From 0d5aeeef2267606245ce833734c7a0371ff93832 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 18 Sep 2018 11:44:16 -0700 Subject: [PATCH] Detect the input file of referenced project with fileNames from parsed command Fixes #25864 and #26054 --- src/compiler/program.ts | 39 +++++++++---------- src/compiler/tsbuild.ts | 2 +- src/testRunner/unittests/tsbuild.ts | 19 +++++++++ .../src/main/a.ts | 2 + .../src/main/b.ts | 1 + .../src/main/tsconfig.json | 6 +++ .../src/other/other.ts | 1 + .../src/other/tsconfig.json | 3 ++ .../tsconfig.base.json | 11 ++++++ 9 files changed, 62 insertions(+), 22 deletions(-) create mode 100644 tests/projects/projectReferenceWithRootDirInParent/src/main/a.ts create mode 100644 tests/projects/projectReferenceWithRootDirInParent/src/main/b.ts create mode 100644 tests/projects/projectReferenceWithRootDirInParent/src/main/tsconfig.json create mode 100644 tests/projects/projectReferenceWithRootDirInParent/src/other/other.ts create mode 100644 tests/projects/projectReferenceWithRootDirInParent/src/other/tsconfig.json create mode 100644 tests/projects/projectReferenceWithRootDirInParent/tsconfig.base.json diff --git a/src/compiler/program.ts b/src/compiler/program.ts index f1a93834cde..d0605bd55d9 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -663,7 +663,7 @@ namespace ts { // A parallel array to projectReferences storing the results of reading in the referenced tsconfig files let resolvedProjectReferences: (ResolvedProjectReference | undefined)[] | undefined = projectReferences ? [] : undefined; - const projectReferenceRedirects: Map = createMap(); + let projectReferenceRedirects: ParsedCommandLine[] | undefined; const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options); const structuralIsReused = tryReuseStructureFromOldProgram(); @@ -681,7 +681,7 @@ namespace ts { const dtsOutfile = changeExtension(out, ".d.ts"); processSourceFile(dtsOutfile, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined); } - addProjectReferenceRedirects(parsedRef.commandLine, projectReferenceRedirects); + addProjectReferenceRedirects(parsedRef.commandLine); } } } @@ -1252,7 +1252,7 @@ namespace ts { if (resolvedProjectReferences) { resolvedProjectReferences.forEach(ref => { if (ref) { - addProjectReferenceRedirects(ref.commandLine, projectReferenceRedirects); + addProjectReferenceRedirects(ref.commandLine); } }); } @@ -2179,20 +2179,24 @@ namespace ts { } function getProjectReferenceRedirect(fileName: string): string | undefined { - const path = toPath(fileName); + // Ignore dts or any of the non ts files + if (!projectReferenceRedirects || fileExtensionIs(fileName, Extension.Dts) || !fileExtensionIsOneOf(fileName, supportedTSExtensions)) { + return undefined; + } + // If this file is produced by a referenced project, we need to rewrite it to // look in the output folder of the referenced project rather than the input - const normalized = getNormalizedAbsolutePath(fileName, path); - let result: string | undefined; - projectReferenceRedirects.forEach((v, k) => { - if (result !== undefined) { + return forEach(projectReferenceRedirects, referencedProject => { + // not input file from the referenced project, ignore + if (!contains(referencedProject.fileNames, fileName, isSameFile)) { return undefined; } - if (normalized.indexOf(k) === 0) { - result = changeExtension(fileName.replace(k, v), ".d.ts"); - } + + const out = referencedProject.options.outFile || referencedProject.options.out; + return out ? + changeExtension(out, Extension.Dts) : + getOutputDeclarationFileName(fileName, referencedProject); }); - return result; } function processReferencedFiles(file: SourceFile, isDefaultLib: boolean) { @@ -2396,15 +2400,8 @@ namespace ts { return { commandLine, sourceFile }; } - function addProjectReferenceRedirects(referencedProject: ParsedCommandLine, target: Map) { - const rootDir = normalizePath(referencedProject.options.rootDir || getDirectoryPath(referencedProject.options.configFilePath!)); // TODO: GH#18217 - target.set(rootDir, getDeclarationOutputDirectory(referencedProject)); - } - - function getDeclarationOutputDirectory(proj: ParsedCommandLine) { - return proj.options.declarationDir || - proj.options.outDir || - getDirectoryPath(proj.options.configFilePath!); // TODO: GH#18217 + function addProjectReferenceRedirects(referencedProject: ParsedCommandLine) { + (projectReferenceRedirects || (projectReferenceRedirects = [])).push(referencedProject); } function verifyCompilerOptions() { diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index 6c3681dbd5c..60733dbdc8c 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -248,7 +248,7 @@ namespace ts { return getOrCreateValueFromConfigFileMap>(configFileMap, resolved, createMap); } - function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine) { + export function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine) { const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile.options, configFile.options.configFilePath!), inputFileName, /*ignoreCase*/ true); const outputPath = resolvePath(configFile.options.declarationDir || configFile.options.outDir || getDirectoryPath(configFile.options.configFilePath!), relativePath); return changeExtension(outputPath, Extension.Dts); diff --git a/src/testRunner/unittests/tsbuild.ts b/src/testRunner/unittests/tsbuild.ts index 4643c2256bd..36feb68a223 100644 --- a/src/testRunner/unittests/tsbuild.ts +++ b/src/testRunner/unittests/tsbuild.ts @@ -357,6 +357,25 @@ export class cNew {}`); ]); }); }); + + describe("tsbuild - with rootDir of project reference in parentDirectory", () => { + const projFs = loadProjectFromDisk("tests/projects/projectReferenceWithRootDirInParent"); + const allExpectedOutputs = [ + "/src/dist/other/other.js", "/src/dist/other/other.d.ts", + "/src/dist/main/a.js", "/src/dist/main/a.d.ts", + "/src/dist/main/b.js", "/src/dist/main/b.d.ts" + ]; + it("verify that it builds correctly", () => { + const fs = projFs.shadow(); + const host = new fakes.SolutionBuilderHost(fs); + const builder = createSolutionBuilder(host, ["/src/src/main", "/src/src/other"], {}); + builder.buildAllProjects(); + host.assertDiagnosticMessages(/*empty*/); + for (const output of allExpectedOutputs) { + assert(fs.existsSync(output), `Expect file ${output} to exist`); + } + }); + }); } export namespace OutFile { diff --git a/tests/projects/projectReferenceWithRootDirInParent/src/main/a.ts b/tests/projects/projectReferenceWithRootDirInParent/src/main/a.ts new file mode 100644 index 00000000000..bacd116a1bb --- /dev/null +++ b/tests/projects/projectReferenceWithRootDirInParent/src/main/a.ts @@ -0,0 +1,2 @@ +import { b } from './b'; +const a = b; \ No newline at end of file diff --git a/tests/projects/projectReferenceWithRootDirInParent/src/main/b.ts b/tests/projects/projectReferenceWithRootDirInParent/src/main/b.ts new file mode 100644 index 00000000000..8ff56d7eca4 --- /dev/null +++ b/tests/projects/projectReferenceWithRootDirInParent/src/main/b.ts @@ -0,0 +1 @@ +export const b = 0; diff --git a/tests/projects/projectReferenceWithRootDirInParent/src/main/tsconfig.json b/tests/projects/projectReferenceWithRootDirInParent/src/main/tsconfig.json new file mode 100644 index 00000000000..deb6cd7b9ba --- /dev/null +++ b/tests/projects/projectReferenceWithRootDirInParent/src/main/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../../tsconfig.base.json", + "references": [ + { "path": "../other" } + ] +} \ No newline at end of file diff --git a/tests/projects/projectReferenceWithRootDirInParent/src/other/other.ts b/tests/projects/projectReferenceWithRootDirInParent/src/other/other.ts new file mode 100644 index 00000000000..002e06d5821 --- /dev/null +++ b/tests/projects/projectReferenceWithRootDirInParent/src/other/other.ts @@ -0,0 +1 @@ +export const Other = 0; diff --git a/tests/projects/projectReferenceWithRootDirInParent/src/other/tsconfig.json b/tests/projects/projectReferenceWithRootDirInParent/src/other/tsconfig.json new file mode 100644 index 00000000000..fdf102617fa --- /dev/null +++ b/tests/projects/projectReferenceWithRootDirInParent/src/other/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../../tsconfig.base.json" +} \ No newline at end of file diff --git a/tests/projects/projectReferenceWithRootDirInParent/tsconfig.base.json b/tests/projects/projectReferenceWithRootDirInParent/tsconfig.base.json new file mode 100644 index 00000000000..966eb3f3b8e --- /dev/null +++ b/tests/projects/projectReferenceWithRootDirInParent/tsconfig.base.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "composite": true, + "declaration": true, + "rootDir": "./src/", + "outDir": "./dist/" + }, + "exclude": [ + "node_modules" + ] +} \ No newline at end of file