Resolve module specifier relative to moduleFile.originalFileName (#32722)

* Resolve module specifier relative to moduleFile.originalFileName

* Use baseline testing for outputs

* Added skipLibCheck to test

* Switch to using vfs.formatPatch for output
This commit is contained in:
Ron Buckton
2019-08-06 13:48:58 -07:00
committed by GitHub
parent 024193fd43
commit d75740280f
6 changed files with 472 additions and 4 deletions

View File

@@ -93,7 +93,7 @@ namespace ts.moduleSpecifiers {
const info = getInfo(importingSourceFile.path, host);
const moduleSourceFile = getSourceFileOfNode(moduleSymbol.valueDeclaration || getNonAugmentationDeclaration(moduleSymbol));
const modulePaths = getAllModulePaths(files, importingSourceFile.path, moduleSourceFile.fileName, info.getCanonicalFileName, host, redirectTargetsMap);
const modulePaths = getAllModulePaths(files, importingSourceFile.path, moduleSourceFile.originalFileName, info.getCanonicalFileName, host, redirectTargetsMap);
const preferences = getPreferences(userPreferences, compilerOptions, importingSourceFile);
const global = mapDefined(modulePaths, moduleFileName => tryGetModuleNameAsNodeModule(moduleFileName, info, host, compilerOptions));

View File

@@ -1525,8 +1525,11 @@ namespace vfs {
return typeof value === "string" || Buffer.isBuffer(value) ? new File(value) : new Directory(value);
}
export function formatPatch(patch: FileSet) {
return formatPatchWorker("", patch);
export function formatPatch(patch: FileSet): string;
export function formatPatch(patch: FileSet | undefined): string | null;
export function formatPatch(patch: FileSet | undefined) {
// tslint:disable-next-line:no-null-keyword
return patch ? formatPatchWorker("", patch) : null;
}
function formatPatchWorker(dirname: string, container: FileSet): string {
@@ -1559,5 +1562,24 @@ namespace vfs {
}
return text;
}
export function iteratePatch(patch: FileSet | undefined): IterableIterator<[string, string]> | null {
// tslint:disable-next-line:no-null-keyword
return patch ? Harness.Compiler.iterateOutputs(iteratePatchWorker("", patch)) : null;
}
function* iteratePatchWorker(dirname: string, container: FileSet): IterableIterator<documents.TextDocument> {
for (const name of Object.keys(container)) {
const entry = normalizeFileSetEntry(container[name]);
const file = dirname ? vpath.combine(dirname, name) : name;
if (entry instanceof Directory) {
yield* ts.arrayFrom(iteratePatchWorker(file, entry.files));
}
else if (entry instanceof File) {
const content = typeof entry.data === "string" ? entry.data : entry.data.toString("utf8");
yield new documents.TextDocument(file, content);
}
}
}
}
// tslint:enable:no-null-keyword

View File

@@ -98,6 +98,7 @@
"unittests/tsbuild/inferredTypeFromTransitiveModule.ts",
"unittests/tsbuild/lateBoundSymbol.ts",
"unittests/tsbuild/missingExtendedFile.ts",
"unittests/tsbuild/moduleSpecifiers.ts",
"unittests/tsbuild/outFile.ts",
"unittests/tsbuild/referencesWithRootDirInParent.ts",
"unittests/tsbuild/resolveJsonModule.ts",

View File

@@ -348,5 +348,4 @@ namespace ts {
});
});
});
}

View File

@@ -0,0 +1,98 @@
namespace ts {
// https://github.com/microsoft/TypeScript/issues/31696
it("unittests:: tsbuild:: moduleSpecifiers:: synthesized module specifiers to referenced projects resolve correctly", () => {
const baseFs = vfs.createFromFileSystem(Harness.IO, /*ignoreCase*/ false, {
files: {
"/src/common/nominal.ts": utils.dedent`
export declare type Nominal<T, Name extends string> = T & {
[Symbol.species]: Name;
};
`,
"/src/common/tsconfig.json": utils.dedent`
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"composite": true
},
"include": ["nominal.ts"]
}`,
"/src/sub-project/index.ts": utils.dedent`
import { Nominal } from '../common/nominal';
export type MyNominal = Nominal<string, 'MyNominal'>;
`,
"/src/sub-project/tsconfig.json": utils.dedent`
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"composite": true
},
"references": [
{ "path": "../common" }
],
"include": ["./index.ts"]
}`,
"/src/sub-project-2/index.ts": utils.dedent`
import { MyNominal } from '../sub-project/index';
const variable = {
key: 'value' as MyNominal,
};
export function getVar(): keyof typeof variable {
return 'key';
}
`,
"/src/sub-project-2/tsconfig.json": utils.dedent`
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"composite": true
},
"references": [
{ "path": "../sub-project" }
],
"include": ["./index.ts"]
}`,
"/src/tsconfig.json": utils.dedent`
{
"compilerOptions": {
"composite": true
},
"references": [
{ "path": "./sub-project" },
{ "path": "./sub-project-2" }
],
"include": []
}`,
"/tsconfig.base.json": utils.dedent`
{
"compilerOptions": {
"skipLibCheck": true,
"rootDir": "./",
"outDir": "lib",
"lib": ["dom", "es2015", "es2015.symbol.wellknown"]
}
}`,
"/tsconfig.json": utils.dedent`{
"compilerOptions": {
"composite": true
},
"references": [
{ "path": "./src" }
],
"include": []
}`
},
cwd: "/"
});
const fs = baseFs.makeReadonly().shadow();
const sys = new fakes.System(fs, { executingFilePath: "/", newLine: "\n" });
const host = new fakes.SolutionBuilderHost(sys);
const builder = createSolutionBuilder(host, ["/tsconfig.json"], { dry: false, force: false, verbose: false });
builder.build();
// Prior to fixing GH31696 the import in `/lib/src/sub-project-2/index.d.ts` was `import("../../lib/src/common/nonterminal")`, which was invalid.
Harness.Baseline.runBaseline("tsbuild/moduleSpecifiers/initial-build/resolves-correctly.js", vfs.formatPatch(fs.diff(baseFs)));
});
}