Skip to content

Commit 0d5aeee

Browse files
committed
Detect the input file of referenced project with fileNames from parsed command
Fixes #25864 and #26054
1 parent d51b8d9 commit 0d5aeee

File tree

9 files changed

+62
-22
lines changed

9 files changed

+62
-22
lines changed

src/compiler/program.ts

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ namespace ts {
663663

664664
// A parallel array to projectReferences storing the results of reading in the referenced tsconfig files
665665
let resolvedProjectReferences: (ResolvedProjectReference | undefined)[] | undefined = projectReferences ? [] : undefined;
666-
const projectReferenceRedirects: Map<string> = createMap();
666+
let projectReferenceRedirects: ParsedCommandLine[] | undefined;
667667

668668
const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options);
669669
const structuralIsReused = tryReuseStructureFromOldProgram();
@@ -681,7 +681,7 @@ namespace ts {
681681
const dtsOutfile = changeExtension(out, ".d.ts");
682682
processSourceFile(dtsOutfile, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined);
683683
}
684-
addProjectReferenceRedirects(parsedRef.commandLine, projectReferenceRedirects);
684+
addProjectReferenceRedirects(parsedRef.commandLine);
685685
}
686686
}
687687
}
@@ -1252,7 +1252,7 @@ namespace ts {
12521252
if (resolvedProjectReferences) {
12531253
resolvedProjectReferences.forEach(ref => {
12541254
if (ref) {
1255-
addProjectReferenceRedirects(ref.commandLine, projectReferenceRedirects);
1255+
addProjectReferenceRedirects(ref.commandLine);
12561256
}
12571257
});
12581258
}
@@ -2179,20 +2179,24 @@ namespace ts {
21792179
}
21802180

21812181
function getProjectReferenceRedirect(fileName: string): string | undefined {
2182-
const path = toPath(fileName);
2182+
// Ignore dts or any of the non ts files
2183+
if (!projectReferenceRedirects || fileExtensionIs(fileName, Extension.Dts) || !fileExtensionIsOneOf(fileName, supportedTSExtensions)) {
2184+
return undefined;
2185+
}
2186+
21832187
// If this file is produced by a referenced project, we need to rewrite it to
21842188
// look in the output folder of the referenced project rather than the input
2185-
const normalized = getNormalizedAbsolutePath(fileName, path);
2186-
let result: string | undefined;
2187-
projectReferenceRedirects.forEach((v, k) => {
2188-
if (result !== undefined) {
2189+
return forEach(projectReferenceRedirects, referencedProject => {
2190+
// not input file from the referenced project, ignore
2191+
if (!contains(referencedProject.fileNames, fileName, isSameFile)) {
21892192
return undefined;
21902193
}
2191-
if (normalized.indexOf(k) === 0) {
2192-
result = changeExtension(fileName.replace(k, v), ".d.ts");
2193-
}
2194+
2195+
const out = referencedProject.options.outFile || referencedProject.options.out;
2196+
return out ?
2197+
changeExtension(out, Extension.Dts) :
2198+
getOutputDeclarationFileName(fileName, referencedProject);
21942199
});
2195-
return result;
21962200
}
21972201

21982202
function processReferencedFiles(file: SourceFile, isDefaultLib: boolean) {
@@ -2396,15 +2400,8 @@ namespace ts {
23962400
return { commandLine, sourceFile };
23972401
}
23982402

2399-
function addProjectReferenceRedirects(referencedProject: ParsedCommandLine, target: Map<string>) {
2400-
const rootDir = normalizePath(referencedProject.options.rootDir || getDirectoryPath(referencedProject.options.configFilePath!)); // TODO: GH#18217
2401-
target.set(rootDir, getDeclarationOutputDirectory(referencedProject));
2402-
}
2403-
2404-
function getDeclarationOutputDirectory(proj: ParsedCommandLine) {
2405-
return proj.options.declarationDir ||
2406-
proj.options.outDir ||
2407-
getDirectoryPath(proj.options.configFilePath!); // TODO: GH#18217
2403+
function addProjectReferenceRedirects(referencedProject: ParsedCommandLine) {
2404+
(projectReferenceRedirects || (projectReferenceRedirects = [])).push(referencedProject);
24082405
}
24092406

24102407
function verifyCompilerOptions() {

src/compiler/tsbuild.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ namespace ts {
248248
return getOrCreateValueFromConfigFileMap<Map<T>>(configFileMap, resolved, createMap);
249249
}
250250

251-
function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine) {
251+
export function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine) {
252252
const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile.options, configFile.options.configFilePath!), inputFileName, /*ignoreCase*/ true);
253253
const outputPath = resolvePath(configFile.options.declarationDir || configFile.options.outDir || getDirectoryPath(configFile.options.configFilePath!), relativePath);
254254
return changeExtension(outputPath, Extension.Dts);

src/testRunner/unittests/tsbuild.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,25 @@ export class cNew {}`);
357357
]);
358358
});
359359
});
360+
361+
describe("tsbuild - with rootDir of project reference in parentDirectory", () => {
362+
const projFs = loadProjectFromDisk("tests/projects/projectReferenceWithRootDirInParent");
363+
const allExpectedOutputs = [
364+
"/src/dist/other/other.js", "/src/dist/other/other.d.ts",
365+
"/src/dist/main/a.js", "/src/dist/main/a.d.ts",
366+
"/src/dist/main/b.js", "/src/dist/main/b.d.ts"
367+
];
368+
it("verify that it builds correctly", () => {
369+
const fs = projFs.shadow();
370+
const host = new fakes.SolutionBuilderHost(fs);
371+
const builder = createSolutionBuilder(host, ["/src/src/main", "/src/src/other"], {});
372+
builder.buildAllProjects();
373+
host.assertDiagnosticMessages(/*empty*/);
374+
for (const output of allExpectedOutputs) {
375+
assert(fs.existsSync(output), `Expect file ${output} to exist`);
376+
}
377+
});
378+
});
360379
}
361380

362381
export namespace OutFile {
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import { b } from './b';
2+
const a = b;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const b = 0;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"extends": "../../tsconfig.base.json",
3+
"references": [
4+
{ "path": "../other" }
5+
]
6+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const Other = 0;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "../../tsconfig.base.json"
3+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"compilerOptions": {
3+
"composite": true,
4+
"declaration": true,
5+
"rootDir": "./src/",
6+
"outDir": "./dist/"
7+
},
8+
"exclude": [
9+
"node_modules"
10+
]
11+
}

0 commit comments

Comments
 (0)