From 2e36c83f775159f3179cd7496f0d8cd5c68c7177 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Wed, 10 May 2017 11:40:15 -0700 Subject: [PATCH] isDeclarationName: Return false for LHS of `import { x as y }` and `export { x as y }` --- src/compiler/checker.ts | 19 ++++++++++++++-- src/compiler/utilities.ts | 22 ++++++------------- .../fourslash/findAllRefsOnImportAliases2.ts | 8 +++---- .../fourslash/findAllRefsReExportLocal.ts | 2 +- tests/cases/fourslash/findAllRefsReExports.ts | 6 ++--- .../cases/fourslash/findAllRefsReExports2.ts | 14 ++++++++++++ .../findAllRefsRenameImportWithSameName.ts | 2 +- .../fourslash/renameImportOfExportEquals2.ts | 4 ++-- .../fourslash/renameImportOfReExport2.ts | 2 +- .../fourslash/transitiveExportImports3.ts | 2 +- 10 files changed, 50 insertions(+), 31 deletions(-) create mode 100644 tests/cases/fourslash/findAllRefsReExports2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index dfccfca1b8f..f17d7a40f58 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22254,7 +22254,7 @@ namespace ts { return undefined; } - if (isDeclarationName(node)) { + if (isDeclarationNameOrImportPropertyName(node)) { // This is a declaration, call getSymbolOfNode return getSymbolOfNode(node.parent); } @@ -22401,7 +22401,7 @@ namespace ts { return getTypeOfSymbol(symbol); } - if (isDeclarationName(node)) { + if (isDeclarationNameOrImportPropertyName(node)) { const symbol = getSymbolAtLocation(node); return symbol && getTypeOfSymbol(symbol); } @@ -24430,4 +24430,19 @@ namespace ts { return result; } } + + /** Like 'isDeclarationName', but returns true for LHS of `import { x as y }` or `export { x as y }`. */ + function isDeclarationNameOrImportPropertyName(name: Node): boolean { + switch (name.parent.kind) { + case SyntaxKind.ImportSpecifier: + case SyntaxKind.ExportSpecifier: + if ((name.parent as ImportOrExportSpecifier).propertyName) { + return true; + } + // falls through + default: + return isDeclarationName(name); + + } + } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 460a9860f1e..95b76286c59 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1758,22 +1758,14 @@ namespace ts { // True if the given identifier, string literal, or number literal is the name of a declaration node export function isDeclarationName(name: Node): boolean { - if (name.kind !== SyntaxKind.Identifier && name.kind !== SyntaxKind.StringLiteral && name.kind !== SyntaxKind.NumericLiteral) { - return false; + switch (name.kind) { + case SyntaxKind.Identifier: + case SyntaxKind.StringLiteral: + case SyntaxKind.NumericLiteral: + return isDeclaration(name.parent) && name.parent.name === name; + default: + return false; } - - const parent = name.parent; - if (parent.kind === SyntaxKind.ImportSpecifier || parent.kind === SyntaxKind.ExportSpecifier) { - if ((parent).propertyName) { - return true; - } - } - - if (isDeclaration(parent)) { - return parent.name === name; - } - - return false; } export function getNameOfDeclaration(declaration: Declaration): DeclarationName { diff --git a/tests/cases/fourslash/findAllRefsOnImportAliases2.ts b/tests/cases/fourslash/findAllRefsOnImportAliases2.ts index 63fb12f5270..64f44018d07 100644 --- a/tests/cases/fourslash/findAllRefsOnImportAliases2.ts +++ b/tests/cases/fourslash/findAllRefsOnImportAliases2.ts @@ -1,16 +1,14 @@ /// //@Filename: a.ts -////export class [|{| "isWriteAccess": true, "isDefinition": true |}Class|] { -////} +////export class [|{| "isWriteAccess": true, "isDefinition": true |}Class|] {} //@Filename: b.ts -////import { [|{| "isWriteAccess": true, "isDefinition": true |}Class|] as [|{| "isWriteAccess": true, "isDefinition": true |}C2|] } from "./a"; -//// +////import { [|Class|] as [|{| "isWriteAccess": true, "isDefinition": true |}C2|] } from "./a"; ////var c = new [|C2|](); //@Filename: c.ts -////export { [|{| "isWriteAccess": true, "isDefinition": true |}Class|] as [|{| "isWriteAccess": true, "isDefinition": true |}C3|] } from "./a"; +////export { [|Class|] as [|{| "isWriteAccess": true, "isDefinition": true |}C3|] } from "./a"; const ranges = test.rangesByText(); const classRanges = ranges.get("Class"); diff --git a/tests/cases/fourslash/findAllRefsReExportLocal.ts b/tests/cases/fourslash/findAllRefsReExportLocal.ts index 25e8accbbc0..3e5890e6317 100644 --- a/tests/cases/fourslash/findAllRefsReExportLocal.ts +++ b/tests/cases/fourslash/findAllRefsReExportLocal.ts @@ -5,7 +5,7 @@ // @Filename: /a.ts ////var [|{| "isWriteAccess": true, "isDefinition": true |}x|]; ////export { [|{| "isWriteAccess": true, "isDefinition": true |}x|] }; -////export { [|{| "isWriteAccess": true, "isDefinition": true |}x|] as [|{| "isWriteAccess": true, "isDefinition": true |}y|] }; +////export { [|x|] as [|{| "isWriteAccess": true, "isDefinition": true |}y|] }; // @Filename: /b.ts ////import { [|{| "isWriteAccess": true, "isDefinition": true |}x|], [|{| "isWriteAccess": true, "isDefinition": true |}y|] } from "./a"; diff --git a/tests/cases/fourslash/findAllRefsReExports.ts b/tests/cases/fourslash/findAllRefsReExports.ts index 593db568c8a..a4cced049b9 100644 --- a/tests/cases/fourslash/findAllRefsReExports.ts +++ b/tests/cases/fourslash/findAllRefsReExports.ts @@ -4,10 +4,10 @@ ////export function [|{| "isWriteAccess": true, "isDefinition": true |}foo|](): void {} // @Filename: /b.ts -////export { [|{| "isWriteAccess": true, "isDefinition": true |}foo|] as [|{| "isWriteAccess": true, "isDefinition": true |}bar|] } from "./a"; +////export { [|foo|] as [|{| "isWriteAccess": true, "isDefinition": true |}bar|] } from "./a"; // @Filename: /c.ts -////export { [|{| "isWriteAccess": true, "isDefinition": true |}foo|] as [|{| "isWriteAccess": true, "isDefinition": true |}default|] } from "./a"; +////export { [|foo|] as [|{| "isWriteAccess": true, "isDefinition": true |}default|] } from "./a"; // @Filename: /d.ts ////export { [|{| "isWriteAccess": true, "isDefinition": true |}default|] } from "./c"; @@ -15,7 +15,7 @@ // @Filename: /e.ts ////import { [|{| "isWriteAccess": true, "isDefinition": true |}bar|] } from "./b"; ////import [|{| "isWriteAccess": true, "isDefinition": true |}baz|] from "./c"; -////import { [|{| "isWriteAccess": true, "isDefinition": true |}default|] as [|{| "isWriteAccess": true, "isDefinition": true |}bang|] } from "./c"; +////import { [|default|] as [|{| "isWriteAccess": true, "isDefinition": true |}bang|] } from "./c"; ////import [|{| "isWriteAccess": true, "isDefinition": true |}boom|] from "./d"; ////[|bar|](); [|baz|](); [|bang|](); [|boom|](); diff --git a/tests/cases/fourslash/findAllRefsReExports2.ts b/tests/cases/fourslash/findAllRefsReExports2.ts new file mode 100644 index 00000000000..5dfdc8aebbf --- /dev/null +++ b/tests/cases/fourslash/findAllRefsReExports2.ts @@ -0,0 +1,14 @@ +/// + +// @Filename: /a.ts +////export function [|{| "isWriteAccess": true, "isDefinition": true |}foo|](): void {} + +// @Filename: /b.ts +////import { [|foo|] as [|{| "isWriteAccess": true, "isDefinition": true |}oof|] } from "./a"; + +verify.noErrors(); +const [r0, r1, r2] = test.ranges(); +verify.referenceGroups(r0, [ + { definition: "function foo(): void", ranges: [r0, r1] }, + { definition: "import oof", ranges: [r2] } +]); diff --git a/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts b/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts index c1a49b3b5b0..5a5db1496a7 100644 --- a/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts +++ b/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts @@ -4,7 +4,7 @@ ////export const [|{| "isWriteAccess": true, "isDefinition": true |}x|] = 0; //@Filename: /b.ts -////import { [|{| "isWriteAccess": true, "isDefinition": true |}x|] as [|{| "isWriteAccess": true, "isDefinition": true |}x|] } from "./a"; +////import { [|x|] as [|{| "isWriteAccess": true, "isDefinition": true |}x|] } from "./a"; ////[|x|]; verify.noErrors(); diff --git a/tests/cases/fourslash/renameImportOfExportEquals2.ts b/tests/cases/fourslash/renameImportOfExportEquals2.ts index f57a10c5777..8ac00b8c012 100644 --- a/tests/cases/fourslash/renameImportOfExportEquals2.ts +++ b/tests/cases/fourslash/renameImportOfExportEquals2.ts @@ -8,10 +8,10 @@ ////} ////declare module "a" { //// import * as [|{| "isWriteAccess": true, "isDefinition": true |}O|] from "mod"; -//// export { [|{| "isWriteAccess": true, "isDefinition": true |}O|] as [|{| "isWriteAccess": true, "isDefinition": true |}P|] }; // Renaming N here would rename +//// export { [|O|] as [|{| "isWriteAccess": true, "isDefinition": true |}P|] }; // Renaming N here would rename ////} ////declare module "b" { -//// import { [|{| "isWriteAccess": true, "isDefinition": true |}P|] as [|{| "isWriteAccess": true, "isDefinition": true |}Q|] } from "a"; +//// import { [|P|] as [|{| "isWriteAccess": true, "isDefinition": true |}Q|] } from "a"; //// export const y: typeof [|Q|].x; ////} diff --git a/tests/cases/fourslash/renameImportOfReExport2.ts b/tests/cases/fourslash/renameImportOfReExport2.ts index 56cc3966112..ac61200b2f0 100644 --- a/tests/cases/fourslash/renameImportOfReExport2.ts +++ b/tests/cases/fourslash/renameImportOfReExport2.ts @@ -4,7 +4,7 @@ //// export class [|{| "isWriteAccess": true, "isDefinition": true |}C|] {} ////} ////declare module "b" { -//// export { [|{| "isWriteAccess": true, "isDefinition": true |}C|] as [|{| "isWriteAccess": true, "isDefinition": true |}D|] } from "a"; +//// export { [|C|] as [|{| "isWriteAccess": true, "isDefinition": true |}D|] } from "a"; ////} ////declare module "c" { //// import { [|{| "isWriteAccess": true, "isDefinition": true |}D|] } from "b"; diff --git a/tests/cases/fourslash/transitiveExportImports3.ts b/tests/cases/fourslash/transitiveExportImports3.ts index 6b3bb10572d..638fa85df83 100644 --- a/tests/cases/fourslash/transitiveExportImports3.ts +++ b/tests/cases/fourslash/transitiveExportImports3.ts @@ -4,7 +4,7 @@ ////export function [|{| "isWriteAccess": true, "isDefinition": true |}f|]() {} // @Filename: b.ts -////export { [|{| "isWriteAccess": true, "isDefinition": true |}f|] as [|{| "isWriteAccess": true, "isDefinition": true |}g|] } from "./a"; +////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";