From 95aae9f41099dd0723fd79fcd5f235fb67120bf6 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Mon, 17 Sep 2018 11:14:29 -0700 Subject: [PATCH] When renaming module, ensure rename span is just the last component of the path --- src/compiler/diagnosticMessages.json | 4 ++++ src/services/rename.ts | 9 ++++++++- .../findAllRefs_importType_exportEquals.ts | 8 ++++---- tests/cases/fourslash/renameImport.ts | 17 ++++++++++++----- 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 5805e2d88d00a..42c594c19b02e 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4145,6 +4145,10 @@ "category": "Error", "code": 8030 }, + "You cannot rename a module via a global import.": { + "category": "Error", + "code": 8031 + }, "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause.": { "category": "Error", "code": 9002 diff --git a/src/services/rename.ts b/src/services/rename.ts index 649ed33786f81..d7f23347cb457 100644 --- a/src/services/rename.ts +++ b/src/services/rename.ts @@ -39,11 +39,18 @@ namespace ts.Rename { } function getRenameInfoForModule(node: StringLiteralLike, sourceFile: SourceFile, moduleSymbol: Symbol): RenameInfo | undefined { + if (!isExternalModuleNameRelative(node.text)) { + return getRenameInfoError(Diagnostics.You_cannot_rename_a_module_via_a_global_import); + } + const moduleSourceFile = find(moduleSymbol.declarations, isSourceFile); if (!moduleSourceFile) return undefined; const withoutIndex = node.text.endsWith("/index") || node.text.endsWith("/index.js") ? undefined : tryRemoveSuffix(removeFileExtension(moduleSourceFile.fileName), "/index"); const name = withoutIndex === undefined ? moduleSourceFile.fileName : withoutIndex; const kind = withoutIndex === undefined ? ScriptElementKind.moduleElement : ScriptElementKind.directory; + const indexAfterLastSlash = node.text.lastIndexOf("/") + 1; + // Span should only be the last component of the path. + 1 to account for the quote character. + const triggerSpan = createTextSpan(node.getStart(sourceFile) + 1 + indexAfterLastSlash, node.text.length - indexAfterLastSlash); return { canRename: true, fileToRename: name, @@ -52,7 +59,7 @@ namespace ts.Rename { localizedErrorMessage: undefined, fullDisplayName: name, kindModifiers: ScriptElementKindModifier.none, - triggerSpan: createTriggerSpanForNode(node, sourceFile), + triggerSpan, }; } diff --git a/tests/cases/fourslash/findAllRefs_importType_exportEquals.ts b/tests/cases/fourslash/findAllRefs_importType_exportEquals.ts index 04b3c212dfc2d..7fe0696f95285 100644 --- a/tests/cases/fourslash/findAllRefs_importType_exportEquals.ts +++ b/tests/cases/fourslash/findAllRefs_importType_exportEquals.ts @@ -8,12 +8,12 @@ ////export = [|T|]; // @Filename: /b.ts -////const x: import("[|./a|]") = 0; -////const y: import("[|./a|]").U = ""; +////const x: import("[|./[|a|]|]") = 0; +////const y: import("[|./[|a|]|]").U = ""; verify.noErrors(); -const [r0, r1, r2, r3, r4] = test.ranges(); +const [r0, r1, r2, r3, r3b, r4, r4b] = test.ranges(); verify.referenceGroups(r0, [{ definition: "type T = number\nnamespace T", ranges: [r0, r2, r3] }]); verify.referenceGroups(r1, [{ definition: "namespace T", ranges: [r1, r2] }]); verify.referenceGroups(r2, [{ definition: "type T = number\nnamespace T", ranges: [r0, r1, r2, r3] }]); @@ -25,7 +25,7 @@ verify.referenceGroups([r3, r4], [ verify.renameLocations(r0, [r0, r2]); verify.renameLocations(r1, [r1, r2]); verify.renameLocations(r2, [r0, r1, r2]); -for (const range of [r3, r4]) { +for (const range of [r3b, r4b]) { goTo.rangeStart(range); verify.renameInfoSucceeded(/*displayName*/ "/a.ts", /*fullDisplayName*/ "/a.ts", /*kind*/ "module", /*kindModifiers*/ "", /*fileToRename*/ "/a.ts", range); } diff --git a/tests/cases/fourslash/renameImport.ts b/tests/cases/fourslash/renameImport.ts index f3221f3584e0a..6fdef347205e9 100644 --- a/tests/cases/fourslash/renameImport.ts +++ b/tests/cases/fourslash/renameImport.ts @@ -2,6 +2,9 @@ // @allowJs: true +// @Filename: /node_modules/global/index.d.ts +////export const x: number; + // @Filename: /a.ts ////export const x = 0; @@ -9,13 +12,14 @@ ////export const x = 0; // @Filename: /b.ts -////import * as a from "[|./a|]"; -////import a2 = require("[|./a|]"); -////import * as dir from "[|{| "target": "dir" |}./dir|]"; -////import * as dir2 from "[|{| "target": "dir/index" |}./dir/index|]"; +////import * as a from "./[|a|]"; +////import a2 = require("./[|a|]"); +////import * as dir from "./[|{| "target": "dir" |}dir|]"; +////import * as dir2 from "./dir/[|{| "target": "dir/index" |}index|]"; // @Filename: /c.js -////const a = require("[|./a|]"); +////const a = require("./[|a|]"); +////const global = require("/*global*/global"); verify.noErrors(); goTo.eachRange(range => { @@ -24,3 +28,6 @@ goTo.eachRange(range => { const kind = target === "dir" ? "directory" : "module"; verify.renameInfoSucceeded(/*displayName*/ name, /*fullDisplayName*/ name, /*kind*/ kind, /*kindModifiers*/ "", /*fileToRename*/ name, range); }); + +goTo.marker("global"); +verify.renameInfoFailed("You cannot rename a module via a global import.");