Skip to content

Commit 414589f

Browse files
author
Andy Hanson
committed
Leave files from node_modules out when calculating getCommonSourceDirectory
1 parent 6b94bae commit 414589f

File tree

8 files changed

+102
-32
lines changed

8 files changed

+102
-32
lines changed

src/compiler/program.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -430,13 +430,14 @@ namespace ts {
430430
return program;
431431

432432
function getCommonSourceDirectory() {
433-
if (typeof commonSourceDirectory === "undefined") {
434-
if (options.rootDir && checkSourceFilesBelongToPath(files, options.rootDir)) {
433+
if (commonSourceDirectory === undefined) {
434+
const emittedFiles = filterSourceFilesInDirectory(files, isSourceFileFromExternalLibrary);
435+
if (options.rootDir && checkSourceFilesBelongToPath(emittedFiles, options.rootDir)) {
435436
// If a rootDir is specified and is valid use it as the commonSourceDirectory
436437
commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, currentDirectory);
437438
}
438439
else {
439-
commonSourceDirectory = computeCommonSourceDirectory(files);
440+
commonSourceDirectory = computeCommonSourceDirectory(emittedFiles);
440441
}
441442
if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== directorySeparator) {
442443
// Make sure directory path ends with directory separator so this string can directly
@@ -448,6 +449,10 @@ namespace ts {
448449
return commonSourceDirectory;
449450
}
450451

452+
function isSourceFileFromExternalLibrary(file: SourceFile): boolean {
453+
return !!sourceFilesFoundSearchingNodeModules[file.path];
454+
}
455+
451456
function getClassifiableNames() {
452457
if (!classifiableNames) {
453458
// Initialize a checker so that all our files are bound.
@@ -592,7 +597,7 @@ namespace ts {
592597
getSourceFile: program.getSourceFile,
593598
getSourceFileByPath: program.getSourceFileByPath,
594599
getSourceFiles: program.getSourceFiles,
595-
isSourceFileFromExternalLibrary: (file: SourceFile) => !!sourceFilesFoundSearchingNodeModules[file.path],
600+
isSourceFileFromExternalLibrary,
596601
writeFile: writeFileCallback || (
597602
(fileName, data, writeByteOrderMark, onError, sourceFiles) => host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles)),
598603
isEmitBlocked,

src/compiler/utilities.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2534,16 +2534,29 @@ namespace ts {
25342534
}
25352535
else {
25362536
const sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile];
2537-
return filter(sourceFiles, isNonDeclarationFile);
2537+
return filterSourceFilesInDirectory(sourceFiles, file => host.isSourceFileFromExternalLibrary(file));
25382538
}
25392539
}
25402540

2541+
/** Don't call this for `--outFile`, just for `--outDir` or plain emit. */
2542+
export function filterSourceFilesInDirectory(sourceFiles: SourceFile[], isSourceFileFromExternalLibrary: (file: SourceFile) => boolean): SourceFile[] {
2543+
return filter(sourceFiles, file => shouldEmitInDirectory(file, isSourceFileFromExternalLibrary));
2544+
}
2545+
25412546
function isNonDeclarationFile(sourceFile: SourceFile) {
25422547
return !isDeclarationFile(sourceFile);
25432548
}
25442549

2550+
/**
2551+
* Whether a file should be emitted in a non-`--outFile` case.
2552+
* Don't emit if source file is a declaration file, or was located under node_modules
2553+
*/
2554+
function shouldEmitInDirectory(sourceFile: SourceFile, isSourceFileFromExternalLibrary: (file: SourceFile) => boolean): boolean {
2555+
return isNonDeclarationFile(sourceFile) && !isSourceFileFromExternalLibrary(sourceFile);
2556+
}
2557+
25452558
function isBundleEmitNonExternalModule(sourceFile: SourceFile) {
2546-
return !isDeclarationFile(sourceFile) && !isExternalModule(sourceFile);
2559+
return isNonDeclarationFile(sourceFile) && !isExternalModule(sourceFile);
25472560
}
25482561

25492562
/**
@@ -2631,8 +2644,7 @@ namespace ts {
26312644
else {
26322645
const sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile];
26332646
for (const sourceFile of sourceFiles) {
2634-
// Don't emit if source file is a declaration file, or was located under node_modules
2635-
if (!isDeclarationFile(sourceFile) && !host.isSourceFileFromExternalLibrary(sourceFile)) {
2647+
if (shouldEmitInDirectory(sourceFile, file => host.isSourceFileFromExternalLibrary(file))) {
26362648
onSingleFileEmit(host, sourceFile);
26372649
}
26382650
}

src/harness/harness.ts

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -470,19 +470,6 @@ namespace Utils {
470470
}
471471
}
472472

473-
namespace Harness.Path {
474-
export function getFileName(fullPath: string) {
475-
return fullPath.replace(/^.*[\\\/]/, "");
476-
}
477-
478-
export function filePath(fullPath: string) {
479-
fullPath = ts.normalizeSlashes(fullPath);
480-
const components = fullPath.split("/");
481-
const path: string[] = components.slice(0, components.length - 1);
482-
return path.join("/") + "/";
483-
}
484-
}
485-
486473
namespace Harness {
487474
export interface IO {
488475
newLine(): string;
@@ -1090,7 +1077,9 @@ namespace Harness {
10901077
{ name: "suppressOutputPathCheck", type: "boolean" },
10911078
{ name: "noImplicitReferences", type: "boolean" },
10921079
{ name: "currentDirectory", type: "string" },
1093-
{ name: "symlink", type: "string" }
1080+
{ name: "symlink", type: "string" },
1081+
// Emitted js baseline will print full paths for every output file
1082+
{ name: "fullEmitPaths", type: "boolean" }
10941083
];
10951084

10961085
let optionsIndex: ts.Map<ts.CommandLineOption>;
@@ -1588,7 +1577,7 @@ namespace Harness {
15881577

15891578
let sourceMapCode = "";
15901579
for (let i = 0; i < result.sourceMaps.length; i++) {
1591-
sourceMapCode += "//// [" + Harness.Path.getFileName(result.sourceMaps[i].fileName) + "]\r\n";
1580+
sourceMapCode += "//// [" + ts.getBaseFileName(result.sourceMaps[i].fileName) + "]\r\n";
15921581
sourceMapCode += getByteOrderMarkText(result.sourceMaps[i]);
15931582
sourceMapCode += result.sourceMaps[i].code;
15941583
}
@@ -1611,21 +1600,22 @@ namespace Harness {
16111600
tsCode += "//// [" + header + "] ////\r\n\r\n";
16121601
}
16131602
for (let i = 0; i < tsSources.length; i++) {
1614-
tsCode += "//// [" + Harness.Path.getFileName(tsSources[i].unitName) + "]\r\n";
1603+
tsCode += "//// [" + ts.getBaseFileName(tsSources[i].unitName) + "]\r\n";
16151604
tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? "\r\n" : "");
16161605
}
16171606

16181607
let jsCode = "";
1619-
for (let i = 0; i < result.files.length; i++) {
1620-
jsCode += "//// [" + Harness.Path.getFileName(result.files[i].fileName) + "]\r\n";
1621-
jsCode += getByteOrderMarkText(result.files[i]);
1622-
jsCode += result.files[i].code;
1608+
for (const file of result.files) {
1609+
const fileName = harnessSettings["fullEmitPaths"] ? file.fileName : ts.getBaseFileName(file.fileName);
1610+
jsCode += "//// [" + fileName + "]\r\n";
1611+
jsCode += getByteOrderMarkText(file);
1612+
jsCode += file.code;
16231613
}
16241614

16251615
if (result.declFilesCode.length > 0) {
16261616
jsCode += "\r\n\r\n";
16271617
for (let i = 0; i < result.declFilesCode.length; i++) {
1628-
jsCode += "//// [" + Harness.Path.getFileName(result.declFilesCode[i].fileName) + "]\r\n";
1618+
jsCode += "//// [" + ts.getBaseFileName(result.declFilesCode[i].fileName) + "]\r\n";
16291619
jsCode += getByteOrderMarkText(result.declFilesCode[i]);
16301620
jsCode += result.declFilesCode[i].code;
16311621
}
@@ -1848,7 +1838,7 @@ namespace Harness {
18481838
}
18491839

18501840
// normalize the fileName for the single file case
1851-
currentFileName = testUnitData.length > 0 || currentFileName ? currentFileName : Path.getFileName(fileName);
1841+
currentFileName = testUnitData.length > 0 || currentFileName ? currentFileName : ts.getBaseFileName(fileName);
18521842

18531843
// EOF, push whatever remains
18541844
const newTestFile2 = {
@@ -2012,7 +2002,7 @@ namespace Harness {
20122002

20132003
export function isDefaultLibraryFile(filePath: string): boolean {
20142004
// We need to make sure that the filePath is prefixed with "lib." not just containing "lib." and end with ".d.ts"
2015-
const fileName = Path.getFileName(filePath);
2005+
const fileName = ts.getBaseFileName(filePath);
20162006
return ts.startsWith(fileName, "lib.") && ts.endsWith(fileName, ".d.ts");
20172007
}
20182008

src/harness/runnerbase.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ abstract class RunnerBase {
3232
/** Replaces instances of full paths with fileNames only */
3333
static removeFullPaths(path: string) {
3434
// If its a full path (starts with "C:" or "/") replace with just the filename
35-
let fixedPath = /^(\w:|\/)/.test(path) ? Harness.Path.getFileName(path) : path;
35+
let fixedPath = /^(\w:|\/)/.test(path) ? ts.getBaseFileName(path) : path;
3636

3737
// when running in the browser the 'full path' is the host name, shows up in error baselines
3838
const localHost = /http:\/localhost:\d+/g;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//// [tests/cases/compiler/commonSourceDirectory.ts] ////
2+
3+
//// [index.ts]
4+
// Test that importing a file from `node_modules` does not affect calculation of the common source directory.
5+
6+
export const x = 0;
7+
8+
//// [index.ts]
9+
import { x } from "foo";
10+
x + 1;
11+
12+
13+
//// [/app/bin/index.js]
14+
"use strict";
15+
var foo_1 = require("foo");
16+
foo_1.x + 1;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
=== /app/index.ts ===
2+
import { x } from "foo";
3+
>x : Symbol(x, Decl(index.ts, 0, 8))
4+
5+
x + 1;
6+
>x : Symbol(x, Decl(index.ts, 0, 8))
7+
8+
=== /node_modules/foo/index.ts ===
9+
// Test that importing a file from `node_modules` does not affect calculation of the common source directory.
10+
11+
export const x = 0;
12+
>x : Symbol(x, Decl(index.ts, 2, 12))
13+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
=== /app/index.ts ===
2+
import { x } from "foo";
3+
>x : 0
4+
5+
x + 1;
6+
>x + 1 : number
7+
>x : 0
8+
>1 : 1
9+
10+
=== /node_modules/foo/index.ts ===
11+
// Test that importing a file from `node_modules` does not affect calculation of the common source directory.
12+
13+
export const x = 0;
14+
>x : 0
15+
>0 : 0
16+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Test that importing a file from `node_modules` does not affect calculation of the common source directory.
2+
// @noImplicitReferences: true
3+
// @moduleResolution: node
4+
// @fullEmitPaths: true
5+
6+
// @filename: /node_modules/foo/index.ts
7+
export const x = 0;
8+
9+
// @filename: /app/index.ts
10+
import { x } from "foo";
11+
x + 1;
12+
13+
// @filename: /app/tsconfig.json
14+
{
15+
"compilerOptions": {
16+
"outDir": "bin"
17+
}
18+
}

0 commit comments

Comments
 (0)