mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-11 19:27:35 -06:00
feat(33792): add new quick fix service to handle missing call in condition (#37152)
This commit is contained in:
parent
47b60ece0b
commit
fc30095e8b
@ -5377,6 +5377,14 @@
|
||||
"category": "Message",
|
||||
"code": 95066
|
||||
},
|
||||
"Add missing call parentheses": {
|
||||
"category": "Message",
|
||||
"code": 95067
|
||||
},
|
||||
"Add all missing call parentheses": {
|
||||
"category": "Message",
|
||||
"code": 95068
|
||||
},
|
||||
"Add 'unknown' conversion for non-overlapping types": {
|
||||
"category": "Message",
|
||||
"code": 95069
|
||||
|
||||
45
src/services/codefixes/fixMissingCallParentheses.ts
Normal file
45
src/services/codefixes/fixMissingCallParentheses.ts
Normal file
@ -0,0 +1,45 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
const fixId = "fixMissingCallParentheses";
|
||||
const errorCodes = [
|
||||
Diagnostics.This_condition_will_always_return_true_since_the_function_is_always_defined_Did_you_mean_to_call_it_instead.code,
|
||||
];
|
||||
|
||||
registerCodeFix({
|
||||
errorCodes,
|
||||
fixIds: [fixId],
|
||||
getCodeActions(context) {
|
||||
const { sourceFile, span } = context;
|
||||
const callName = getCallName(sourceFile, span.start);
|
||||
if (!callName) return;
|
||||
|
||||
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, callName));
|
||||
return [createCodeFixAction(fixId, changes, Diagnostics.Add_missing_call_parentheses, fixId, Diagnostics.Add_all_missing_call_parentheses)];
|
||||
},
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
|
||||
const callName = getCallName(diag.file, diag.start);
|
||||
if (callName) doChange(changes, diag.file, callName);
|
||||
})
|
||||
});
|
||||
|
||||
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, name: Identifier | PrivateIdentifier): void {
|
||||
changes.replaceNodeWithText(sourceFile, name, `${ name.text }()`);
|
||||
}
|
||||
|
||||
function getCallName(sourceFile: SourceFile, start: number): Identifier | PrivateIdentifier | undefined {
|
||||
const token = getTokenAtPosition(sourceFile, start);
|
||||
if (isPropertyAccessExpression(token.parent)) {
|
||||
let current: PropertyAccessExpression = token.parent;
|
||||
while (isPropertyAccessExpression(current.parent)) {
|
||||
current = current.parent;
|
||||
}
|
||||
return current.name;
|
||||
}
|
||||
|
||||
if (isIdentifier(token)) {
|
||||
return token;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@ -80,6 +80,7 @@
|
||||
"codefixes/fixUnreachableCode.ts",
|
||||
"codefixes/fixUnusedLabel.ts",
|
||||
"codefixes/fixJSDocTypes.ts",
|
||||
"codefixes/fixMissingCallParentheses.ts",
|
||||
"codefixes/fixAwaitInSyncFunction.ts",
|
||||
"codefixes/disableJsDiagnostics.ts",
|
||||
"codefixes/helpers.ts",
|
||||
|
||||
19
tests/cases/fourslash/codeFixMissingCallParentheses1.ts
Normal file
19
tests/cases/fourslash/codeFixMissingCallParentheses1.ts
Normal file
@ -0,0 +1,19 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @strictNullChecks: true
|
||||
////function foo(fn: () => boolean) {
|
||||
//// fn/**/ ? console.log('test') : undefined;
|
||||
////}
|
||||
|
||||
verify.codeFixAvailable([
|
||||
{ description: ts.Diagnostics.Add_missing_call_parentheses.message }
|
||||
]);
|
||||
|
||||
verify.codeFix({
|
||||
description: ts.Diagnostics.Add_missing_call_parentheses.message,
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`function foo(fn: () => boolean) {
|
||||
fn() ? console.log('test') : undefined;
|
||||
}`,
|
||||
});
|
||||
29
tests/cases/fourslash/codeFixMissingCallParentheses10.ts
Normal file
29
tests/cases/fourslash/codeFixMissingCallParentheses10.ts
Normal file
@ -0,0 +1,29 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @strictNullChecks: true
|
||||
////class Foo {
|
||||
//// #test = () => true;
|
||||
//// run() {
|
||||
//// if (this.#test/**/) {
|
||||
//// console.log('test')
|
||||
//// }
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFixAvailable([
|
||||
{ description: ts.Diagnostics.Add_missing_call_parentheses.message }
|
||||
]);
|
||||
|
||||
verify.codeFix({
|
||||
description: ts.Diagnostics.Add_missing_call_parentheses.message,
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`class Foo {
|
||||
#test = () => true;
|
||||
run() {
|
||||
if (this.#test()) {
|
||||
console.log('test')
|
||||
}
|
||||
}
|
||||
}`,
|
||||
});
|
||||
55
tests/cases/fourslash/codeFixMissingCallParentheses11.ts
Normal file
55
tests/cases/fourslash/codeFixMissingCallParentheses11.ts
Normal file
@ -0,0 +1,55 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @strictNullChecks: true
|
||||
////class Foo {
|
||||
//// #test = () => true;
|
||||
//// run() {
|
||||
//// if (this.#test) {
|
||||
//// console.log('test')
|
||||
//// }
|
||||
//// }
|
||||
////}
|
||||
////
|
||||
////function foo() {
|
||||
//// function test() { return Math.random() > 0.5; }
|
||||
//// test ? console.log('test') : undefined;
|
||||
////}
|
||||
////
|
||||
////function foo() {
|
||||
//// const x = {
|
||||
//// foo: {
|
||||
//// bar() { return true; }
|
||||
//// }
|
||||
//// }
|
||||
//// x.foo.bar ? console.log('test') : undefined;
|
||||
//// if (x.foo.bar) {}
|
||||
////}
|
||||
|
||||
verify.codeFixAll({
|
||||
fixAllDescription: ts.Diagnostics.Add_all_missing_call_parentheses.message,
|
||||
fixId: "fixMissingCallParentheses",
|
||||
newFileContent:
|
||||
`class Foo {
|
||||
#test = () => true;
|
||||
run() {
|
||||
if (this.#test()) {
|
||||
console.log('test')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function foo() {
|
||||
function test() { return Math.random() > 0.5; }
|
||||
test() ? console.log('test') : undefined;
|
||||
}
|
||||
|
||||
function foo() {
|
||||
const x = {
|
||||
foo: {
|
||||
bar() { return true; }
|
||||
}
|
||||
}
|
||||
x.foo.bar() ? console.log('test') : undefined;
|
||||
if (x.foo.bar()) {}
|
||||
}`,
|
||||
});
|
||||
21
tests/cases/fourslash/codeFixMissingCallParentheses2.ts
Normal file
21
tests/cases/fourslash/codeFixMissingCallParentheses2.ts
Normal file
@ -0,0 +1,21 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @strictNullChecks: true
|
||||
////function foo() {
|
||||
//// function test() { return Math.random() > 0.5; }
|
||||
//// test/**/ ? console.log('test') : undefined;
|
||||
////}
|
||||
|
||||
verify.codeFixAvailable([
|
||||
{ description: ts.Diagnostics.Add_missing_call_parentheses.message }
|
||||
]);
|
||||
|
||||
verify.codeFix({
|
||||
description: ts.Diagnostics.Add_missing_call_parentheses.message,
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`function foo() {
|
||||
function test() { return Math.random() > 0.5; }
|
||||
test() ? console.log('test') : undefined;
|
||||
}`,
|
||||
});
|
||||
29
tests/cases/fourslash/codeFixMissingCallParentheses3.ts
Normal file
29
tests/cases/fourslash/codeFixMissingCallParentheses3.ts
Normal file
@ -0,0 +1,29 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @strictNullChecks: true
|
||||
////function foo() {
|
||||
//// const x = {
|
||||
//// foo: {
|
||||
//// bar() { return true; }
|
||||
//// }
|
||||
//// }
|
||||
//// x.foo.bar/**/ ? console.log('test') : undefined;
|
||||
////}
|
||||
|
||||
verify.codeFixAvailable([
|
||||
{ description: ts.Diagnostics.Add_missing_call_parentheses.message }
|
||||
]);
|
||||
|
||||
verify.codeFix({
|
||||
description: ts.Diagnostics.Add_missing_call_parentheses.message,
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`function foo() {
|
||||
const x = {
|
||||
foo: {
|
||||
bar() { return true; }
|
||||
}
|
||||
}
|
||||
x.foo.bar() ? console.log('test') : undefined;
|
||||
}`,
|
||||
});
|
||||
30
tests/cases/fourslash/codeFixMissingCallParentheses4.ts
Normal file
30
tests/cases/fourslash/codeFixMissingCallParentheses4.ts
Normal file
@ -0,0 +1,30 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @strictNullChecks: true
|
||||
////class Foo {
|
||||
//// test() {
|
||||
//// return true;
|
||||
//// }
|
||||
//// run() {
|
||||
//// this.test/**/ ? console.log('test') : undefined;
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFixAvailable([
|
||||
{ description: ts.Diagnostics.Add_missing_call_parentheses.message }
|
||||
]);
|
||||
|
||||
verify.codeFix({
|
||||
description: ts.Diagnostics.Add_missing_call_parentheses.message,
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`class Foo {
|
||||
test() {
|
||||
return true;
|
||||
}
|
||||
run() {
|
||||
this.test() ? console.log('test') : undefined;
|
||||
}
|
||||
}`,
|
||||
});
|
||||
|
||||
25
tests/cases/fourslash/codeFixMissingCallParentheses5.ts
Normal file
25
tests/cases/fourslash/codeFixMissingCallParentheses5.ts
Normal file
@ -0,0 +1,25 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @strictNullChecks: true
|
||||
////class Foo {
|
||||
//// #test = () => true;
|
||||
//// run() {
|
||||
//// this.#test/**/ ? console.log('test') : undefined;
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFixAvailable([
|
||||
{ description: ts.Diagnostics.Add_missing_call_parentheses.message }
|
||||
]);
|
||||
|
||||
verify.codeFix({
|
||||
description: ts.Diagnostics.Add_missing_call_parentheses.message,
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`class Foo {
|
||||
#test = () => true;
|
||||
run() {
|
||||
this.#test() ? console.log('test') : undefined;
|
||||
}
|
||||
}`,
|
||||
});
|
||||
23
tests/cases/fourslash/codeFixMissingCallParentheses6.ts
Normal file
23
tests/cases/fourslash/codeFixMissingCallParentheses6.ts
Normal file
@ -0,0 +1,23 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @strictNullChecks: true
|
||||
////function foo(fn: () => boolean) {
|
||||
//// if (fn/**/) {
|
||||
//// console.log('test');
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFixAvailable([
|
||||
{ description: ts.Diagnostics.Add_missing_call_parentheses.message }
|
||||
]);
|
||||
|
||||
verify.codeFix({
|
||||
description: ts.Diagnostics.Add_missing_call_parentheses.message,
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`function foo(fn: () => boolean) {
|
||||
if (fn()) {
|
||||
console.log('test');
|
||||
}
|
||||
}`,
|
||||
});
|
||||
25
tests/cases/fourslash/codeFixMissingCallParentheses7.ts
Normal file
25
tests/cases/fourslash/codeFixMissingCallParentheses7.ts
Normal file
@ -0,0 +1,25 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @strictNullChecks: true
|
||||
////function foo() {
|
||||
//// function test() { return Math.random() > 0.5; }
|
||||
//// if (test/**/) {
|
||||
//// console.log('test')
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFixAvailable([
|
||||
{ description: ts.Diagnostics.Add_missing_call_parentheses.message }
|
||||
]);
|
||||
|
||||
verify.codeFix({
|
||||
description: ts.Diagnostics.Add_missing_call_parentheses.message,
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`function foo() {
|
||||
function test() { return Math.random() > 0.5; }
|
||||
if (test()) {
|
||||
console.log('test')
|
||||
}
|
||||
}`,
|
||||
});
|
||||
33
tests/cases/fourslash/codeFixMissingCallParentheses8.ts
Normal file
33
tests/cases/fourslash/codeFixMissingCallParentheses8.ts
Normal file
@ -0,0 +1,33 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @strictNullChecks: true
|
||||
////function foo() {
|
||||
//// const x = {
|
||||
//// foo: {
|
||||
//// bar() { return true; }
|
||||
//// }
|
||||
//// }
|
||||
//// if (x.foo.bar/**/) {
|
||||
//// console.log('test')
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFixAvailable([
|
||||
{ description: ts.Diagnostics.Add_missing_call_parentheses.message }
|
||||
]);
|
||||
|
||||
verify.codeFix({
|
||||
description: ts.Diagnostics.Add_missing_call_parentheses.message,
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`function foo() {
|
||||
const x = {
|
||||
foo: {
|
||||
bar() { return true; }
|
||||
}
|
||||
}
|
||||
if (x.foo.bar()) {
|
||||
console.log('test')
|
||||
}
|
||||
}`,
|
||||
});
|
||||
33
tests/cases/fourslash/codeFixMissingCallParentheses9.ts
Normal file
33
tests/cases/fourslash/codeFixMissingCallParentheses9.ts
Normal file
@ -0,0 +1,33 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @strictNullChecks: true
|
||||
////function foo() {
|
||||
//// const x = {
|
||||
//// foo: {
|
||||
//// bar() { return true; }
|
||||
//// }
|
||||
//// }
|
||||
//// if (x.foo.bar/**/) {
|
||||
//// console.log('test')
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFixAvailable([
|
||||
{ description: ts.Diagnostics.Add_missing_call_parentheses.message }
|
||||
]);
|
||||
|
||||
verify.codeFix({
|
||||
description: ts.Diagnostics.Add_missing_call_parentheses.message,
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`function foo() {
|
||||
const x = {
|
||||
foo: {
|
||||
bar() { return true; }
|
||||
}
|
||||
}
|
||||
if (x.foo.bar()) {
|
||||
console.log('test')
|
||||
}
|
||||
}`,
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user