Skip to content

Commit 1fb050b

Browse files
author
Andy
authored
Don't report unused diagnostics when the unused node has a parse error (#25598)
* Don't report unused diagnostics when the unused node has a parse error * Update test
1 parent 32e60a9 commit 1fb050b

File tree

3 files changed

+24
-20
lines changed

3 files changed

+24
-20
lines changed

src/compiler/checker.ts

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -336,8 +336,8 @@ namespace ts {
336336
}
337337

338338
function addUnusedDiagnostics() {
339-
checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(file), (kind, diag) => {
340-
if (!unusedIsError(kind)) {
339+
checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(file), (containingNode, kind, diag) => {
340+
if (!containsParseError(containingNode) && !unusedIsError(kind)) {
341341
(diagnostics || (diagnostics = [])).push({ ...diag, category: DiagnosticCategory.Suggestion });
342342
}
343343
});
@@ -646,7 +646,8 @@ namespace ts {
646646
Local,
647647
Parameter,
648648
}
649-
type AddUnusedDiagnostic = (type: UnusedKind, diagnostic: DiagnosticWithLocation) => void;
649+
/** @param containingNode Node to check for parse error */
650+
type AddUnusedDiagnostic = (containingNode: Node, type: UnusedKind, diagnostic: DiagnosticWithLocation) => void;
650651

651652
const builtinGlobals = createSymbolTable();
652653
builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol);
@@ -23612,7 +23613,7 @@ namespace ts {
2361223613
function errorUnusedLocal(declaration: Declaration, name: string, addDiagnostic: AddUnusedDiagnostic) {
2361323614
const node = getNameOfDeclaration(declaration) || declaration;
2361423615
const message = isTypeDeclaration(declaration) ? Diagnostics._0_is_declared_but_never_used : Diagnostics._0_is_declared_but_its_value_is_never_read;
23615-
addDiagnostic(UnusedKind.Local, createDiagnosticForNode(node, message, name));
23616+
addDiagnostic(declaration, UnusedKind.Local, createDiagnosticForNode(node, message, name));
2361623617
}
2361723618

2361823619
function isIdentifierThatStartsWithUnderscore(node: Node) {
@@ -23633,13 +23634,13 @@ namespace ts {
2363323634
}
2363423635
const symbol = getSymbolOfNode(member);
2363523636
if (!symbol.isReferenced && hasModifier(member, ModifierFlags.Private)) {
23636-
addDiagnostic(UnusedKind.Local, createDiagnosticForNode(member.name!, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolToString(symbol)));
23637+
addDiagnostic(member, UnusedKind.Local, createDiagnosticForNode(member.name!, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolToString(symbol)));
2363723638
}
2363823639
break;
2363923640
case SyntaxKind.Constructor:
2364023641
for (const parameter of (<ConstructorDeclaration>member).parameters) {
2364123642
if (!parameter.symbol.isReferenced && hasModifier(parameter, ModifierFlags.Private)) {
23642-
addDiagnostic(UnusedKind.Local, createDiagnosticForNode(parameter.name, Diagnostics.Property_0_is_declared_but_its_value_is_never_read, symbolName(parameter.symbol)));
23643+
addDiagnostic(parameter, UnusedKind.Local, createDiagnosticForNode(parameter.name, Diagnostics.Property_0_is_declared_but_its_value_is_never_read, symbolName(parameter.symbol)));
2364323644
}
2364423645
}
2364523646
break;
@@ -23664,7 +23665,7 @@ namespace ts {
2366423665
if (!(node.flags & NodeFlags.Ambient) && last(getSymbolOfNode(node).declarations) === node) {
2366523666
for (const typeParameter of typeParameters) {
2366623667
if (!(getMergedSymbol(typeParameter.symbol).isReferenced! & SymbolFlags.TypeParameter) && !isIdentifierThatStartsWithUnderscore(typeParameter.name)) {
23667-
addDiagnostic(UnusedKind.Parameter, createDiagnosticForNode(typeParameter.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(typeParameter.symbol)));
23668+
addDiagnostic(typeParameter, UnusedKind.Parameter, createDiagnosticForNode(typeParameter.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(typeParameter.symbol)));
2366823669
}
2366923670
}
2367023671
}
@@ -23723,7 +23724,7 @@ namespace ts {
2372323724
const name = local.valueDeclaration && getNameOfDeclaration(local.valueDeclaration);
2372423725
if (parameter && name) {
2372523726
if (!isParameterPropertyDeclaration(parameter) && !parameterIsThisKeyword(parameter) && !isIdentifierThatStartsWithUnderscore(name)) {
23726-
addDiagnostic(UnusedKind.Parameter, createDiagnosticForNode(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local)));
23727+
addDiagnostic(parameter, UnusedKind.Parameter, createDiagnosticForNode(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local)));
2372723728
}
2372823729
}
2372923730
else {
@@ -23739,7 +23740,7 @@ namespace ts {
2373923740
(importClause.namedBindings.kind === SyntaxKind.NamespaceImport ? 1 : importClause.namedBindings.elements.length)
2374023741
: 0);
2374123742
if (nDeclarations === unuseds.length) {
23742-
addDiagnostic(UnusedKind.Local, unuseds.length === 1
23743+
addDiagnostic(importDecl, UnusedKind.Local, unuseds.length === 1
2374323744
? createDiagnosticForNode(importDecl, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(first(unuseds).name!))
2374423745
: createDiagnosticForNode(importDecl, Diagnostics.All_imports_in_import_declaration_are_unused));
2374523746
}
@@ -23754,26 +23755,26 @@ namespace ts {
2375423755
addToGroup(unusedVariables, bindingPattern.parent.parent, bindingPattern.parent, getNodeId);
2375523756
}
2375623757
else {
23757-
addDiagnostic(kind, bindingElements.length === 1
23758+
addDiagnostic(bindingPattern, kind, bindingElements.length === 1
2375823759
? createDiagnosticForNode(bindingPattern, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(cast(first(bindingElements).name, isIdentifier)))
2375923760
: createDiagnosticForNode(bindingPattern, Diagnostics.All_destructured_elements_are_unused));
2376023761
}
2376123762
}
2376223763
else {
2376323764
for (const e of bindingElements) {
23764-
addDiagnostic(kind, createDiagnosticForNode(e, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(cast(e.name, isIdentifier))));
23765+
addDiagnostic(e, kind, createDiagnosticForNode(e, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(cast(e.name, isIdentifier))));
2376523766
}
2376623767
}
2376723768
});
2376823769
unusedVariables.forEach(([declarationList, declarations]) => {
2376923770
if (declarationList.declarations.length === declarations.length) {
23770-
addDiagnostic(UnusedKind.Local, declarations.length === 1
23771+
addDiagnostic(declarationList, UnusedKind.Local, declarations.length === 1
2377123772
? createDiagnosticForNode(first(declarations).name, Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(first(declarations).name))
2377223773
: createDiagnosticForNode(declarationList.parent.kind === SyntaxKind.VariableStatement ? declarationList.parent : declarationList, Diagnostics.All_variables_are_unused));
2377323774
}
2377423775
else {
2377523776
for (const decl of declarations) {
23776-
addDiagnostic(UnusedKind.Local, createDiagnosticForNode(decl, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(cast(decl.name, isIdentifier))));
23777+
addDiagnostic(decl, UnusedKind.Local, createDiagnosticForNode(decl, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(cast(decl.name, isIdentifier))));
2377723778
}
2377823779
}
2377923780
});
@@ -26626,8 +26627,8 @@ namespace ts {
2662626627
}
2662726628

2662826629
if (!node.isDeclarationFile && (compilerOptions.noUnusedLocals || compilerOptions.noUnusedParameters)) {
26629-
checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(node), (kind, diag) => {
26630-
if (unusedIsError(kind)) {
26630+
checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(node), (containingNode, kind, diag) => {
26631+
if (!containsParseError(containingNode) && unusedIsError(kind)) {
2663126632
diagnostics.add(diag);
2663226633
}
2663326634
});

tests/cases/fourslash/incompleteFunctionCallCodefix2.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,4 @@
33
// @noImplicitAny: true
44
////function f(new C(100, 3, undefined)
55

6-
verify.codeFix({
7-
description: "Prefix 'C' with an underscore",
8-
index: 2,
9-
newFileContent: "function f(new _C(100, 3, undefined)",
10-
});
6+
verify.codeFixAvailable([]); // Parse error, so no unused diagnostics
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @Filename: /a.ts
4+
////export {};
5+
////const a = 1 d;
6+
7+
verify.getSuggestionDiagnostics([]);

0 commit comments

Comments
 (0)