Skip to content

Commit a07f9f4

Browse files
author
Andy Hanson
committed
Improve performance: do not add unused suggestion diagnostics unless asking for a suggestion
1 parent eaf1575 commit a07f9f4

14 files changed

+63
-62
lines changed

src/compiler/checker.ts

+32-26
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,22 @@ namespace ts {
311311
return node && getTypeArgumentConstraint(node);
312312
},
313313

314-
getSuggestionDiagnostics: file => (suggestionDiagnostics.get(file.fileName) || emptyArray).concat(getUnusedDiagnostics(file)),
314+
getSuggestionDiagnostics: file => {
315+
return (suggestionDiagnostics.get(file.fileName) || emptyArray).concat(getUnusedDiagnostics());
316+
function getUnusedDiagnostics(): ReadonlyArray<Diagnostic> {
317+
checkSourceFile(file);
318+
const diagnostics: Diagnostic[] = [];
319+
Debug.assert(!!(getNodeLinks(file).flags & NodeCheckFlags.TypeChecked));
320+
if (!file.isDeclarationFile) {
321+
checkUnusedIdentifiers(allPotentiallyUnusedIdentifiers.get(file.fileName)!, (kind, diag) => {
322+
if (!unusedIsError(kind)) {
323+
diagnostics.push({ ...diag, category: DiagnosticCategory.Suggestion });
324+
}
325+
});
326+
}
327+
return diagnostics;
328+
}
329+
},
315330
};
316331

317332
const tupleTypes: GenericType[] = [];
@@ -18732,7 +18747,6 @@ namespace ts {
1873218747
return type;
1873318748
}
1873418749

18735-
//why?
1873618750
function checkFunctionExpressionOrObjectLiteralMethodDeferred(node: ArrowFunction | FunctionExpression | MethodDeclaration) {
1873718751
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
1873818752

@@ -21564,11 +21578,16 @@ namespace ts {
2156421578
}
2156521579

2156621580
function registerForUnusedIdentifiersCheck(node: PotentiallyUnusedIdentifier): void {
21581+
// May be in a call such as getTypeOfNode that happened to call this. But potentiallyUnusedIdentifiers is only defined in the scope of `checkSourceFile`.
21582+
if (potentiallyUnusedIdentifiers === undefined) return;
21583+
2156721584
if (contains(potentiallyUnusedIdentifiers, node)) {
21568-
// TODO: #22491 Apparently we check the BlockStatement in the callback in `getPropertyAssignment` twice.
21585+
// TODO: GH#22491 Apparently we check the BlockStatement in the callback in `getPropertyAssignment` twice.
2156921586
// Debug.fail();
21570-
} else
21587+
}
21588+
else {
2157121589
potentiallyUnusedIdentifiers.push(node);
21590+
}
2157221591
}
2157321592

