Skip to content

Commit

Permalink
Improve performance: do not add unused suggestion diagnostics unless …
Browse files Browse the repository at this point in the history
…asking for a suggestion
  • Loading branch information
Andy Hanson committed Mar 12, 2018
1 parent eaf1575 commit a07f9f4
Show file tree
Hide file tree
Showing 14 changed files with 63 additions and 62 deletions.
58 changes: 32 additions & 26 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,22 @@ namespace ts {
return node && getTypeArgumentConstraint(node);
},

getSuggestionDiagnostics: file => (suggestionDiagnostics.get(file.fileName) || emptyArray).concat(getUnusedDiagnostics(file)),
getSuggestionDiagnostics: file => {
return (suggestionDiagnostics.get(file.fileName) || emptyArray).concat(getUnusedDiagnostics());
function getUnusedDiagnostics(): ReadonlyArray<Diagnostic> {
checkSourceFile(file);
const diagnostics: Diagnostic[] = [];
Debug.assert(!!(getNodeLinks(file).flags & NodeCheckFlags.TypeChecked));
if (!file.isDeclarationFile) {
checkUnusedIdentifiers(allPotentiallyUnusedIdentifiers.get(file.fileName)!, (kind, diag) => {
if (!unusedIsError(kind)) {
diagnostics.push({ ...diag, category: DiagnosticCategory.Suggestion });
}
});
}
return diagnostics;
}
},
};

const tupleTypes: GenericType[] = [];
Expand Down Expand Up @@ -18732,7 +18747,6 @@ namespace ts {
return type;
}

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

Expand Down Expand Up @@ -21564,11 +21578,16 @@ namespace ts {
}

function registerForUnusedIdentifiersCheck(node: PotentiallyUnusedIdentifier): void {
// May be in a call such as getTypeOfNode that happened to call this. But potentiallyUnusedIdentifiers is only defined in the scope of `checkSourceFile`.
if (potentiallyUnusedIdentifiers === undefined) return;

if (contains(potentiallyUnusedIdentifiers, node)) {
// TODO: #22491 Apparently we check the BlockStatement in the callback in `getPropertyAssignment` twice.
// TODO: GH#22491 Apparently we check the BlockStatement in the callback in `getPropertyAssignment` twice.
// Debug.fail();
} else
}
else {
potentiallyUnusedIdentifiers.push(node);
}
}

