mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 21:36:50 -05:00
Merge branch 'master' into fixFindReferencesOnExports
This commit is contained in:
@@ -26,15 +26,36 @@ module ts {
|
||||
content?: string
|
||||
}
|
||||
|
||||
function createModuleResolutionHost(...files: File[]): ModuleResolutionHost {
|
||||
function createModuleResolutionHost(hasDirectoryExists: boolean, ...files: File[]): ModuleResolutionHost {
|
||||
let map = arrayToMap(files, f => f.name);
|
||||
|
||||
return { fileExists, readFile };
|
||||
|
||||
function fileExists(path: string): boolean {
|
||||
return hasProperty(map, path);
|
||||
if (hasDirectoryExists) {
|
||||
const directories: Map<string> = {};
|
||||
for (const f of files) {
|
||||
let name = getDirectoryPath(f.name);
|
||||
while (true) {
|
||||
directories[name] = name;
|
||||
let baseName = getDirectoryPath(name);
|
||||
if (baseName === name) {
|
||||
break;
|
||||
}
|
||||
name = baseName;
|
||||
}
|
||||
}
|
||||
return {
|
||||
readFile,
|
||||
directoryExists: path => {
|
||||
return hasProperty(directories, path);
|
||||
},
|
||||
fileExists: path => {
|
||||
assert.isTrue(hasProperty(directories, getDirectoryPath(path)), "'fileExists' request in non-existing directory");
|
||||
return hasProperty(map, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return { readFile, fileExists: path => hasProperty(map, path), };
|
||||
}
|
||||
|
||||
function readFile(path: string): string {
|
||||
return hasProperty(map, path) ? map[path].content : undefined;
|
||||
}
|
||||
@@ -51,9 +72,14 @@ module ts {
|
||||
|
||||
function testLoadAsFile(containingFileName: string, moduleFileNameNoExt: string, moduleName: string): void {
|
||||
for (let ext of supportedTypeScriptExtensions) {
|
||||
test(ext, /*hasDirectoryExists*/ false);
|
||||
test(ext, /*hasDirectoryExists*/ true);
|
||||
}
|
||||
|
||||
function test(ext: string, hasDirectoryExists: boolean) {
|
||||
let containingFile = { name: containingFileName }
|
||||
let moduleFile = { name: moduleFileNameNoExt + ext }
|
||||
let resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(containingFile, moduleFile));
|
||||
let resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
|
||||
|
||||
@@ -69,6 +95,7 @@ module ts {
|
||||
}
|
||||
|
||||
assert.deepEqual(resolution.failedLookupLocations, failedLookupLocations);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,14 +116,19 @@ module ts {
|
||||
});
|
||||
|
||||
function testLoadingFromPackageJson(containingFileName: string, packageJsonFileName: string, fieldRef: string, moduleFileName: string, moduleName: string): void {
|
||||
let containingFile = { name: containingFileName };
|
||||
let packageJson = { name: packageJsonFileName, content: JSON.stringify({ "typings": fieldRef }) };
|
||||
let moduleFile = { name: moduleFileName };
|
||||
let resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(containingFile, packageJson, moduleFile));
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
|
||||
// expect three failed lookup location - attempt to load module as file with all supported extensions
|
||||
assert.equal(resolution.failedLookupLocations.length, supportedTypeScriptExtensions.length);
|
||||
test(/*hasDirectoryExists*/ false);
|
||||
test(/*hasDirectoryExists*/ true);
|
||||
|
||||
function test(hasDirectoryExists: boolean) {
|
||||
let containingFile = { name: containingFileName };
|
||||
let packageJson = { name: packageJsonFileName, content: JSON.stringify({ "typings": fieldRef }) };
|
||||
let moduleFile = { name: moduleFileName };
|
||||
let resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile));
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
|
||||
// expect three failed lookup location - attempt to load module as file with all supported extensions
|
||||
assert.equal(resolution.failedLookupLocations.length, supportedTypeScriptExtensions.length);
|
||||
}
|
||||
}
|
||||
|
||||
it("module name as directory - load from 'typings'", () => {
|
||||
@@ -107,16 +139,21 @@ module ts {
|
||||
});
|
||||
|
||||
function testTypingsIgnored(typings: any): void {
|
||||
let containingFile = { name: "/a/b.ts" };
|
||||
let packageJson = { name: "/node_modules/b/package.json", content: JSON.stringify({ "typings": typings }) };
|
||||
let moduleFile = { name: "/a/b.d.ts" };
|
||||
test(/*hasDirectoryExists*/ false);
|
||||
test(/*hasDirectoryExists*/ true);
|
||||
|
||||
let indexPath = "/node_modules/b/index.d.ts";
|
||||
let indexFile = { name: indexPath }
|
||||
function test(hasDirectoryExists: boolean) {
|
||||
let containingFile = { name: "/a/b.ts" };
|
||||
let packageJson = { name: "/node_modules/b/package.json", content: JSON.stringify({ "typings": typings }) };
|
||||
let moduleFile = { name: "/a/b.d.ts" };
|
||||
|
||||
let resolution = nodeModuleNameResolver("b", containingFile.name, {}, createModuleResolutionHost(containingFile, packageJson, moduleFile, indexFile));
|
||||
let indexPath = "/node_modules/b/index.d.ts";
|
||||
let indexFile = { name: indexPath }
|
||||
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, indexPath);
|
||||
let resolution = nodeModuleNameResolver("b", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile, indexFile));
|
||||
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, indexPath);
|
||||
}
|
||||
}
|
||||
|
||||
it("module name as directory - handle invalid 'typings'", () => {
|
||||
@@ -128,89 +165,110 @@ module ts {
|
||||
});
|
||||
|
||||
it("module name as directory - load index.d.ts", () => {
|
||||
let containingFile = { name: "/a/b/c.ts" };
|
||||
let packageJson = { name: "/a/b/foo/package.json", content: JSON.stringify({ main: "/c/d" }) };
|
||||
let indexFile = { name: "/a/b/foo/index.d.ts" };
|
||||
let resolution = nodeModuleNameResolver("./foo", containingFile.name, {}, createModuleResolutionHost(containingFile, packageJson, indexFile));
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, indexFile.name);
|
||||
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
|
||||
assert.deepEqual(resolution.failedLookupLocations, [
|
||||
"/a/b/foo.ts",
|
||||
"/a/b/foo.tsx",
|
||||
"/a/b/foo.d.ts",
|
||||
"/a/b/foo/index.ts",
|
||||
"/a/b/foo/index.tsx",
|
||||
]);
|
||||
test(/*hasDirectoryExists*/ false);
|
||||
test(/*hasDirectoryExists*/ true);
|
||||
|
||||
function test(hasDirectoryExists: boolean) {
|
||||
let containingFile = { name: "/a/b/c.ts" };
|
||||
let packageJson = { name: "/a/b/foo/package.json", content: JSON.stringify({ main: "/c/d" }) };
|
||||
let indexFile = { name: "/a/b/foo/index.d.ts" };
|
||||
let resolution = nodeModuleNameResolver("./foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, indexFile));
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, indexFile.name);
|
||||
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
|
||||
assert.deepEqual(resolution.failedLookupLocations, [
|
||||
"/a/b/foo.ts",
|
||||
"/a/b/foo.tsx",
|
||||
"/a/b/foo.d.ts",
|
||||
"/a/b/foo/index.ts",
|
||||
"/a/b/foo/index.tsx",
|
||||
]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("Node module resolution - non-relative paths", () => {
|
||||
it("load module as file - ts files not loaded", () => {
|
||||
let containingFile = { name: "/a/b/c/d/e.ts" };
|
||||
let moduleFile = { name: "/a/b/node_modules/foo.ts" };
|
||||
let resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(containingFile, moduleFile));
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.deepEqual(resolution.failedLookupLocations, [
|
||||
"/a/b/c/d/node_modules/foo.ts",
|
||||
"/a/b/c/d/node_modules/foo.tsx",
|
||||
"/a/b/c/d/node_modules/foo.d.ts",
|
||||
"/a/b/c/d/node_modules/foo/package.json",
|
||||
"/a/b/c/d/node_modules/foo/index.ts",
|
||||
"/a/b/c/d/node_modules/foo/index.tsx",
|
||||
"/a/b/c/d/node_modules/foo/index.d.ts",
|
||||
"/a/b/c/node_modules/foo.ts",
|
||||
"/a/b/c/node_modules/foo.tsx",
|
||||
"/a/b/c/node_modules/foo.d.ts",
|
||||
"/a/b/c/node_modules/foo/package.json",
|
||||
"/a/b/c/node_modules/foo/index.ts",
|
||||
"/a/b/c/node_modules/foo/index.tsx",
|
||||
"/a/b/c/node_modules/foo/index.d.ts",
|
||||
])
|
||||
test(/*hasDirectoryExists*/ false);
|
||||
test(/*hasDirectoryExists*/ true);
|
||||
|
||||
function test(hasDirectoryExists: boolean) {
|
||||
let containingFile = { name: "/a/b/c/d/e.ts" };
|
||||
let moduleFile = { name: "/a/b/node_modules/foo.ts" };
|
||||
let resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.deepEqual(resolution.failedLookupLocations, [
|
||||
"/a/b/c/d/node_modules/foo.ts",
|
||||
"/a/b/c/d/node_modules/foo.tsx",
|
||||
"/a/b/c/d/node_modules/foo.d.ts",
|
||||
"/a/b/c/d/node_modules/foo/package.json",
|
||||
"/a/b/c/d/node_modules/foo/index.ts",
|
||||
"/a/b/c/d/node_modules/foo/index.tsx",
|
||||
"/a/b/c/d/node_modules/foo/index.d.ts",
|
||||
"/a/b/c/node_modules/foo.ts",
|
||||
"/a/b/c/node_modules/foo.tsx",
|
||||
"/a/b/c/node_modules/foo.d.ts",
|
||||
"/a/b/c/node_modules/foo/package.json",
|
||||
"/a/b/c/node_modules/foo/index.ts",
|
||||
"/a/b/c/node_modules/foo/index.tsx",
|
||||
"/a/b/c/node_modules/foo/index.d.ts",
|
||||
])
|
||||
}
|
||||
});
|
||||
|
||||
it("load module as file", () => {
|
||||
let containingFile = { name: "/a/b/c/d/e.ts" };
|
||||
let moduleFile = { name: "/a/b/node_modules/foo.d.ts" };
|
||||
let resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(containingFile, moduleFile));
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.equal(resolution.resolvedModule.isExternalLibraryImport, true);
|
||||
test(/*hasDirectoryExists*/ false);
|
||||
test(/*hasDirectoryExists*/ true);
|
||||
|
||||
function test(hasDirectoryExists: boolean) {
|
||||
let containingFile = { name: "/a/b/c/d/e.ts" };
|
||||
let moduleFile = { name: "/a/b/node_modules/foo.d.ts" };
|
||||
let resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.equal(resolution.resolvedModule.isExternalLibraryImport, true);
|
||||
}
|
||||
});
|
||||
|
||||
it("load module as directory", () => {
|
||||
let containingFile = { name: "/a/node_modules/b/c/node_modules/d/e.ts" };
|
||||
let moduleFile = { name: "/a/node_modules/foo/index.d.ts" };
|
||||
let resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(containingFile, moduleFile));
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.equal(resolution.resolvedModule.isExternalLibraryImport, true);
|
||||
assert.deepEqual(resolution.failedLookupLocations, [
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo.tsx",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/package.json",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.tsx",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/foo.ts",
|
||||
"/a/node_modules/b/c/node_modules/foo.tsx",
|
||||
"/a/node_modules/b/c/node_modules/foo.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/foo/package.json",
|
||||
"/a/node_modules/b/c/node_modules/foo/index.ts",
|
||||
"/a/node_modules/b/c/node_modules/foo/index.tsx",
|
||||
"/a/node_modules/b/c/node_modules/foo/index.d.ts",
|
||||
"/a/node_modules/b/node_modules/foo.ts",
|
||||
"/a/node_modules/b/node_modules/foo.tsx",
|
||||
"/a/node_modules/b/node_modules/foo.d.ts",
|
||||
"/a/node_modules/b/node_modules/foo/package.json",
|
||||
"/a/node_modules/b/node_modules/foo/index.ts",
|
||||
"/a/node_modules/b/node_modules/foo/index.tsx",
|
||||
"/a/node_modules/b/node_modules/foo/index.d.ts",
|
||||
"/a/node_modules/foo.ts",
|
||||
"/a/node_modules/foo.tsx",
|
||||
"/a/node_modules/foo.d.ts",
|
||||
"/a/node_modules/foo/package.json",
|
||||
"/a/node_modules/foo/index.ts",
|
||||
"/a/node_modules/foo/index.tsx"
|
||||
]);
|
||||
test(/*hasDirectoryExists*/ false);
|
||||
test(/*hasDirectoryExists*/ true);
|
||||
|
||||
function test(hasDirectoryExists: boolean) {
|
||||
let containingFile = { name: "/a/node_modules/b/c/node_modules/d/e.ts" };
|
||||
let moduleFile = { name: "/a/node_modules/foo/index.d.ts" };
|
||||
let resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.equal(resolution.resolvedModule.isExternalLibraryImport, true);
|
||||
assert.deepEqual(resolution.failedLookupLocations, [
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo.tsx",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/package.json",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.tsx",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/foo.ts",
|
||||
"/a/node_modules/b/c/node_modules/foo.tsx",
|
||||
"/a/node_modules/b/c/node_modules/foo.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/foo/package.json",
|
||||
"/a/node_modules/b/c/node_modules/foo/index.ts",
|
||||
"/a/node_modules/b/c/node_modules/foo/index.tsx",
|
||||
"/a/node_modules/b/c/node_modules/foo/index.d.ts",
|
||||
"/a/node_modules/b/node_modules/foo.ts",
|
||||
"/a/node_modules/b/node_modules/foo.tsx",
|
||||
"/a/node_modules/b/node_modules/foo.d.ts",
|
||||
"/a/node_modules/b/node_modules/foo/package.json",
|
||||
"/a/node_modules/b/node_modules/foo/index.ts",
|
||||
"/a/node_modules/b/node_modules/foo/index.tsx",
|
||||
"/a/node_modules/b/node_modules/foo/index.d.ts",
|
||||
"/a/node_modules/foo.ts",
|
||||
"/a/node_modules/foo.tsx",
|
||||
"/a/node_modules/foo.d.ts",
|
||||
"/a/node_modules/foo/package.json",
|
||||
"/a/node_modules/foo/index.ts",
|
||||
"/a/node_modules/foo/index.tsx"
|
||||
]);
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -400,4 +458,21 @@ import b = require("./moduleB.ts");
|
||||
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /* useCaseSensitiveFileNames */ false, ["moduleD.ts"], []);
|
||||
})
|
||||
});
|
||||
|
||||
function notImplemented(name: string): () => any {
|
||||
return () => assert(`${name} is not implemented and should not be called`);
|
||||
}
|
||||
|
||||
describe("ModuleResolutionHost.directoryExists", () => {
|
||||
it("No 'fileExists' calls if containing directory is missing", () => {
|
||||
const host: ModuleResolutionHost = {
|
||||
readFile: notImplemented("readFile"),
|
||||
fileExists: notImplemented("fileExists"),
|
||||
directoryExists: _ => false
|
||||
};
|
||||
|
||||
const result = resolveModuleName("someName", "/a/b/c/d", { moduleResolution: ModuleResolutionKind.NodeJs }, host);
|
||||
assert(!result.resolvedModule);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user