diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 72ac25c2e21..f8606e2bf1c 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -27,16 +27,31 @@ namespace ts.FindAllReferences { readonly textSpan: TextSpan; } export function nodeEntry(node: Node, kind: NodeEntryKind = EntryKind.Node): NodeEntry { + return { + kind, + node: (node as NamedDeclaration).name || node, + declaration: getDeclarationForDeclarationSpanForNode(node) + }; + } + + function getDeclarationForDeclarationSpanForNode(node: Node): Node | undefined { + if (isDeclaration(node)) { + return getDeclarationForDeclarationSpan(node); + } + // TODO(shkamat):: // JSXOpeningElement or JSXElement for tagName ? - const declaration = getDeclarationForDeclarationSpan( - isDeclaration(node) ? - node : - node.parent && isDeclaration(node.parent) && node.parent.name === node ? - node.parent : - undefined - ); - return { kind, node: (node as NamedDeclaration).name || node, declaration }; + if (!node.parent || !isDeclaration(node.parent)) { + return undefined; + } + + if (node.parent.name === node || // node is name of declaration, use parent + // Property name of the import export specifier use import/export specifier + isImportOrExportSpecifier(node.parent) && node.parent.propertyName === node) { + return getDeclarationForDeclarationSpan(node.parent); + } + + return undefined; } export function getDeclarationForDeclarationSpan(node: NamedDeclaration | undefined): Node | undefined { diff --git a/tests/cases/fourslash/transitiveExportImports.ts b/tests/cases/fourslash/transitiveExportImports.ts index 9cdfb2e3a12..fb5480b28c8 100644 --- a/tests/cases/fourslash/transitiveExportImports.ts +++ b/tests/cases/fourslash/transitiveExportImports.ts @@ -1,22 +1,22 @@ /// // @Filename: a.ts -////class [|{| "isWriteAccess": true, "isDefinition": true |}A|] { -////} +////[|class [|{| "isWriteAccess": true, "isDefinition": true, "declarationRangeIndex": 0 |}A|] { +////}|] ////export = [|A|]; // @Filename: b.ts -////export import [|{| "isWriteAccess": true, "isDefinition": true |}b|] = require('./a'); +////[|export import [|{| "isWriteAccess": true, "isDefinition": true, "declarationRangeIndex": 3 |}b|] = require('./a');|] // @Filename: c.ts -////import [|{| "isWriteAccess": true, "isDefinition": true |}b|] = require('./b'); +////[|import [|{| "isWriteAccess": true, "isDefinition": true, "declarationRangeIndex": 5 |}b|] = require('./b');|] ////var a = new [|b|]./**/[|b|](); goTo.marker(); verify.quickInfoExists(); verify.noErrors(); -const [a0, a1, b0, c0, c1, c2] = test.ranges(); +const [a0Def, a0, a1, b0Def, b0, c0Def, c0, c1, c2] = test.ranges(); const aRanges = [a0, a1]; const bRanges = [b0, c2]; const cRanges = [c0, c1]; diff --git a/tests/cases/fourslash/transitiveExportImports2.ts b/tests/cases/fourslash/transitiveExportImports2.ts index 7ec1e61c02b..8070ad73e04 100644 --- a/tests/cases/fourslash/transitiveExportImports2.ts +++ b/tests/cases/fourslash/transitiveExportImports2.ts @@ -1,20 +1,20 @@ /// // @Filename: a.ts -////namespace [|{| "isWriteAccess": true, "isDefinition": true |}A|] { +////[|namespace [|{| "isWriteAccess": true, "isDefinition": true, "declarationRangeIndex": 0 |}A|] { //// export const x = 0; -////} +////}|] // @Filename: b.ts -////export import [|{| "isWriteAccess": true, "isDefinition": true |}B|] = [|A|]; +////[|export import [|{| "isWriteAccess": true, "isDefinition": true, "declarationRangeIndex": 2 |}B|] = [|A|];|] ////[|B|].x; // @Filename: c.ts -////import { [|{| "isWriteAccess": true, "isDefinition": true |}B|] } from "./b"; +////[|import { [|{| "isWriteAccess": true, "isDefinition": true, "declarationRangeIndex": 6 |}B|] } from "./b";|] verify.noErrors(); -const [A0, B0, A1, B1, B2] = test.ranges(); +const [A0Def, A0, B0Def, B0, A1, B1, B2Def, B2] = test.ranges(); const aRanges = [A0, A1]; const bRanges = [B0, B1]; const cRanges = [B2]; diff --git a/tests/cases/fourslash/transitiveExportImports3.ts b/tests/cases/fourslash/transitiveExportImports3.ts index c5d6dfe9afc..ab8c5e8ca1b 100644 --- a/tests/cases/fourslash/transitiveExportImports3.ts +++ b/tests/cases/fourslash/transitiveExportImports3.ts @@ -1,16 +1,16 @@ /// // @Filename: a.ts -////export function [|{| "isWriteAccess": true, "isDefinition": true |}f|]() {} +////[|export function [|{| "isWriteAccess": true, "isDefinition": true, "declarationRangeIndex": 0 |}f|]() {}|] // @Filename: b.ts -////export { [|f|] as [|{| "isWriteAccess": true, "isDefinition": true |}g|] } from "./a"; -////import { [|{| "isWriteAccess": true, "isDefinition": true |}f|] } from "./a"; -////import { [|{| "isWriteAccess": true, "isDefinition": true |}g|] } from "./b"; +////[|export { [|{| "declarationRangeIndex": 2 |}f|] as [|{| "isWriteAccess": true, "isDefinition": true, "declarationRangeIndex": 2 |}g|] } from "./a";|] +////[|import { [|{| "isWriteAccess": true, "isDefinition": true, "declarationRangeIndex": 5 |}f|] } from "./a";|] +////[|import { [|{| "isWriteAccess": true, "isDefinition": true, "declarationRangeIndex": 7 |}g|] } from "./b";|] verify.noErrors(); -const [f0, f1, g0, f2, g1] = test.ranges(); +const [f0Def, f0, f1Def, f1, g0, f2Def, f2, g1Def, g1] = test.ranges(); const af = { definition: "function f(): void", ranges: [f0, f1] }; const g0Group = { definition: "(alias) function g(): void\nexport g", ranges: [g0] }; diff --git a/tests/cases/fourslash/tsxFindAllReferences2.ts b/tests/cases/fourslash/tsxFindAllReferences2.ts index d83cb426992..f1b71e51811 100644 --- a/tests/cases/fourslash/tsxFindAllReferences2.ts +++ b/tests/cases/fourslash/tsxFindAllReferences2.ts @@ -15,6 +15,6 @@ const rangesByText = test.rangesByText(); verify.singleReferenceGroup( - "(property) name ?: string", + "(property) name?: string", rangesByText.get("name") );