type PotentiallyUnusedIdentifier =
Expand All @@ -21581,15 +21600,15 @@ namespace ts {
switch (node.kind) {
case SyntaxKind.SourceFile:
case SyntaxKind.ModuleDeclaration:
checkUnusedModuleMembers(<ModuleDeclaration | SourceFile>node, addDiagnostic);
checkUnusedModuleMembers(node, addDiagnostic);
break;
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ClassExpression:
checkUnusedClassMembers(<ClassDeclaration | ClassExpression>node, addDiagnostic);
checkUnusedTypeParameters(<ClassDeclaration | ClassExpression>node, addDiagnostic);
checkUnusedClassMembers(node, addDiagnostic);
checkUnusedTypeParameters(node, addDiagnostic);
break;
case SyntaxKind.InterfaceDeclaration:
checkUnusedTypeParameters(<InterfaceDeclaration>node, addDiagnostic);
checkUnusedTypeParameters(node, addDiagnostic);
break;
case SyntaxKind.Block:
case SyntaxKind.CaseBlock:
Expand All @@ -21605,18 +21624,18 @@ namespace ts {
case SyntaxKind.MethodDeclaration:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
if ((<FunctionLikeDeclaration>node).body) {
checkUnusedLocalsAndParameters(<FunctionLikeDeclaration>node, addDiagnostic);
if (node.body) {
checkUnusedLocalsAndParameters(node, addDiagnostic);
}
checkUnusedTypeParameters(<FunctionLikeDeclaration>node, addDiagnostic);
checkUnusedTypeParameters(node, addDiagnostic);
break;
case SyntaxKind.MethodSignature:
case SyntaxKind.CallSignature:
case SyntaxKind.ConstructSignature:
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
case SyntaxKind.TypeAliasDeclaration:
checkUnusedTypeParameters(<MethodSignature | CallSignatureDeclaration | ConstructSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | TypeAliasDeclaration>node, addDiagnostic);
checkUnusedTypeParameters(node, addDiagnostic);
break;
default:
Debug.assertNever(node, "Node should not have been registered for unused identifiers check");
Expand Down Expand Up @@ -24549,19 +24568,6 @@ namespace ts {
}
}

function getUnusedDiagnostics(node: SourceFile): ReadonlyArray<Diagnostic> {
const diagnostics: Diagnostic[] = [];
Debug.assert(!!(getNodeLinks(node).flags & NodeCheckFlags.TypeChecked));
if (!node.isDeclarationFile) {
checkUnusedIdentifiers(allPotentiallyUnusedIdentifiers.get(node.fileName)!, (kind, diag) => {
if (!unusedIsError(kind)) {
diagnostics.push(diag);
}
});
}
return diagnostics;
}

// Fully type check a source file and collect the relevant diagnostics.
function checkSourceFileWorker(node: SourceFile) {
const links = getNodeLinks(node);
Expand Down Expand Up @@ -24593,7 +24599,7 @@ namespace ts {
registerForUnusedIdentifiersCheck(node);
}

if (!node.isDeclarationFile) { //&& (compilerOptions.noUnusedLocals || compilerOptions.noUnusedParameters)) {
if (!node.isDeclarationFile && (compilerOptions.noUnusedLocals || compilerOptions.noUnusedParameters)) {
checkUnusedIdentifiers(potentiallyUnusedIdentifiers, (kind, diag) => {
if (unusedIsError(kind)) {
diagnostics.add(diag);
Expand Down
10 changes: 1 addition & 9 deletions tests/cases/fourslash/annotateWithTypeFromJSDoc15.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,6 @@ verify.codeFix({
* @param {promise<String>} zeta
*/
function f(x: boolean, y: string, z: number, alpha: object, beta: Date, gamma: Promise<any>, delta: Array<any>, epsilon: Array<number>, zeta: Promise<string>) {
x;
y;
z;
alpha;
beta;
gamma;
delta;
epsilon;
zeta;
x; y; z; alpha; beta; gamma; delta; epsilon; zeta;
}`,
});
3 changes: 1 addition & 2 deletions tests/cases/fourslash/annotateWithTypeFromJSDoc22.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ verify.codeFix({
/** @param {Object<string, boolean>} sb
* @param {Object<number, string>} ns */
function f(sb: { [s: string]: boolean; }, ns: { [n: number]: string; }) {
sb;
ns;
sb; ns;
}`,
});
6 changes: 1 addition & 5 deletions tests/cases/fourslash/annotateWithTypeFromJSDoc3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ verify.codeFix({
* @param {*} beta - I have no idea how this got here
*/
function f(x: number, y: { a: string; b: Date; }, z: string, alpha, beta: any) {
x;
y;
z;
alpha;
beta;
x; y; z; alpha; beta;
}`,
});
8 changes: 1 addition & 7 deletions tests/cases/fourslash/annotateWithTypeFromJSDoc4.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,6 @@ verify.codeFix({
* @param {number!} delta
*/
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) {
x;
y;
z;
alpha;
beta;
gamma;
delta;
x; y; z; alpha; beta; gamma; delta;
}`,
});
2 changes: 1 addition & 1 deletion tests/cases/fourslash/annotateWithTypeFromJSDoc8.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ verify.codeFix({
* @param {number} x
* @returns {number}
*/
var f = function(x: number): number {
var f = function (x: number): number {
return x
}`,
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@
////exports.y;
////
////exports.z = 2;
////function f(z) {
//// exports.z;
////exports.f = function(z) {
//// exports.z; z;
////}

verify.codeFix({
description: "Convert to ES6 module",
// TODO: GH#22492
newFileContent:
`export const x = 0;
x;
Expand All @@ -28,7 +29,7 @@ _y;
const _z = 2;
export { _z as z };
function f(z) {
_z;
export function f(z) {
_z z;
}`,
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
// @allowJs: true

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

verify.codeFix({
description: "Convert to ES6 module",
newFileContent:
`export async function* f(p) { }
`export async function* f(p) { p; }
export class C extends D {
m() { }
}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

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

verify.codeFix({
description: "Convert to ES6 module",
newFileContent: `import _x from "x";
const [x, y] = _x;`,
const [x, y] = _x;
x; y;`,
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
////const x = require("x");
////const [a, b] = require("x");
////const {c, ...d} = require("x");
////x; a; b; c; d;

verify.codeFix({
description: "Convert to ES6 module",
Expand All @@ -14,5 +15,6 @@ verify.codeFix({
import _x from "x";
const [a, b] = _x;
import __x from "x";
const { c, ...d } = __x;`,
const { c, ...d } = __x;
x; a; b; c; d;`,
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@

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

verify.codeFix({
description: "Convert to ES6 module",
newFileContent:
`import x from "x";
const y = 0;
import { z } from "z";`,
import { z } from "z";
x; y; z;`,
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

// @Filename: /a.js
////const { x: { a, b } } = require("x");
////a; b;

verify.codeFix({
description: "Convert to ES6 module",
newFileContent:
`import x from "x";
const { x: { a, b } } = x;`,
const { x: { a, b } } = x;
a; b;`,
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@

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

verify.codeFix({
description: "Convert to ES6 module",
newFileContent: 'import { x, y as z } from "x";',
newFileContent:
`import { x, y as z } from "x";
x; z;`,
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
////const a = require("a").a;
////const [a, b] = require("c").d;
////const [a, b] = require("c").a; // Test that we avoid shadowing the earlier local variable 'a' from 'const [a,b] = d;'.
////x; a; b;

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

0 comments on commit a07f9f4

Please sign in to comment.