Skip to content

Commit 9f1ed87

Browse files
committed
don't add .ts extensions to imports
1 parent 41f7887 commit 9f1ed87

File tree

3 files changed

+37
-9
lines changed

3 files changed

+37
-9
lines changed

src/services/stringCompletions.ts

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -321,13 +321,14 @@ namespace ts.Completions.StringCompletions {
321321

322322
interface ExtensionOptions {
323323
readonly extensions: readonly Extension[];
324-
readonly includeExtensions: boolean;
324+
readonly includeExtensionsOption: IncludeExtensionsOption;
325325
}
326-
function getExtensionOptions(compilerOptions: CompilerOptions, includeExtensions = false): ExtensionOptions {
327-
return { extensions: getSupportedExtensionsForModuleResolution(compilerOptions), includeExtensions };
326+
function getExtensionOptions(compilerOptions: CompilerOptions, includeExtensionsOption = IncludeExtensionsOption.Exclude): ExtensionOptions {
327+
return { extensions: getSupportedExtensionsForModuleResolution(compilerOptions), includeExtensionsOption };
328328
}
329329
function getCompletionEntriesForRelativeModules(literalValue: string, scriptDirectory: string, compilerOptions: CompilerOptions, host: LanguageServiceHost, scriptPath: Path, preferences: UserPreferences) {
330-
const extensionOptions = getExtensionOptions(compilerOptions, preferences.importModuleSpecifierEnding === "js");
330+
const includeExtensions = preferences.importModuleSpecifierEnding === "js" ? IncludeExtensionsOption.ModuleSpecifierCompletion : IncludeExtensionsOption.Exclude;
331+
const extensionOptions = getExtensionOptions(compilerOptions, includeExtensions);
331332
if (compilerOptions.rootDirs) {
332333
return getCompletionEntriesForDirectoryFragmentWithRootDirs(
333334
compilerOptions.rootDirs, literalValue, scriptDirectory, extensionOptions, compilerOptions, host, scriptPath);
@@ -370,10 +371,15 @@ namespace ts.Completions.StringCompletions {
370371
return flatMap(baseDirectories, baseDirectory => getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensionOptions, host, exclude));
371372
}
372373

374+
enum IncludeExtensionsOption {
375+
Exclude,
376+
Include,
377+
ModuleSpecifierCompletion,
378+
}
373379
/**
374380
* Given a path ending at a directory, gets the completions for the path, and filters for those entries containing the basename.
375381
*/
376-
function getCompletionEntriesForDirectoryFragment(fragment: string, scriptPath: string, { extensions, includeExtensions }: ExtensionOptions, host: LanguageServiceHost, exclude?: string, result: NameAndKind[] = []): NameAndKind[] {
382+
function getCompletionEntriesForDirectoryFragment(fragment: string, scriptPath: string, { extensions, includeExtensionsOption }: ExtensionOptions, host: LanguageServiceHost, exclude?: string, result: NameAndKind[] = []): NameAndKind[] {
377383
if (fragment === undefined) {
378384
fragment = "";
379385
}
@@ -407,7 +413,7 @@ namespace ts.Completions.StringCompletions {
407413
if (files) {
408414
/**
409415
* Multiple file entries might map to the same truncated name once we remove extensions
410-
* (happens iff includeExtensions === false)so we use a set-like data structure. Eg:
416+
* (happens iff includeExtensionsOption === includeExtensionsOption.Exclude) so we use a set-like data structure. Eg:
411417
*
412418
* both foo.ts and foo.tsx become foo
413419
*/
@@ -418,8 +424,19 @@ namespace ts.Completions.StringCompletions {
418424
continue;
419425
}
420426

421-
const foundFileName = includeExtensions || fileExtensionIs(filePath, Extension.Json) ? getBaseFileName(filePath) : removeFileExtension(getBaseFileName(filePath));
422-
foundFiles.set(foundFileName, tryGetExtensionFromPath(filePath));
427+
let foundFileName: string;
428+
if (includeExtensionsOption === IncludeExtensionsOption.Exclude && !fileExtensionIs(filePath, Extension.Json)) {
429+
foundFileName = removeFileExtension(getBaseFileName(filePath));
430+
foundFiles.set(foundFileName, tryGetExtensionFromPath(filePath));
431+
}
432+
else if (includeExtensionsOption === IncludeExtensionsOption.ModuleSpecifierCompletion && fileExtensionIs(filePath, Extension.Ts)) {
433+
foundFileName = changeExtension(getBaseFileName(filePath), Extension.Js);
434+
foundFiles.set(foundFileName, Extension.Js);
435+
}
436+
else {
437+
foundFileName = getBaseFileName(filePath);
438+
foundFiles.set(foundFileName, tryGetExtensionFromPath(filePath));
439+
}
423440
}
424441

425442
foundFiles.forEach((ext, foundFile) => {
@@ -635,7 +652,7 @@ namespace ts.Completions.StringCompletions {
635652

636653
const [, prefix, kind, toComplete] = match;
637654
const scriptPath = getDirectoryPath(sourceFile.path);
638-
const names = kind === "path" ? getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getExtensionOptions(compilerOptions, /*includeExtensions*/ true), host, sourceFile.path)
655+
const names = kind === "path" ? getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getExtensionOptions(compilerOptions, IncludeExtensionsOption.Include), host, sourceFile.path)
639656
: kind === "types" ? getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, getFragmentDirectory(toComplete), getExtensionOptions(compilerOptions))
640657
: Debug.fail();
641658
return addReplacementSpans(toComplete, range.pos + prefix.length, names);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/// <reference path='fourslash.ts'/>
2+
//@Filename:test.ts
3+
////export function f(){
4+
//// return 1
5+
////}
6+
7+
//@Filename:module.ts
8+
////import { f } from ".//**/"
9+
10+
11+
verify.completions({ marker: "", includes:{name:"test.js"}, preferences: {importModuleSpecifierEnding: "js" }, isNewIdentifierLocation: true})

0 commit comments

Comments
 (0)