mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 20:25:23 -06:00
Use getDirectories and condition node modules resolution on moduleResolution flag
This commit is contained in:
parent
4ca7e95706
commit
9e797b4c78
@ -1171,6 +1171,11 @@ namespace ts {
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string): ResolvedModule[];
|
||||
resolveTypeReferenceDirectives?(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
directoryExists?(directoryName: string): boolean;
|
||||
|
||||
/**
|
||||
* getDirectories is also required for full import and type reference completions. Without it defined, certain
|
||||
* completions will not be provided
|
||||
*/
|
||||
getDirectories?(directoryName: string): string[];
|
||||
}
|
||||
|
||||
@ -4652,7 +4657,7 @@ namespace ts {
|
||||
|
||||
getCompletionEntriesFromTypings(host, options, scriptPath, result);
|
||||
|
||||
forEach(enumeratePotentialNonRelativeModules(fragment, scriptPath), moduleName => {
|
||||
forEach(enumeratePotentialNonRelativeModules(fragment, scriptPath, options), moduleName => {
|
||||
result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName));
|
||||
});
|
||||
|
||||
@ -4704,7 +4709,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function enumeratePotentialNonRelativeModules(fragment: string, scriptPath: string): string[] {
|
||||
function enumeratePotentialNonRelativeModules(fragment: string, scriptPath: string, options: CompilerOptions): string[] {
|
||||
const trailingSeperator = hasTrailingDirectorySeparator(fragment);
|
||||
fragment = normalizePath(fragment);
|
||||
|
||||
@ -4733,19 +4738,21 @@ namespace ts {
|
||||
return moduleName;
|
||||
});
|
||||
|
||||
forEach(enumerateNodeModulesVisibleToScript(host, scriptPath, moduleNameFragment), visibleModule => {
|
||||
if (!isNestedModule) {
|
||||
nonRelativeModules.push(visibleModule.canBeImported ? visibleModule.moduleName : ensureTrailingDirectorySeparator(visibleModule.moduleName));
|
||||
}
|
||||
else {
|
||||
const nestedFiles = host.readDirectory(visibleModule.moduleDir, supportedTypeScriptExtensions, /*exclude*/undefined, /*include*/["./*"]);
|
||||
if (!options.moduleResolution || options.moduleResolution === ModuleResolutionKind.NodeJs) {
|
||||
forEach(enumerateNodeModulesVisibleToScript(host, scriptPath, moduleNameFragment), visibleModule => {
|
||||
if (!isNestedModule) {
|
||||
nonRelativeModules.push(visibleModule.canBeImported ? visibleModule.moduleName : ensureTrailingDirectorySeparator(visibleModule.moduleName));
|
||||
}
|
||||
else {
|
||||
const nestedFiles = host.readDirectory(visibleModule.moduleDir, supportedTypeScriptExtensions, /*exclude*/undefined, /*include*/["./*"]);
|
||||
|
||||
forEach(nestedFiles, (f) => {
|
||||
const nestedModule = removeFileExtension(getBaseFileName(f));
|
||||
nonRelativeModules.push(nestedModule);
|
||||
});
|
||||
}
|
||||
});
|
||||
forEach(nestedFiles, (f) => {
|
||||
const nestedModule = removeFileExtension(getBaseFileName(f));
|
||||
nonRelativeModules.push(nestedModule);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return deduplicate(nonRelativeModules);
|
||||
}
|
||||
@ -4791,16 +4798,18 @@ namespace ts {
|
||||
result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName));
|
||||
});
|
||||
}
|
||||
else if (options.typeRoots) {
|
||||
else if (host.getDirectories && options.typeRoots) {
|
||||
const absoluteRoots = map(options.typeRoots, rootDirectory => getAbsoluteProjectPath(rootDirectory, host, options.project));
|
||||
forEach(absoluteRoots, absoluteRoot => getCompletionEntriesFromDirectory(host, options, absoluteRoot, result));
|
||||
forEach(absoluteRoots, absoluteRoot => getCompletionEntriesFromDirectories(host, options, absoluteRoot, result));
|
||||
}
|
||||
|
||||
// Also get all @types typings installed in visible node_modules directories
|
||||
forEach(findPackageJsons(scriptPath), package => {
|
||||
const typesDir = combinePaths(getDirectoryPath(package), "node_modules/@types");
|
||||
getCompletionEntriesFromDirectory(host, options, typesDir, result);
|
||||
});
|
||||
if (host.getDirectories) {
|
||||
// Also get all @types typings installed in visible node_modules directories
|
||||
forEach(findPackageJsons(scriptPath), package => {
|
||||
const typesDir = combinePaths(getDirectoryPath(package), "node_modules/@types");
|
||||
getCompletionEntriesFromDirectories(host, options, typesDir, result);
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -4817,16 +4826,10 @@ namespace ts {
|
||||
return normalizePath(host.resolvePath(path));
|
||||
}
|
||||
|
||||
function getCompletionEntriesFromDirectory(host: LanguageServiceHost, options: CompilerOptions, directory: string, result: CompletionEntry[]) {
|
||||
if (directoryProbablyExists(directory, host)) {
|
||||
const typeDirectories = host.readDirectory(directory, getSupportedExtensions(options), /*exclude*/undefined, /*include*/["./*/*"]);
|
||||
const seen: {[index: string]: boolean} = {};
|
||||
forEach(typeDirectories, typeFile => {
|
||||
const typeDirectory = getDirectoryPath(typeFile);
|
||||
if (!hasProperty(seen, typeDirectory)) {
|
||||
seen[typeDirectory] = true;
|
||||
result.push(createCompletionEntryForModule(getBaseFileName(typeDirectory), ScriptElementKind.externalModuleName));
|
||||
}
|
||||
function getCompletionEntriesFromDirectories(host: LanguageServiceHost, options: CompilerOptions, directory: string, result: CompletionEntry[]) {
|
||||
if (host.getDirectories && directoryProbablyExists(directory, host)) {
|
||||
forEach(host.getDirectories(directory), typeDirectory => {
|
||||
result.push(createCompletionEntryForModule(getBaseFileName(typeDirectory), ScriptElementKind.externalModuleName));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @moduleResolution: classic
|
||||
|
||||
// @Filename: dir1/dir2/dir3/dir4/test0.ts
|
||||
//// import * as foo1 from "f/*import_as0*/
|
||||
//// import * as foo3 from "fake-module/*import_as1*/
|
||||
|
||||
//// import foo4 = require("f/*import_equals0*/
|
||||
//// import foo6 = require("fake-module/*import_equals1*/
|
||||
|
||||
//// var foo7 = require("f/*require0*/
|
||||
//// var foo9 = require("fake-module/*require1*/
|
||||
|
||||
// @Filename: package.json
|
||||
//// { "dependencies": { "fake-module": "latest" } }
|
||||
// @Filename: node_modules/fake-module/ts.ts
|
||||
//// /*module1*/
|
||||
|
||||
// @Filename: dir1/dir2/dir3/package.json
|
||||
//// { "dependencies": { "fake-module3": "latest" } }
|
||||
// @Filename: dir1/dir2/dir3/node_modules/fake-module3/ts.ts
|
||||
//// /*module3*/
|
||||
|
||||
const kinds = ["import_as", "import_equals", "require"];
|
||||
|
||||
for (const kind of kinds) {
|
||||
goTo.marker(kind + "0");
|
||||
verify.completionListIsEmpty();
|
||||
|
||||
goTo.marker(kind + "1");
|
||||
verify.completionListIsEmpty();
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user