Skip to content

Commit 30dc54d

Browse files
committed
feat(33792): add new quick fix service to handle missing call in condition
1 parent 634d514 commit 30dc54d

14 files changed

+376
-0
lines changed

src/compiler/diagnosticMessages.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5357,6 +5357,14 @@
53575357
"category": "Message",
53585358
"code": 95066
53595359
},
5360+
"Add missing call": {
5361+
"category": "Message",
5362+
"code": 95067
5363+
},
5364+
"Add all missing calls": {
5365+
"category": "Message",
5366+
"code": 95068
5367+
},
53605368
"Add 'unknown' conversion for non-overlapping types": {
53615369
"category": "Message",
53625370
"code": 95069
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/* @internal */
2+
namespace ts.codefix {
3+
const fixId = "fixMissingCallInCondition";
4+
const errorCodes = [
5+
Diagnostics.This_condition_will_always_return_true_since_the_function_is_always_defined_Did_you_mean_to_call_it_instead.code,
6+
];
7+
8+
registerCodeFix({
9+
errorCodes,
10+
fixIds: [fixId],
11+
getCodeActions(context) {
12+
const { sourceFile, span } = context;
13+
const callName = getCallName(sourceFile, span.start);
14+
if (!callName) return;
15+
16+
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, callName));
17+
return [createCodeFixAction(fixId, changes, Diagnostics.Add_missing_call, fixId, Diagnostics.Add_all_missing_calls)];
18+
},
19+
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
20+
const callName = getCallName(diag.file, diag.start);
21+
if (callName) doChange(changes, diag.file, callName);
22+
})
23+
});
24+
25+
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, name: Identifier | PrivateIdentifier): void {
26+
changes.replaceNode(sourceFile, name, createCall(createIdentifier(name.text), /*typeArguments*/ undefined, /*argumentsArray*/ undefined));
27+
}
28+
29+
function getCallName(sourceFile: SourceFile, start: number): Identifier | PrivateIdentifier | undefined {
30+
const token = getTokenAtPosition(sourceFile, start);
31+
if (isPropertyAccessExpression(token.parent)) {
32+
let current: PropertyAccessExpression = token.parent;
33+
while (isPropertyAccessExpression(current.parent)) {
34+
current = current.parent;
35+
}
36+
return current.name;
37+
}
38+
39+
if (isIdentifier(token)) {
40+
return token;
41+
}
42+
43+
return undefined;
44+
}
45+
}

