diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 57207d0564a..dc31dfb5213 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -904,7 +904,7 @@ namespace ts { function computeCommonSourceDirectory(sourceFiles: SourceFile[]): string { let commonPathComponents: string[]; - forEach(files, sourceFile => { + const failed = forEach(files, sourceFile => { // Each file contributes into common source file path if (isDeclarationFile(sourceFile)) { return; @@ -920,10 +920,10 @@ namespace ts { } for (let i = 0, n = Math.min(commonPathComponents.length, sourcePathComponents.length); i < n; i++) { - if (commonPathComponents[i] !== sourcePathComponents[i]) { + if (getCanonicalFileName(commonPathComponents[i]) !== getCanonicalFileName(sourcePathComponents[i])) { if (i === 0) { - programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files)); - return; + // Failed to find any common path component + return true; } // New common path found that is 0 -> i-1 @@ -938,6 +938,11 @@ namespace ts { } }); + // A common path can not be found when paths span multiple drives on windows, for example + if (failed) { + return ""; + } + if (!commonPathComponents) { // Can happen when all input files are .d.ts files return currentDirectory; } @@ -1059,6 +1064,10 @@ namespace ts { else { // Compute the commonSourceDirectory from the input files commonSourceDirectory = computeCommonSourceDirectory(files); + // If we failed to find a good common directory, but outDir is specified and at least one of our files is on a windows drive/URL/other resource, add a failure + if (options.outDir && commonSourceDirectory === "" && forEach(files, file => getRootLength(file.fileName) > 1)) { + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files)); + } } if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== directorySeparator) { diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index 399f8a272dd..425fa888013 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -40,19 +40,18 @@ class CompilerBaselineRunner extends RunnerBase { this.basePath += "/" + this.testSuiteName; } + private makeUnitName(name: string, root: string) { + return ts.isRootedDiskPath(name) ? name : ts.combinePaths(root, name); + }; + public checkTestCodeOutput(fileName: string) { describe("compiler tests for " + fileName, () => { // Mocha holds onto the closure environment of the describe callback even after the test is done. // Everything declared here should be cleared out in the "after" callback. let justName: string; - let content: string; - let testCaseContent: { settings: Harness.TestCaseParser.CompilerSettings; testUnitData: Harness.TestCaseParser.TestUnitData[]; }; - - let units: Harness.TestCaseParser.TestUnitData[]; - let harnessSettings: Harness.TestCaseParser.CompilerSettings; let lastUnit: Harness.TestCaseParser.TestUnitData; - let rootDir: string; + let harnessSettings: Harness.TestCaseParser.CompilerSettings; let result: Harness.Compiler.CompilerResult; let options: ts.CompilerOptions; @@ -63,28 +62,28 @@ class CompilerBaselineRunner extends RunnerBase { before(() => { justName = fileName.replace(/^.*[\\\/]/, ""); // strips the fileName from the path. - content = Harness.IO.readFile(fileName); - testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, fileName); - units = testCaseContent.testUnitData; + const content = Harness.IO.readFile(fileName); + const testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, fileName); + const units = testCaseContent.testUnitData; harnessSettings = testCaseContent.settings; lastUnit = units[units.length - 1]; - rootDir = lastUnit.originalFilePath.indexOf("conformance") === -1 ? "tests/cases/compiler/" : lastUnit.originalFilePath.substring(0, lastUnit.originalFilePath.lastIndexOf("/")) + "/"; + const rootDir = lastUnit.originalFilePath.indexOf("conformance") === -1 ? "tests/cases/compiler/" : lastUnit.originalFilePath.substring(0, lastUnit.originalFilePath.lastIndexOf("/")) + "/"; // We need to assemble the list of input files for the compiler and other related files on the 'filesystem' (ie in a multi-file test) // If the last file in a test uses require or a triple slash reference we'll assume all other files will be brought in via references, // otherwise, assume all files are just meant to be in the same compilation session without explicit references to one another. toBeCompiled = []; otherFiles = []; if (/require\(/.test(lastUnit.content) || /reference\spath/.test(lastUnit.content)) { - toBeCompiled.push({ unitName: ts.combinePaths(rootDir, lastUnit.name), content: lastUnit.content }); + toBeCompiled.push({ unitName: this.makeUnitName(lastUnit.name, rootDir), content: lastUnit.content }); units.forEach(unit => { if (unit.name !== lastUnit.name) { - otherFiles.push({ unitName: ts.combinePaths(rootDir, unit.name), content: unit.content }); + otherFiles.push({ unitName: this.makeUnitName(unit.name, rootDir), content: unit.content }); } }); } else { toBeCompiled = units.map(unit => { - return { unitName: ts.combinePaths(rootDir, unit.name), content: unit.content }; + return { unitName: this.makeUnitName(unit.name, rootDir), content: unit.content }; }); } @@ -99,12 +98,7 @@ class CompilerBaselineRunner extends RunnerBase { // Mocha holds onto the closure environment of the describe callback even after the test is done. // Therefore we have to clean out large objects after the test is done. justName = undefined; - content = undefined; - testCaseContent = undefined; - units = undefined; - harnessSettings = undefined; lastUnit = undefined; - rootDir = undefined; result = undefined; options = undefined; toBeCompiled = undefined; diff --git a/tests/baselines/reference/commonSourceDir1.js b/tests/baselines/reference/commonSourceDir1.js new file mode 100644 index 00000000000..68833aed49d --- /dev/null +++ b/tests/baselines/reference/commonSourceDir1.js @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/commonSourceDir1.ts] //// + +//// [bar.ts] +var x: number; + +//// [baz.ts] +var y: number; + + +//// [bar.js] +var x; +//// [baz.js] +var y; diff --git a/tests/baselines/reference/commonSourceDir1.symbols b/tests/baselines/reference/commonSourceDir1.symbols new file mode 100644 index 00000000000..9248e0c97af --- /dev/null +++ b/tests/baselines/reference/commonSourceDir1.symbols @@ -0,0 +1,8 @@ +=== A:/foo/bar.ts === +var x: number; +>x : Symbol(x, Decl(bar.ts, 0, 3)) + +=== A:/foo/baz.ts === +var y: number; +>y : Symbol(y, Decl(baz.ts, 0, 3)) + diff --git a/tests/baselines/reference/commonSourceDir1.types b/tests/baselines/reference/commonSourceDir1.types new file mode 100644 index 00000000000..6c9864c02cc --- /dev/null +++ b/tests/baselines/reference/commonSourceDir1.types @@ -0,0 +1,8 @@ +=== A:/foo/bar.ts === +var x: number; +>x : number + +=== A:/foo/baz.ts === +var y: number; +>y : number + diff --git a/tests/baselines/reference/commonSourceDir2.errors.txt b/tests/baselines/reference/commonSourceDir2.errors.txt new file mode 100644 index 00000000000..85bcf5d9c72 --- /dev/null +++ b/tests/baselines/reference/commonSourceDir2.errors.txt @@ -0,0 +1,9 @@ +error TS5009: Cannot find the common subdirectory path for the input files. + + +!!! error TS5009: Cannot find the common subdirectory path for the input files. +==== A:/foo/bar.ts (0 errors) ==== + var x: number; + +==== B:/foo/baz.ts (0 errors) ==== + var y: number; \ No newline at end of file diff --git a/tests/baselines/reference/commonSourceDir2.js b/tests/baselines/reference/commonSourceDir2.js new file mode 100644 index 00000000000..cf263b51fb6 --- /dev/null +++ b/tests/baselines/reference/commonSourceDir2.js @@ -0,0 +1,12 @@ +//// [tests/cases/compiler/commonSourceDir2.ts] //// + +//// [bar.ts] +var x: number; + +//// [baz.ts] +var y: number; + +//// [bar.js] +var x; +//// [baz.js] +var y; diff --git a/tests/baselines/reference/commonSourceDir3.js b/tests/baselines/reference/commonSourceDir3.js new file mode 100644 index 00000000000..0535d51f4bf --- /dev/null +++ b/tests/baselines/reference/commonSourceDir3.js @@ -0,0 +1,12 @@ +//// [tests/cases/compiler/commonSourceDir3.ts] //// + +//// [bar.ts] +var x: number; + +//// [baz.ts] +var y: number; + +//// [bar.js] +var x; +//// [baz.js] +var y; diff --git a/tests/baselines/reference/commonSourceDir3.symbols b/tests/baselines/reference/commonSourceDir3.symbols new file mode 100644 index 00000000000..b8783523dfd --- /dev/null +++ b/tests/baselines/reference/commonSourceDir3.symbols @@ -0,0 +1,8 @@ +=== A:/foo/bar.ts === +var x: number; +>x : Symbol(x, Decl(bar.ts, 0, 3)) + +=== a:/foo/baz.ts === +var y: number; +>y : Symbol(y, Decl(baz.ts, 0, 3)) + diff --git a/tests/baselines/reference/commonSourceDir3.types b/tests/baselines/reference/commonSourceDir3.types new file mode 100644 index 00000000000..a0b95275897 --- /dev/null +++ b/tests/baselines/reference/commonSourceDir3.types @@ -0,0 +1,8 @@ +=== A:/foo/bar.ts === +var x: number; +>x : number + +=== a:/foo/baz.ts === +var y: number; +>y : number + diff --git a/tests/baselines/reference/commonSourceDir4.errors.txt b/tests/baselines/reference/commonSourceDir4.errors.txt new file mode 100644 index 00000000000..f3493504e4d --- /dev/null +++ b/tests/baselines/reference/commonSourceDir4.errors.txt @@ -0,0 +1,9 @@ +error TS5009: Cannot find the common subdirectory path for the input files. + + +!!! error TS5009: Cannot find the common subdirectory path for the input files. +==== A:/foo/bar.ts (0 errors) ==== + var x: number; + +==== a:/foo/baz.ts (0 errors) ==== + var y: number; \ No newline at end of file diff --git a/tests/baselines/reference/commonSourceDir4.js b/tests/baselines/reference/commonSourceDir4.js new file mode 100644 index 00000000000..2f2af9f68b2 --- /dev/null +++ b/tests/baselines/reference/commonSourceDir4.js @@ -0,0 +1,12 @@ +//// [tests/cases/compiler/commonSourceDir4.ts] //// + +//// [bar.ts] +var x: number; + +//// [baz.ts] +var y: number; + +//// [bar.js] +var x; +//// [baz.js] +var y; diff --git a/tests/cases/compiler/commonSourceDir1.ts b/tests/cases/compiler/commonSourceDir1.ts new file mode 100644 index 00000000000..1a178ac0226 --- /dev/null +++ b/tests/cases/compiler/commonSourceDir1.ts @@ -0,0 +1,6 @@ +// @outDir: A:/ +// @Filename: A:/foo/bar.ts +var x: number; + +// @Filename: A:/foo/baz.ts +var y: number; diff --git a/tests/cases/compiler/commonSourceDir2.ts b/tests/cases/compiler/commonSourceDir2.ts new file mode 100644 index 00000000000..68dab0727a3 --- /dev/null +++ b/tests/cases/compiler/commonSourceDir2.ts @@ -0,0 +1,6 @@ +// @outDir: A:/ +// @Filename: A:/foo/bar.ts +var x: number; + +// @Filename: B:/foo/baz.ts +var y: number; \ No newline at end of file diff --git a/tests/cases/compiler/commonSourceDir3.ts b/tests/cases/compiler/commonSourceDir3.ts new file mode 100644 index 00000000000..54b6e8c89b7 --- /dev/null +++ b/tests/cases/compiler/commonSourceDir3.ts @@ -0,0 +1,7 @@ +// @useCaseSensitiveFileNames: false +// @outDir: A:/ +// @Filename: A:/foo/bar.ts +var x: number; + +// @Filename: a:/foo/baz.ts +var y: number; \ No newline at end of file diff --git a/tests/cases/compiler/commonSourceDir4.ts b/tests/cases/compiler/commonSourceDir4.ts new file mode 100644 index 00000000000..41ee7a0344a --- /dev/null +++ b/tests/cases/compiler/commonSourceDir4.ts @@ -0,0 +1,7 @@ +// @useCaseSensitiveFileNames: true +// @outDir: A:/ +// @Filename: A:/foo/bar.ts +var x: number; + +// @Filename: a:/foo/baz.ts +var y: number; \ No newline at end of file