2157421593
type PotentiallyUnusedIdentifier =
@@ -21581,15 +21600,15 @@ namespace ts {
2158121600
switch (node.kind) {
2158221601
case SyntaxKind.SourceFile:
2158321602
case SyntaxKind.ModuleDeclaration:
21584-
checkUnusedModuleMembers(<ModuleDeclaration | SourceFile>node, addDiagnostic);
21603+
checkUnusedModuleMembers(node, addDiagnostic);
2158521604
break;
2158621605
case SyntaxKind.ClassDeclaration:
2158721606
case SyntaxKind.ClassExpression:
21588-
checkUnusedClassMembers(<ClassDeclaration | ClassExpression>node, addDiagnostic);
21589-
checkUnusedTypeParameters(<ClassDeclaration | ClassExpression>node, addDiagnostic);
21607+
checkUnusedClassMembers(node, addDiagnostic);
21608+
checkUnusedTypeParameters(node, addDiagnostic);
2159021609
break;
2159121610
case SyntaxKind.InterfaceDeclaration:
21592-
checkUnusedTypeParameters(<InterfaceDeclaration>node, addDiagnostic);
21611+
checkUnusedTypeParameters(node, addDiagnostic);
2159321612
break;
2159421613
case SyntaxKind.Block:
2159521614
case SyntaxKind.CaseBlock:
@@ -21605,18 +21624,18 @@ namespace ts {
2160521624
case SyntaxKind.MethodDeclaration:
2160621625
case SyntaxKind.GetAccessor:
2160721626
case SyntaxKind.SetAccessor:
21608-
if ((<FunctionLikeDeclaration>node).body) {
21609-
checkUnusedLocalsAndParameters(<FunctionLikeDeclaration>node, addDiagnostic);
21627+
if (node.body) {
21628+
checkUnusedLocalsAndParameters(node, addDiagnostic);
2161021629
}
21611-
checkUnusedTypeParameters(<FunctionLikeDeclaration>node, addDiagnostic);
21630+
checkUnusedTypeParameters(node, addDiagnostic);
2161221631
break;
2161321632
case SyntaxKind.MethodSignature:
2161421633
case SyntaxKind.CallSignature:
2161521634
case SyntaxKind.ConstructSignature:
2161621635
case SyntaxKind.FunctionType:
2161721636
case SyntaxKind.ConstructorType:
2161821637
case SyntaxKind.TypeAliasDeclaration:
21619-
checkUnusedTypeParameters(<MethodSignature | CallSignatureDeclaration | ConstructSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | TypeAliasDeclaration>node, addDiagnostic);
21638+
checkUnusedTypeParameters(node, addDiagnostic);
2162021639
break;
2162121640
default:
2162221641
Debug.assertNever(node, "Node should not have been registered for unused identifiers check");
@@ -24549,19 +24568,6 @@ namespace ts {
2454924568
}
2455024569
}
2455124570

24552-
function getUnusedDiagnostics(node: SourceFile): ReadonlyArray<Diagnostic> {
24553-
const diagnostics: Diagnostic[] = [];
24554-
Debug.assert(!!(getNodeLinks(node).flags & NodeCheckFlags.TypeChecked));
24555-
if (!node.isDeclarationFile) {
24556-
checkUnusedIdentifiers(allPotentiallyUnusedIdentifiers.get(node.fileName)!, (kind, diag) => {
24557-
if (!unusedIsError(kind)) {
24558-
diagnostics.push(diag);
24559-
}
24560-
});
24561-
}
24562-
return diagnostics;
24563-
}
24564-
2456524571
// Fully type check a source file and collect the relevant diagnostics.
2456624572
function checkSourceFileWorker(node: SourceFile) {
2456724573
const links = getNodeLinks(node);
@@ -24593,7 +24599,7 @@ namespace ts {
2459324599
registerForUnusedIdentifiersCheck(node);
2459424600
}
2459524601

24596-
if (!node.isDeclarationFile) { //&& (compilerOptions.noUnusedLocals || compilerOptions.noUnusedParameters)) {
24602+
if (!node.isDeclarationFile && (compilerOptions.noUnusedLocals || compilerOptions.noUnusedParameters)) {
2459724603
checkUnusedIdentifiers(potentiallyUnusedIdentifiers, (kind, diag) => {
2459824604
if (unusedIsError(kind)) {
2459924605
diagnostics.add(diag);

tests/cases/fourslash/annotateWithTypeFromJSDoc15.ts

+1-9
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,6 @@ verify.codeFix({
3030
* @param {promise<String>} zeta
3131
*/
3232
function f(x: boolean, y: string, z: number, alpha: object, beta: Date, gamma: Promise<any>, delta: Array<any>, epsilon: Array<number>, zeta: Promise<string>) {
33-
x;
34-
y;
35-
z;
36-
alpha;
37-
beta;
38-
gamma;
39-
delta;
40-
epsilon;
41-
zeta;
33+
x; y; z; alpha; beta; gamma; delta; epsilon; zeta;
4234
}`,
4335
});

tests/cases/fourslash/annotateWithTypeFromJSDoc22.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ verify.codeFix({
1414
/** @param {Object<string, boolean>} sb
1515
* @param {Object<number, string>} ns */
1616
function f(sb: { [s: string]: boolean; }, ns: { [n: number]: string; }) {
17-
sb;
18-
ns;
17+
sb; ns;
1918
}`,
2019
});

tests/cases/fourslash/annotateWithTypeFromJSDoc3.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ verify.codeFix({
2727
* @param {*} beta - I have no idea how this got here
2828
*/
2929
function f(x: number, y: { a: string; b: Date; }, z: string, alpha, beta: any) {
30-
x;
31-
y;
32-
z;
33-
alpha;
34-
beta;
30+
x; y; z; alpha; beta;
3531
}`,
3632
});

tests/cases/fourslash/annotateWithTypeFromJSDoc4.ts

+1-7
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,6 @@ verify.codeFix({
2626
* @param {number!} delta
2727
*/
2828
function f(x: any, y: any, z: number | undefined, alpha: number[], beta: (this: { a: string; }, arg1: string, arg2: number) => boolean, gamma: number | null, delta: number) {
29-
x;
30-
y;
31-
z;
32-
alpha;
33-
beta;
34-
gamma;
35-
delta;
29+
x; y; z; alpha; beta; gamma; delta;
3630
}`,
3731
});

tests/cases/fourslash/annotateWithTypeFromJSDoc8.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ verify.codeFix({
1515
* @param {number} x
1616
* @returns {number}
1717
*/
18-
var f = function(x: number): number {
18+
var f = function (x: number): number {
1919
return x
2020
}`,
2121
});

tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@
1111
////exports.y;
1212
////
1313
////exports.z = 2;
14-
////function f(z) {
15-
//// exports.z;
14+
////exports.f = function(z) {
15+
//// exports.z; z;
1616
////}
1717

1818
verify.codeFix({
1919
description: "Convert to ES6 module",
20+
// TODO: GH#22492
2021
newFileContent:
2122
`export const x = 0;
2223
x;
@@ -28,7 +29,7 @@ _y;
2829
2930
const _z = 2;
3031
export { _z as z };
31-
function f(z) {
32-
_z;
32+
export function f(z) {
33+
_z z;
3334
}`,
3435
});

tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
// @allowJs: true
44

55
// @Filename: /a.js
6-
////exports.f = async function* f(p) {}
6+
////exports.f = async function* f(p) { p; }
77
////exports.C = class C extends D { m() {} }
88

99
verify.codeFix({
1010
description: "Convert to ES6 module",
1111
newFileContent:
12-
`export async function* f(p) { }
12+
`export async function* f(p) { p; }
1313
export class C extends D {
1414
m() { }
1515
}`,

tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
// @Filename: /a.js
66
////const [x, y] = /*a*/require/*b*/("x");
7+
////x; y;
78

89
verify.codeFix({
910
description: "Convert to ES6 module",
1011
newFileContent: `import _x from "x";
11-
const [x, y] = _x;`,
12+
const [x, y] = _x;
13+
x; y;`,
1214
});

tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
////const x = require("x");
77
////const [a, b] = require("x");
88
////const {c, ...d} = require("x");
9+
////x; a; b; c; d;
910

1011
verify.codeFix({
1112
description: "Convert to ES6 module",
@@ -14,5 +15,6 @@ verify.codeFix({
1415
import _x from "x";
1516
const [a, b] = _x;
1617
import __x from "x";
17-
const { c, ...d } = __x;`,
18+
const { c, ...d } = __x;
19+
x; a; b; c; d;`,
1820
});

tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66

77
// @Filename: /a.js
88
////const x = require("x"), y = 0, { z } = require("z");
9+
////x; y; z;
910

1011
verify.codeFix({
1112
description: "Convert to ES6 module",
1213
newFileContent:
1314
`import x from "x";
1415
const y = 0;
15-
import { z } from "z";`,
16+
import { z } from "z";
17+
x; y; z;`,
1618
});

tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44

55
// @Filename: /a.js
66
////const { x: { a, b } } = require("x");
7+
////a; b;
78

89
verify.codeFix({
910
description: "Convert to ES6 module",
1011
newFileContent:
1112
`import x from "x";
12-
const { x: { a, b } } = x;`,
13+
const { x: { a, b } } = x;
14+
a; b;`,
1315
});

tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44

55
// @Filename: /a.js
66
////const { x, y: z } = require("x");
7+
////x; z;
78

89
verify.codeFix({
910
description: "Convert to ES6 module",
10-
newFileContent: 'import { x, y as z } from "x";',
11+
newFileContent:
12+
`import { x, y as z } from "x";
13+
x; z;`,
1114
});

tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
////const a = require("a").a;
99
////const [a, b] = require("c").d;
1010
////const [a, b] = require("c").a; // Test that we avoid shadowing the earlier local variable 'a' from 'const [a,b] = d;'.
11+
////x; a; b;
1112

1213
verify.codeFix({
1314
description: "Convert to ES6 module",
@@ -18,5 +19,6 @@ import { a } from "a";
1819
import { d } from "c";
1920
const [a, b] = d;
2021
import { a as _a } from "c";
21-
const [a, b] = _a; // Test that we avoid shadowing the earlier local variable 'a' from 'const [a,b] = d;'.`,
22+
const [a, b] = _a; // Test that we avoid shadowing the earlier local variable 'a' from 'const [a,b] = d;'.
23+
x; a; b;`,
2224
});

0 commit comments

Comments
 (0)