From bc80712a7b8b13d9f62edd2d8e002130a317fee5 Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Tue, 15 Jun 2021 12:15:03 -0700 Subject: [PATCH 1/6] don't add .ts extensions to imports --- src/services/stringCompletions.ts | 35 ++++++++++++++----- ...ompletionImportModuleSpecifierEndingJs.ts} | 0 ...completionImportModuleSpecifierEndingTs.ts | 11 ++++++ 3 files changed, 37 insertions(+), 9 deletions(-) rename tests/cases/fourslash/{completionImportModuleSpecifierEnding.ts => completionImportModuleSpecifierEndingJs.ts} (100%) create mode 100644 tests/cases/fourslash/completionImportModuleSpecifierEndingTs.ts diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index 92d205ed8bcdb..e8b55f488d126 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -321,13 +321,14 @@ namespace ts.Completions.StringCompletions { interface ExtensionOptions { readonly extensions: readonly Extension[]; - readonly includeExtensions: boolean; + readonly includeExtensionsOption: IncludeExtensionsOption; } - function getExtensionOptions(compilerOptions: CompilerOptions, includeExtensions = false): ExtensionOptions { - return { extensions: getSupportedExtensionsForModuleResolution(compilerOptions), includeExtensions }; + function getExtensionOptions(compilerOptions: CompilerOptions, includeExtensionsOption = IncludeExtensionsOption.Exclude): ExtensionOptions { + return { extensions: getSupportedExtensionsForModuleResolution(compilerOptions), includeExtensionsOption }; } function getCompletionEntriesForRelativeModules(literalValue: string, scriptDirectory: string, compilerOptions: CompilerOptions, host: LanguageServiceHost, scriptPath: Path, preferences: UserPreferences) { - const extensionOptions = getExtensionOptions(compilerOptions, preferences.importModuleSpecifierEnding === "js"); + const includeExtensions = preferences.importModuleSpecifierEnding === "js" ? IncludeExtensionsOption.ModuleSpecifierCompletion : IncludeExtensionsOption.Exclude; + const extensionOptions = getExtensionOptions(compilerOptions, includeExtensions); if (compilerOptions.rootDirs) { return getCompletionEntriesForDirectoryFragmentWithRootDirs( compilerOptions.rootDirs, literalValue, scriptDirectory, extensionOptions, compilerOptions, host, scriptPath); @@ -370,10 +371,15 @@ namespace ts.Completions.StringCompletions { return flatMap(baseDirectories, baseDirectory => getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensionOptions, host, exclude)); } + enum IncludeExtensionsOption { + Exclude, + Include, + ModuleSpecifierCompletion, + } /** * Given a path ending at a directory, gets the completions for the path, and filters for those entries containing the basename. */ - function getCompletionEntriesForDirectoryFragment(fragment: string, scriptPath: string, { extensions, includeExtensions }: ExtensionOptions, host: LanguageServiceHost, exclude?: string, result: NameAndKind[] = []): NameAndKind[] { + function getCompletionEntriesForDirectoryFragment(fragment: string, scriptPath: string, { extensions, includeExtensionsOption }: ExtensionOptions, host: LanguageServiceHost, exclude?: string, result: NameAndKind[] = []): NameAndKind[] { if (fragment === undefined) { fragment = ""; } @@ -407,7 +413,7 @@ namespace ts.Completions.StringCompletions { if (files) { /** * Multiple file entries might map to the same truncated name once we remove extensions - * (happens iff includeExtensions === false)so we use a set-like data structure. Eg: + * (happens iff includeExtensionsOption === includeExtensionsOption.Exclude) so we use a set-like data structure. Eg: * * both foo.ts and foo.tsx become foo */ @@ -418,8 +424,19 @@ namespace ts.Completions.StringCompletions { continue; } - const foundFileName = includeExtensions || fileExtensionIs(filePath, Extension.Json) ? getBaseFileName(filePath) : removeFileExtension(getBaseFileName(filePath)); - foundFiles.set(foundFileName, tryGetExtensionFromPath(filePath)); + let foundFileName: string; + if (includeExtensionsOption === IncludeExtensionsOption.Exclude && !fileExtensionIs(filePath, Extension.Json)) { + foundFileName = removeFileExtension(getBaseFileName(filePath)); + foundFiles.set(foundFileName, tryGetExtensionFromPath(filePath)); + } + else if (includeExtensionsOption === IncludeExtensionsOption.ModuleSpecifierCompletion && fileExtensionIs(filePath, Extension.Ts)) { + foundFileName = changeExtension(getBaseFileName(filePath), Extension.Js); + foundFiles.set(foundFileName, Extension.Js); + } + else { + foundFileName = getBaseFileName(filePath); + foundFiles.set(foundFileName, tryGetExtensionFromPath(filePath)); + } } foundFiles.forEach((ext, foundFile) => { @@ -635,7 +652,7 @@ namespace ts.Completions.StringCompletions { const [, prefix, kind, toComplete] = match; const scriptPath = getDirectoryPath(sourceFile.path); - const names = kind === "path" ? getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getExtensionOptions(compilerOptions, /*includeExtensions*/ true), host, sourceFile.path) + const names = kind === "path" ? getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getExtensionOptions(compilerOptions, IncludeExtensionsOption.Include), host, sourceFile.path) : kind === "types" ? getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, getFragmentDirectory(toComplete), getExtensionOptions(compilerOptions)) : Debug.fail(); return addReplacementSpans(toComplete, range.pos + prefix.length, names); diff --git a/tests/cases/fourslash/completionImportModuleSpecifierEnding.ts b/tests/cases/fourslash/completionImportModuleSpecifierEndingJs.ts similarity index 100% rename from tests/cases/fourslash/completionImportModuleSpecifierEnding.ts rename to tests/cases/fourslash/completionImportModuleSpecifierEndingJs.ts diff --git a/tests/cases/fourslash/completionImportModuleSpecifierEndingTs.ts b/tests/cases/fourslash/completionImportModuleSpecifierEndingTs.ts new file mode 100644 index 0000000000000..877f1958e5416 --- /dev/null +++ b/tests/cases/fourslash/completionImportModuleSpecifierEndingTs.ts @@ -0,0 +1,11 @@ +/// +//@Filename:test.ts +////export function f(){ +//// return 1 +////} + +//@Filename:module.ts +////import { f } from ".//**/" + + +verify.completions({ marker: "", includes:{name:"test.js"}, preferences: {importModuleSpecifierEnding: "js" }, isNewIdentifierLocation: true}) \ No newline at end of file From 76509c3cfb326254468a69dbcc10480c25857bef Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Tue, 15 Jun 2021 14:32:28 -0700 Subject: [PATCH 2/6] Update src/services/stringCompletions.ts Co-authored-by: Andrew Branch --- src/services/stringCompletions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index e8b55f488d126..f24717654e5b2 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -371,7 +371,7 @@ namespace ts.Completions.StringCompletions { return flatMap(baseDirectories, baseDirectory => getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensionOptions, host, exclude)); } - enum IncludeExtensionsOption { + const enum IncludeExtensionsOption { Exclude, Include, ModuleSpecifierCompletion, From 25555c35c663894a650e2f14b030b68bade5f7c2 Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Mon, 21 Jun 2021 12:55:30 -0700 Subject: [PATCH 3/6] add other supported extension types --- src/compiler/moduleSpecifiers.ts | 12 +++++++----- src/services/stringCompletions.ts | 7 ++++--- .../completionImportModuleSpecifierEndingDts.ts | 9 +++++++++ .../completionImportModuleSpecifierEndingJs.ts | 4 ++-- .../completionImportModuleSpecifierEndingJsx.ts | 11 +++++++++++ .../completionImportModuleSpecifierEndingTs.ts | 4 ++-- ...mpletionImportModuleSpecifierEndingTsxPreserve.ts | 10 ++++++++++ .../completionImportModuleSpecifierEndingTsxReact.ts | 10 ++++++++++ 8 files changed, 55 insertions(+), 12 deletions(-) create mode 100644 tests/cases/fourslash/completionImportModuleSpecifierEndingDts.ts create mode 100644 tests/cases/fourslash/completionImportModuleSpecifierEndingJsx.ts create mode 100644 tests/cases/fourslash/completionImportModuleSpecifierEndingTsxPreserve.ts create mode 100644 tests/cases/fourslash/completionImportModuleSpecifierEndingTsxReact.ts diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index cc42d82f48247..821a680b2e0c3 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -687,13 +687,17 @@ namespace ts.moduleSpecifiers { case Ending.Index: return noExtension; case Ending.JsExtension: - return noExtension + getJSExtensionForFile(fileName, options); + return noExtension + getJSExtensionForFileIfApplicable(fileName, options); default: return Debug.assertNever(ending); } } - function getJSExtensionForFile(fileName: string, options: CompilerOptions): Extension { + function getJSExtensionForFileIfApplicable(fileName: string, options: CompilerOptions): Extension { + return getJSExtensionForFile(fileName, options) ?? Debug.fail(`Extension ${extensionFromPath(fileName)} is unsupported:: FileName:: ${fileName}`); + } + + export function getJSExtensionForFile(fileName: string, options: CompilerOptions): Extension | undefined { const ext = extensionFromPath(fileName); switch (ext) { case Extension.Ts: @@ -705,10 +709,8 @@ namespace ts.moduleSpecifiers { case Extension.Jsx: case Extension.Json: return ext; - case Extension.TsBuildInfo: - return Debug.fail(`Extension ${Extension.TsBuildInfo} is unsupported:: FileName:: ${fileName}`); default: - return Debug.assertNever(ext); + return undefined; } } diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index f24717654e5b2..b21cc52e242a6 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -425,13 +425,14 @@ namespace ts.Completions.StringCompletions { } let foundFileName: string; + const outputExtension = moduleSpecifiers.getJSExtensionForFile(filePath, host.getCompilationSettings()); if (includeExtensionsOption === IncludeExtensionsOption.Exclude && !fileExtensionIs(filePath, Extension.Json)) { foundFileName = removeFileExtension(getBaseFileName(filePath)); foundFiles.set(foundFileName, tryGetExtensionFromPath(filePath)); } - else if (includeExtensionsOption === IncludeExtensionsOption.ModuleSpecifierCompletion && fileExtensionIs(filePath, Extension.Ts)) { - foundFileName = changeExtension(getBaseFileName(filePath), Extension.Js); - foundFiles.set(foundFileName, Extension.Js); + else if (includeExtensionsOption === IncludeExtensionsOption.ModuleSpecifierCompletion && outputExtension) { + foundFileName = changeExtension(getBaseFileName(filePath), outputExtension); + foundFiles.set(foundFileName, outputExtension); } else { foundFileName = getBaseFileName(filePath); diff --git a/tests/cases/fourslash/completionImportModuleSpecifierEndingDts.ts b/tests/cases/fourslash/completionImportModuleSpecifierEndingDts.ts new file mode 100644 index 0000000000000..4d80c8d68c14c --- /dev/null +++ b/tests/cases/fourslash/completionImportModuleSpecifierEndingDts.ts @@ -0,0 +1,9 @@ +/// +//@Filename:test.d.ts +//// export declare class Test {} + +//@Filename:module.ts +////import { Test } from ".//**/" + +verify.completions({ marker: "", includes:{name:"test.js"}, preferences: {importModuleSpecifierEnding: "js" }, isNewIdentifierLocation: true}); +verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); \ No newline at end of file diff --git a/tests/cases/fourslash/completionImportModuleSpecifierEndingJs.ts b/tests/cases/fourslash/completionImportModuleSpecifierEndingJs.ts index 7771a9ac781d3..38cbdd39f6b21 100644 --- a/tests/cases/fourslash/completionImportModuleSpecifierEndingJs.ts +++ b/tests/cases/fourslash/completionImportModuleSpecifierEndingJs.ts @@ -8,5 +8,5 @@ //@Filename:module.js ////import { f } from ".//**/" - -verify.completions({ marker: "", includes:{name:"test.js"}, preferences: {importModuleSpecifierEnding: "js" }, isNewIdentifierLocation: true}) \ No newline at end of file +verify.completions({ marker: "", includes:{name:"test.js"}, preferences: {importModuleSpecifierEnding: "js" }, isNewIdentifierLocation: true}); +verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); \ No newline at end of file diff --git a/tests/cases/fourslash/completionImportModuleSpecifierEndingJsx.ts b/tests/cases/fourslash/completionImportModuleSpecifierEndingJsx.ts new file mode 100644 index 0000000000000..c57ef7350d88b --- /dev/null +++ b/tests/cases/fourslash/completionImportModuleSpecifierEndingJsx.ts @@ -0,0 +1,11 @@ +/// +//@allowJs: true +//@jsx:preserve +//@Filename:test.jsx +//// export class Test { } + +//@Filename:module.jsx +////import { Test } from ".//**/" + +verify.completions({ marker: "", includes:{name:"test.jsx"}, preferences: {importModuleSpecifierEnding: "js"}, isNewIdentifierLocation: true}); +verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); \ No newline at end of file diff --git a/tests/cases/fourslash/completionImportModuleSpecifierEndingTs.ts b/tests/cases/fourslash/completionImportModuleSpecifierEndingTs.ts index 877f1958e5416..15ec4746f841c 100644 --- a/tests/cases/fourslash/completionImportModuleSpecifierEndingTs.ts +++ b/tests/cases/fourslash/completionImportModuleSpecifierEndingTs.ts @@ -7,5 +7,5 @@ //@Filename:module.ts ////import { f } from ".//**/" - -verify.completions({ marker: "", includes:{name:"test.js"}, preferences: {importModuleSpecifierEnding: "js" }, isNewIdentifierLocation: true}) \ No newline at end of file +verify.completions({ marker: "", includes:{name:"test.js"}, preferences: {importModuleSpecifierEnding: "js" }, isNewIdentifierLocation: true}); +verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); \ No newline at end of file diff --git a/tests/cases/fourslash/completionImportModuleSpecifierEndingTsxPreserve.ts b/tests/cases/fourslash/completionImportModuleSpecifierEndingTsxPreserve.ts new file mode 100644 index 0000000000000..8d8bd9820367e --- /dev/null +++ b/tests/cases/fourslash/completionImportModuleSpecifierEndingTsxPreserve.ts @@ -0,0 +1,10 @@ +/// +//@jsx:preserve +//@Filename:test.tsx +//// export class Test { } + +//@Filename:module.tsx +////import { Test } from ".//**/" + +verify.completions({ marker: "", includes:{name:"test.jsx"}, preferences: {importModuleSpecifierEnding: "js"}, isNewIdentifierLocation: true}); +verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); \ No newline at end of file diff --git a/tests/cases/fourslash/completionImportModuleSpecifierEndingTsxReact.ts b/tests/cases/fourslash/completionImportModuleSpecifierEndingTsxReact.ts new file mode 100644 index 0000000000000..f3aaf7ddbb8b5 --- /dev/null +++ b/tests/cases/fourslash/completionImportModuleSpecifierEndingTsxReact.ts @@ -0,0 +1,10 @@ +/// +//@jsx:react +//@Filename:test.tsx +//// export class Test { } + +//@Filename:module.tsx +////import { Test } from ".//**/" + +verify.completions({ marker: "", includes:{name:"test.js"}, preferences: {importModuleSpecifierEnding: "js"}, isNewIdentifierLocation: true}); +verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); \ No newline at end of file From ab950c05c6da90682beccfdaec295e3071514722 Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Mon, 21 Jun 2021 12:58:25 -0700 Subject: [PATCH 4/6] add final newlines --- .../cases/fourslash/completionImportModuleSpecifierEndingDts.ts | 2 +- .../cases/fourslash/completionImportModuleSpecifierEndingJs.ts | 2 +- .../cases/fourslash/completionImportModuleSpecifierEndingJsx.ts | 2 +- .../cases/fourslash/completionImportModuleSpecifierEndingTs.ts | 2 +- .../completionImportModuleSpecifierEndingTsxPreserve.ts | 2 +- .../fourslash/completionImportModuleSpecifierEndingTsxReact.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/cases/fourslash/completionImportModuleSpecifierEndingDts.ts b/tests/cases/fourslash/completionImportModuleSpecifierEndingDts.ts index 4d80c8d68c14c..2fc97f4868d0b 100644 --- a/tests/cases/fourslash/completionImportModuleSpecifierEndingDts.ts +++ b/tests/cases/fourslash/completionImportModuleSpecifierEndingDts.ts @@ -6,4 +6,4 @@ ////import { Test } from ".//**/" verify.completions({ marker: "", includes:{name:"test.js"}, preferences: {importModuleSpecifierEnding: "js" }, isNewIdentifierLocation: true}); -verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); \ No newline at end of file +verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); diff --git a/tests/cases/fourslash/completionImportModuleSpecifierEndingJs.ts b/tests/cases/fourslash/completionImportModuleSpecifierEndingJs.ts index 38cbdd39f6b21..120c0c7680988 100644 --- a/tests/cases/fourslash/completionImportModuleSpecifierEndingJs.ts +++ b/tests/cases/fourslash/completionImportModuleSpecifierEndingJs.ts @@ -9,4 +9,4 @@ ////import { f } from ".//**/" verify.completions({ marker: "", includes:{name:"test.js"}, preferences: {importModuleSpecifierEnding: "js" }, isNewIdentifierLocation: true}); -verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); \ No newline at end of file +verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); diff --git a/tests/cases/fourslash/completionImportModuleSpecifierEndingJsx.ts b/tests/cases/fourslash/completionImportModuleSpecifierEndingJsx.ts index c57ef7350d88b..41043b250ab96 100644 --- a/tests/cases/fourslash/completionImportModuleSpecifierEndingJsx.ts +++ b/tests/cases/fourslash/completionImportModuleSpecifierEndingJsx.ts @@ -8,4 +8,4 @@ ////import { Test } from ".//**/" verify.completions({ marker: "", includes:{name:"test.jsx"}, preferences: {importModuleSpecifierEnding: "js"}, isNewIdentifierLocation: true}); -verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); \ No newline at end of file +verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); diff --git a/tests/cases/fourslash/completionImportModuleSpecifierEndingTs.ts b/tests/cases/fourslash/completionImportModuleSpecifierEndingTs.ts index 15ec4746f841c..92510ee6a598f 100644 --- a/tests/cases/fourslash/completionImportModuleSpecifierEndingTs.ts +++ b/tests/cases/fourslash/completionImportModuleSpecifierEndingTs.ts @@ -8,4 +8,4 @@ ////import { f } from ".//**/" verify.completions({ marker: "", includes:{name:"test.js"}, preferences: {importModuleSpecifierEnding: "js" }, isNewIdentifierLocation: true}); -verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); \ No newline at end of file +verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); diff --git a/tests/cases/fourslash/completionImportModuleSpecifierEndingTsxPreserve.ts b/tests/cases/fourslash/completionImportModuleSpecifierEndingTsxPreserve.ts index 8d8bd9820367e..97857185c4490 100644 --- a/tests/cases/fourslash/completionImportModuleSpecifierEndingTsxPreserve.ts +++ b/tests/cases/fourslash/completionImportModuleSpecifierEndingTsxPreserve.ts @@ -7,4 +7,4 @@ ////import { Test } from ".//**/" verify.completions({ marker: "", includes:{name:"test.jsx"}, preferences: {importModuleSpecifierEnding: "js"}, isNewIdentifierLocation: true}); -verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); \ No newline at end of file +verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); diff --git a/tests/cases/fourslash/completionImportModuleSpecifierEndingTsxReact.ts b/tests/cases/fourslash/completionImportModuleSpecifierEndingTsxReact.ts index f3aaf7ddbb8b5..43f8fcb211cda 100644 --- a/tests/cases/fourslash/completionImportModuleSpecifierEndingTsxReact.ts +++ b/tests/cases/fourslash/completionImportModuleSpecifierEndingTsxReact.ts @@ -7,4 +7,4 @@ ////import { Test } from ".//**/" verify.completions({ marker: "", includes:{name:"test.js"}, preferences: {importModuleSpecifierEnding: "js"}, isNewIdentifierLocation: true}); -verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); \ No newline at end of file +verify.completions({ marker: "", includes:{name:"test"}, preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true}); From 5adaabcbc73fd9070ad93fdf301d8d667303e0e1 Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Mon, 21 Jun 2021 13:51:00 -0700 Subject: [PATCH 5/6] adress PR comment --- src/compiler/moduleSpecifiers.ts | 10 +++++----- src/services/stringCompletions.ts | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 821a680b2e0c3..3c44fd95205aa 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -687,18 +687,18 @@ namespace ts.moduleSpecifiers { case Ending.Index: return noExtension; case Ending.JsExtension: - return noExtension + getJSExtensionForFileIfApplicable(fileName, options); + return noExtension + getJSExtensionForFile(fileName, options); default: return Debug.assertNever(ending); } } - function getJSExtensionForFileIfApplicable(fileName: string, options: CompilerOptions): Extension { - return getJSExtensionForFile(fileName, options) ?? Debug.fail(`Extension ${extensionFromPath(fileName)} is unsupported:: FileName:: ${fileName}`); + function getJSExtensionForFile(fileName: string, options: CompilerOptions): Extension { + return tryGetJSExtensionForFile(fileName, options) ?? Debug.fail(`Extension ${extensionFromPath(fileName)} is unsupported:: FileName:: ${fileName}`); } - export function getJSExtensionForFile(fileName: string, options: CompilerOptions): Extension | undefined { - const ext = extensionFromPath(fileName); + export function tryGetJSExtensionForFile(fileName: string, options: CompilerOptions): Extension | undefined { + const ext = tryGetExtensionFromPath(fileName); switch (ext) { case Extension.Ts: case Extension.Dts: diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index b21cc52e242a6..ac0c1baeb6907 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -425,7 +425,7 @@ namespace ts.Completions.StringCompletions { } let foundFileName: string; - const outputExtension = moduleSpecifiers.getJSExtensionForFile(filePath, host.getCompilationSettings()); + const outputExtension = moduleSpecifiers.tryGetJSExtensionForFile(filePath, host.getCompilationSettings()); if (includeExtensionsOption === IncludeExtensionsOption.Exclude && !fileExtensionIs(filePath, Extension.Json)) { foundFileName = removeFileExtension(getBaseFileName(filePath)); foundFiles.set(foundFileName, tryGetExtensionFromPath(filePath)); From 15a473539ee7657e83dc654537165816c5df17f8 Mon Sep 17 00:00:00 2001 From: Jesse Trinity Date: Mon, 21 Jun 2021 13:57:10 -0700 Subject: [PATCH 6/6] add unsupported extension test --- ...ionImportModuleSpecifierEndingUnsupportedExtension.ts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 tests/cases/fourslash/completionImportModuleSpecifierEndingUnsupportedExtension.ts diff --git a/tests/cases/fourslash/completionImportModuleSpecifierEndingUnsupportedExtension.ts b/tests/cases/fourslash/completionImportModuleSpecifierEndingUnsupportedExtension.ts new file mode 100644 index 0000000000000..1d095a063fe25 --- /dev/null +++ b/tests/cases/fourslash/completionImportModuleSpecifierEndingUnsupportedExtension.ts @@ -0,0 +1,9 @@ +/// +//@Filename:index.css +//// body {} + +//@Filename:module.ts +////import ".//**/" + +verify.completions({ marker: "", excludes:"index.css", preferences: {importModuleSpecifierEnding: "js" }, isNewIdentifierLocation: true}); +verify.completions({ marker: "", excludes:"index", preferences: {importModuleSpecifierEnding: "index" }, isNewIdentifierLocation: true});