@@ -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);
@@ -4682,13 +4683,7 @@ namespace ts {
46824683 }
46834684 }
46844685 // Use contextual parameter type if one is available
4685- let type: Type | undefined;
4686- if (declaration.symbol.escapedName === "this") {
4687- type = getContextualThisParameterType(func);
4688- }
4689- else {
4690- type = getContextuallyTypedParameterType(declaration);
4691- }
4686+ const type = declaration.symbol.escapedName === "this" ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration);
46924687 if (type) {
46934688 return addOptionality(type, isOptional);
46944689 }
@@ -16209,7 +16204,7 @@ namespace ts {
1620916204
1621016205 // If the given type is an object or union type with a single signature, and if that signature has at
1621116206 // least as many parameters as the given function, return the signature. Otherwise return undefined.
16212- function getContextualCallSignature(type: Type, node: FunctionExpression | ArrowFunction | MethodDeclaration ): Signature | undefined {
16207+ function getContextualCallSignature(type: Type, node: SignatureDeclaration ): Signature | undefined {
1621316208 const signatures = getSignaturesOfType(type, SignatureKind.Call);
1621416209 if (signatures.length === 1) {
1621516210 const signature = signatures[0];
@@ -16220,7 +16215,7 @@ namespace ts {
1622016215 }
1622116216
1622216217 /** If the contextual signature has fewer parameters than the function expression, do not use it */
16223- function isAritySmaller(signature: Signature, target: FunctionExpression | ArrowFunction | MethodDeclaration ) {
16218+ function isAritySmaller(signature: Signature, target: SignatureDeclaration ) {
1622416219 let targetParameterCount = 0;
1622516220 for (; targetParameterCount < target.parameters.length; targetParameterCount++) {
1622616221 const param = target.parameters[targetParameterCount];
@@ -23538,12 +23533,13 @@ namespace ts {
2353823533 // yielded values. The only way to trigger these errors is to try checking its return type.
2353923534 getReturnTypeOfSignature(getSignatureFromDeclaration(node));
2354023535 }
23541- // A js function declaration can have a @type tag instead of a return type node, but that type must have a call signature
23542- if (isInJavaScriptFile(node)) {
23543- const typeTag = getJSDocTypeTag(node);
23544- if (typeTag && typeTag.typeExpression && !getSignaturesOfType(getTypeFromTypeNode(typeTag.typeExpression), SignatureKind.Call).length) {
23545- error(typeTag, Diagnostics.The_type_of_a_function_declaration_must_be_callable);
23546- }
23536+ }
23537+
23538+ // A js function declaration can have a @type tag instead of a return type node, but that type must have a call signature
23539+ if (isInJavaScriptFile(node)) {
23540+ const typeTag = getJSDocTypeTag(node);
23541+ if (typeTag && typeTag.typeExpression && !getContextualCallSignature(getTypeFromTypeNode(typeTag.typeExpression), node)) {
23542+ error(typeTag, Diagnostics.The_type_of_a_function_declaration_must_match_the_function_s_signature);
2354723543 }
2354823544 }
2354923545 }
@@ -23617,7 +23613,7 @@ namespace ts {
2361723613 function errorUnusedLocal(declaration: Declaration, name: string, addDiagnostic: AddUnusedDiagnostic) {
2361823614 const node = getNameOfDeclaration(declaration) || declaration;
2361923615 const message = isTypeDeclaration(declaration) ? Diagnostics._0_is_declared_but_never_used : Diagnostics._0_is_declared_but_its_value_is_never_read;
23620- addDiagnostic(UnusedKind.Local, createDiagnosticForNode(node, message, name));
23616+ addDiagnostic(declaration, UnusedKind.Local, createDiagnosticForNode(node, message, name));
2362123617 }
2362223618
2362323619 function isIdentifierThatStartsWithUnderscore(node: Node) {
@@ -23638,13 +23634,13 @@ namespace ts {
2363823634 }
2363923635 const symbol = getSymbolOfNode(member);
2364023636 if (!symbol.isReferenced && hasModifier(member, ModifierFlags.Private)) {
23641- 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)));
2364223638 }
2364323639 break;
2364423640 case SyntaxKind.Constructor:
2364523641 for (const parameter of (<ConstructorDeclaration>member).parameters) {
2364623642 if (!parameter.symbol.isReferenced && hasModifier(parameter, ModifierFlags.Private)) {
23647- 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)));
2364823644 }
2364923645 }
2365023646 break;
@@ -23669,7 +23665,7 @@ namespace ts {
2366923665 if (!(node.flags & NodeFlags.Ambient) && last(getSymbolOfNode(node).declarations) === node) {
2367023666 for (const typeParameter of typeParameters) {
2367123667 if (!(getMergedSymbol(typeParameter.symbol).isReferenced! & SymbolFlags.TypeParameter) && !isIdentifierThatStartsWithUnderscore(typeParameter.name)) {
23672- 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)));
2367323669 }
2367423670 }
2367523671 }
@@ -23728,7 +23724,7 @@ namespace ts {
2372823724 const name = local.valueDeclaration && getNameOfDeclaration(local.valueDeclaration);
2372923725 if (parameter && name) {
2373023726 if (!isParameterPropertyDeclaration(parameter) && !parameterIsThisKeyword(parameter) && !isIdentifierThatStartsWithUnderscore(name)) {
23731- 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)));
2373223728 }
2373323729 }
2373423730 else {
@@ -23744,7 +23740,7 @@ namespace ts {
2374423740 (importClause.namedBindings.kind === SyntaxKind.NamespaceImport ? 1 : importClause.namedBindings.elements.length)
2374523741 : 0);
2374623742 if (nDeclarations === unuseds.length) {
23747- addDiagnostic(UnusedKind.Local, unuseds.length === 1
23743+ addDiagnostic(importDecl, UnusedKind.Local, unuseds.length === 1
2374823744 ? createDiagnosticForNode(importDecl, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(first(unuseds).name!))
2374923745 : createDiagnosticForNode(importDecl, Diagnostics.All_imports_in_import_declaration_are_unused));
2375023746 }
@@ -23759,26 +23755,26 @@ namespace ts {
2375923755 addToGroup(unusedVariables, bindingPattern.parent.parent, bindingPattern.parent, getNodeId);
2376023756 }
2376123757 else {
23762- addDiagnostic(kind, bindingElements.length === 1
23758+ addDiagnostic(bindingPattern, kind, bindingElements.length === 1
2376323759 ? createDiagnosticForNode(bindingPattern, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(cast(first(bindingElements).name, isIdentifier)))
2376423760 : createDiagnosticForNode(bindingPattern, Diagnostics.All_destructured_elements_are_unused));
2376523761 }
2376623762 }
2376723763 else {
2376823764 for (const e of bindingElements) {
23769- 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))));
2377023766 }
2377123767 }
2377223768 });
2377323769 unusedVariables.forEach(([declarationList, declarations]) => {
2377423770 if (declarationList.declarations.length === declarations.length) {
23775- addDiagnostic(UnusedKind.Local, declarations.length === 1
23771+ addDiagnostic(declarationList, UnusedKind.Local, declarations.length === 1
2377623772 ? createDiagnosticForNode(first(declarations).name, Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(first(declarations).name))
2377723773 : createDiagnosticForNode(declarationList.parent.kind === SyntaxKind.VariableStatement ? declarationList.parent : declarationList, Diagnostics.All_variables_are_unused));
2377823774 }
2377923775 else {
2378023776 for (const decl of declarations) {
23781- 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))));
2378223778 }
2378323779 }
2378423780 });
@@ -26631,8 +26627,8 @@ namespace ts {
2663126627 }
2663226628
2663326629 if (!node.isDeclarationFile && (compilerOptions.noUnusedLocals || compilerOptions.noUnusedParameters)) {
26634- checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(node), (kind, diag) => {
26635- if (unusedIsError(kind)) {
26630+ checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(node), (containingNode, kind, diag) => {
26631+ if (!containsParseError(containingNode) && unusedIsError(kind)) {
2663626632 diagnostics.add(diag);
2663726633 }
2663826634 });
0 commit comments