src/services/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
"codefixes/fixUnreachableCode.ts",
8181
"codefixes/fixUnusedLabel.ts",
8282
"codefixes/fixJSDocTypes.ts",
83+
"codefixes/fixMissingCallInCondition.ts",
8384
"codefixes/fixAwaitInSyncFunction.ts",
8485
"codefixes/disableJsDiagnostics.ts",
8586
"codefixes/helpers.ts",
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
// @strictNullChecks: true
4+
////function foo(fn: () => boolean) {
5+
//// fn/**/ ? console.log('test') : undefined;
6+
////}
7+
8+
verify.codeFixAvailable([
9+
{ description: ts.Diagnostics.Add_missing_call.message }
10+
]);
11+
12+
verify.codeFix({
13+
description: ts.Diagnostics.Add_missing_call.message,
14+
index: 0,
15+
newFileContent:
16+
`function foo(fn: () => boolean) {
17+
fn() ? console.log('test') : undefined;
18+
}`,
19+
});
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
// @strictNullChecks: true
4+
////class Foo {
5+
//// #test = () => true;
6+
//// run() {
7+
//// if (this.#test/**/) {
8+
//// console.log('test')
9+
//// }
10+
//// }
11+
////}
12+
13+
verify.codeFixAvailable([
14+
{ description: ts.Diagnostics.Add_missing_call.message }
15+
]);
16+
17+
verify.codeFix({
18+
description: ts.Diagnostics.Add_missing_call.message,
19+
index: 0,
20+
newFileContent:
21+
`class Foo {
22+
#test = () => true;
23+
run() {
24+
if (this.#test()) {
25+
console.log('test')
26+
}
27+
}
28+
}`,
29+
});
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
// @strictNullChecks: true
4+
////class Foo {
5+
//// #test = () => true;
6+
//// run() {
7+
//// if (this.#test) {
8+
//// console.log('test')
9+
//// }
10+
//// }
11+
////}
12+
////
13+
////function foo() {
14+
//// function test() { return Math.random() > 0.5; }
15+
//// test ? console.log('test') : undefined;
16+
////}
17+
////
18+
////function foo() {
19+
//// const x = {
20+
//// foo: {
21+
//// bar() { return true; }
22+
//// }
23+
//// }
24+
//// x.foo.bar ? console.log('test') : undefined;
25+
//// if (x.foo.bar) {}
26+
////}
27+
28+
verify.codeFixAll({
29+
fixAllDescription: ts.Diagnostics.Add_all_missing_calls.message,
30+
fixId: "fixMissingCallInCondition",
31+
newFileContent:
32+
`class Foo {
33+
#test = () => true;
34+
run() {
35+
if (this.#test()) {
36+
console.log('test')
37+
}
38+
}
39+
}
40+
41+
function foo() {
42+
function test() { return Math.random() > 0.5; }
43+
test() ? console.log('test') : undefined;
44+
}
45+
46+
function foo() {
47+
const x = {
48+
foo: {
49+
bar() { return true; }
50+
}
51+
}
52+
x.foo.bar() ? console.log('test') : undefined;
53+
if (x.foo.bar()) {}
54+
}`,
55+
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
// @strictNullChecks: true
4+
////function foo() {
5+
//// function test() { return Math.random() > 0.5; }
6+
//// test/**/ ? console.log('test') : undefined;
7+
////}
8+
9+
verify.codeFixAvailable([
10+
{ description: ts.Diagnostics.Add_missing_call.message }
11+
]);
12+
13+
verify.codeFix({
14+
description: ts.Diagnostics.Add_missing_call.message,
15+
index: 0,
16+
newFileContent:
17+
`function foo() {
18+
function test() { return Math.random() > 0.5; }
19+
test() ? console.log('test') : undefined;
20+
}`,
21+
});
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
// @strictNullChecks: true
4+
////function foo() {
5+
//// const x = {
6+
//// foo: {
7+
//// bar() { return true; }
8+
//// }
9+
//// }
10+
//// x.foo.bar/**/ ? console.log('test') : undefined;
11+
////}
12+
13+
verify.codeFixAvailable([
14+
{ description: ts.Diagnostics.Add_missing_call.message }
15+
]);
16+
17+
verify.codeFix({
18+
description: ts.Diagnostics.Add_missing_call.message,
19+
index: 0,
20+
newFileContent:
21+
`function foo() {
22+
const x = {
23+
foo: {
24+
bar() { return true; }
25+
}
26+
}
27+
x.foo.bar() ? console.log('test') : undefined;
28+
}`,
29+
});
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
// @strictNullChecks: true
4+
////class Foo {
5+
//// test() {
6+
//// return true;
7+
//// }
8+
//// run() {
9+
//// this.test/**/ ? console.log('test') : undefined;
10+
//// }
11+
////}
12+
13+
verify.codeFixAvailable([
14+
{ description: ts.Diagnostics.Add_missing_call.message }
15+
]);
16+
17+
verify.codeFix({
18+
description: ts.Diagnostics.Add_missing_call.message,
19+
index: 0,
20+
newFileContent:
21+
`class Foo {
22+
test() {
23+
return true;
24+
}
25+
run() {
26+
this.test() ? console.log('test') : undefined;
27+
}
28+
}`,
29+
});
30+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
// @strictNullChecks: true
4+
////class Foo {
5+
//// #test = () => true;
6+
//// run() {
7+
//// this.#test/**/ ? console.log('test') : undefined;
8+
//// }
9+
////}
10+
11+
verify.codeFixAvailable([
12+
{ description: ts.Diagnostics.Add_missing_call.message }
13+
]);
14+
15+
verify.codeFix({
16+
description: ts.Diagnostics.Add_missing_call.message,
17+
index: 0,
18+
newFileContent:
19+
`class Foo {
20+
#test = () => true;
21+
run() {
22+
this.#test() ? console.log('test') : undefined;
23+
}
24+
}`,
25+
});

0 commit comments

Comments
 (0)