From d137029f786e63bf29db6ff36feff5e3b7733a33 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Mon, 11 Jun 2018 09:18:38 -0700 Subject: [PATCH] goToDefinition: Don't add duplicate definitions for VariableDeclaration and ArrowFunction at `f = () => {}` --- src/services/goToDefinition.ts | 11 ++++++++++- tests/cases/fourslash/goToDefinitionSignatureAlias.ts | 9 +++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 1281f30d73371..2c0a1f2b75655 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -32,7 +32,7 @@ namespace ts.GoToDefinition { const sigInfo = createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration); // For a function, if this is the original function definition, return just sigInfo. // If this is the original constructor definition, parent is the class. - if (typeChecker.getRootSymbols(symbol).some(s => calledDeclaration.symbol === s || calledDeclaration.symbol.parent === s) || + if (typeChecker.getRootSymbols(symbol).some(s => symbolMatchesSignature(s, calledDeclaration)) || // TODO: GH#23742 Following check shouldn't be necessary if 'require' is an alias symbol.declarations.some(d => isVariableDeclaration(d) && !!d.initializer && isRequireCall(d.initializer, /*checkArgumentIsStringLiteralLike*/ false))) { return [sigInfo]; @@ -93,6 +93,15 @@ namespace ts.GoToDefinition { return getDefinitionFromSymbol(typeChecker, symbol, node); } + /** + * True if we should not add definitions for both the signature symbol and the definition symbol. + * True for `const |f = |() => 0`, false for `function |f() {} const |g = f;`. + */ + function symbolMatchesSignature(s: Symbol, calledDeclaration: SignatureDeclaration) { + return s === calledDeclaration.symbol || s === calledDeclaration.symbol.parent || + isVariableDeclaration(calledDeclaration.parent) && s === calledDeclaration.parent.symbol; + } + export function getReferenceAtPosition(sourceFile: SourceFile, position: number, program: Program): { fileName: string, file: SourceFile } | undefined { const referencePath = findReferenceInPosition(sourceFile.referencedFiles, position); if (referencePath) { diff --git a/tests/cases/fourslash/goToDefinitionSignatureAlias.ts b/tests/cases/fourslash/goToDefinitionSignatureAlias.ts index 27ff0eb69d974..3657ebfd0d6a8 100644 --- a/tests/cases/fourslash/goToDefinitionSignatureAlias.ts +++ b/tests/cases/fourslash/goToDefinitionSignatureAlias.ts @@ -8,8 +8,17 @@ ////[|/*useG*/g|](); ////[|/*useH*/h|](); +////const i = /*i*/() => 0; +////const /*j*/j = i; + +////[|/*useI*/i|](); +////[|/*useJ*/j|](); + verify.goToDefinition({ useF: "f", useG: ["g", "f"], useH: ["h", "f"], + + useI: "i", + useJ: ["j", "i"], });