Skip to content

Commit 07bfbab

Browse files
committed
Changed implementation to use closure
1 parent 4d4f679 commit 07bfbab

3 files changed

Lines changed: 33 additions & 47 deletions

File tree

src/compiler/program.ts

Lines changed: 27 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,16 @@ namespace ts {
10661066
let resolvedTypeReferenceDirectives: Map<ResolvedTypeReferenceDirective> = {};
10671067
let fileProcessingDiagnostics = createDiagnosticCollection();
10681068

1069+
// The below settings are to track if a .js file should be add to the program if loaded via searching under node_modules.
1070+
// This works as imported modules are discovered recursively in a depth first manner, specifically:
1071+
// - For each root file, findSourceFile is called.
1072+
// - This calls processImportedModules for each module imported in the source file.
1073+
// - This calls resolveModuleNames, and then calls findSourceFile for each resolved module.
1074+
// As all these operations happen - and are nested - within the createProgram call, they close over the below variables.
1075+
// The current resolution depth is tracked by incrementing/decrementing as the depth first search progresses.
1076+
const maxNodeModulesJsDepth = options.maxNodeModuleJsDepth || 2;
1077+
let currentNodeModulesJsDepth = 0;
1078+
10691079
const start = new Date().getTime();
10701080

10711081
host = host || createCompilerHost(options);
@@ -1869,7 +1879,7 @@ namespace ts {
18691879
}
18701880

18711881
// Get source file from normalized fileName
1872-
function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, isReference: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number, isFileFromNodeSearch?: boolean): SourceFile {
1882+
function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, isReference: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile {
18731883
if (filesByName.contains(path)) {
18741884
const file = filesByName.get(path);
18751885
// try to check if we've already seen this file but with a different casing in path
@@ -1878,12 +1888,6 @@ namespace ts {
18781888
reportFileNamesDifferOnlyInCasingError(fileName, file.fileName, refFile, refPos, refEnd);
18791889
}
18801890

1881-
// If this was a file found by a node_modules search, set the nodeModuleSearchDistance to parent distance + 1.
1882-
if (isFileFromNodeSearch) {
1883-
const newDistance = (refFile && refFile.nodeModuleSearchDistance) === undefined ? 1 : refFile.nodeModuleSearchDistance + 1;
1884-
// If already set on the file, don't overwrite if it was already found closer (which may be '0' if added as a root file)
1885-
file.nodeModuleSearchDistance = (typeof file.nodeModuleSearchDistance === "number") ? Math.min(file.nodeModuleSearchDistance, newDistance) : newDistance;
1886-
}
18871891
return file;
18881892
}
18891893

@@ -1902,12 +1906,6 @@ namespace ts {
19021906
if (file) {
19031907
file.path = path;
19041908

1905-
// Default to same distance as parent. Add one if found by a search.
1906-
file.nodeModuleSearchDistance = (refFile && refFile.nodeModuleSearchDistance) || 0;
1907-
if (isFileFromNodeSearch) {
1908-
file.nodeModuleSearchDistance++;
1909-
}
1910-
19111909
if (host.useCaseSensitiveFileNames()) {
19121910
// for case-sensitive file systems check if we've already seen some file with similar filename ignoring case
19131911
const existingFile = filesByNameIgnoreCase.get(path);
@@ -2020,13 +2018,11 @@ namespace ts {
20202018
}
20212019

20222020
function processImportedModules(file: SourceFile, basePath: string) {
2023-
const maxJsNodeModuleSearchDistance = options.maxNodeModuleJsDepth || 0;
20242021
collectExternalModuleReferences(file);
20252022
if (file.imports.length || file.moduleAugmentations.length) {
20262023
file.resolvedModules = {};
20272024
const moduleNames = map(concatenate(file.imports, file.moduleAugmentations), getTextOfLiteral);
20282025
const resolutions = resolveModuleNamesWorker(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory));
2029-
file.nodeModuleSearchDistance = file.nodeModuleSearchDistance || 0;
20302026
for (let i = 0; i < moduleNames.length; i++) {
20312027
const resolution = resolutions[i];
20322028
setResolvedModule(file, moduleNames[i], resolution);
@@ -2035,32 +2031,24 @@ namespace ts {
20352031
// - noResolve is falsy
20362032
// - module name comes from the list of imports
20372033
// - it's not a top level JavaScript module that exceeded the search max
2038-
const exceedsJsSearchDepth = resolution && resolution.isExternalLibraryImport &&
2039-
hasJavaScriptFileExtension(resolution.resolvedFileName) &&
2040-
file.nodeModuleSearchDistance >= maxJsNodeModuleSearchDistance;
2041-
const shouldAddFile = resolution && !options.noResolve && i < file.imports.length && !exceedsJsSearchDepth;
2034+
let isJsFileUnderNodeModules = resolution && resolution.isExternalLibraryImport &&
2035+
hasJavaScriptFileExtension(resolution.resolvedFileName);
2036+
if (isJsFileUnderNodeModules) {
2037+
currentNodeModulesJsDepth++;
2038+
}
2039+
const shouldAddFile = resolution && !options.noResolve && i < file.imports.length &&
2040+
!(isJsFileUnderNodeModules && currentNodeModulesJsDepth > maxNodeModulesJsDepth);
20422041

20432042
if (shouldAddFile) {
2044-
// const importedFile = findSourceFile(resolution.resolvedFileName,
2045-
// toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName),
2046-
// /*isDefaultLib*/ false, /*isReference*/ false,
2047-
// file,
2048-
// skipTrivia(file.text, file.imports[i].pos),
2049-
// file.imports[i].end,
2050-
// resolution.isExternalLibraryImport);
2051-
//
2052-
// // TODO (billti): Should we check here if a JavaScript file is a CommonJS file, or doesn't have /// references?
2053-
// if (importedFile && resolution.isExternalLibraryImport && !hasJavaScriptFileExtension(importedFile.fileName)) {
2054-
// if (!isExternalModule(importedFile) && importedFile.statements.length) {
2055-
// const start = getTokenPosOfNode(file.imports[i], file);
2056-
// fileProcessingDiagnostics.add(createFileDiagnostic(file, start, file.imports[i].end - start, Diagnostics.Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition, importedFile.fileName));
2057-
// }
2058-
// else if (importedFile.referencedFiles.length) {
2059-
// const firstRef = importedFile.referencedFiles[0];
2060-
// fileProcessingDiagnostics.add(createFileDiagnostic(importedFile, firstRef.pos, firstRef.end - firstRef.pos, Diagnostics.Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition));
2061-
// }
2062-
// }
2063-
findSourceFile(resolution.resolvedFileName, toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), /*isDefaultLib*/ false, /*isReference*/ false, file, skipTrivia(file.text, file.imports[i].pos), file.imports[i].end);
2043+
findSourceFile(resolution.resolvedFileName,
2044+
toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName),
2045+
/*isDefaultLib*/ false, /*isReference*/ false,
2046+
file,
2047+
skipTrivia(file.text, file.imports[i].pos),
2048+
file.imports[i].end);
2049+
}
2050+
if (isJsFileUnderNodeModules) {
2051+
currentNodeModulesJsDepth--;
20642052
}
20652053
}
20662054
}

src/compiler/types.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,8 +1642,6 @@ namespace ts {
16421642
/* @internal */ externalModuleIndicator: Node;
16431643
// The first node that causes this file to be a CommonJS module
16441644
/* @internal */ commonJsModuleIndicator: Node;
1645-
// The number of times node_modules was searched to locate the package containing this file
1646-
/* @internal */ nodeModuleSearchDistance?: number;
16471645

16481646
/* @internal */ identifiers: Map<string>;
16491647
/* @internal */ nodeCount: number;

src/compiler/utilities.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2275,8 +2275,8 @@ namespace ts {
22752275
else {
22762276
const sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile];
22772277
for (const sourceFile of sourceFiles) {
2278-
// Don't emit if source file is a declaration file, or was found by a search under 'node_modules'
2279-
if (!isDeclarationFile(sourceFile) && !sourceFile.nodeModuleSearchDistance) {
2278+
// Don't emit if source file is a declaration file, or TODO: was found by a search under 'node_modules'
2279+
if (!isDeclarationFile(sourceFile)) {
22802280
onSingleFileEmit(host, sourceFile);
22812281
}
22822282
}
@@ -2310,10 +2310,10 @@ namespace ts {
23102310
function onBundledEmit(host: EmitHost) {
23112311
// Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified
23122312
const bundledSources = filter(host.getSourceFiles(),
2313-
sourceFile => !isDeclarationFile(sourceFile) && // Not a declaration file
2314-
!sourceFile.nodeModuleSearchDistance && // Not loaded from searching under node_modules
2315-
(!isExternalModule(sourceFile) || // non module file
2316-
(getEmitModuleKind(options) && isExternalModule(sourceFile)))); // module that can emit - note falsy value from getEmitModuleKind means the module kind that shouldn't be emitted
2313+
// TODO: Don't emit from source resolved by searching under node_modules
2314+
sourceFile => !isDeclarationFile(sourceFile) && // Not a declaration file
2315+
(!isExternalModule(sourceFile) || // non module file
2316+
!!getEmitModuleKind(options))); // module that can emit - note falsy value from getEmitModuleKind means the module kind that shouldn't be emitted
23172317
if (bundledSources.length) {
23182318
const jsFilePath = options.outFile || options.out;
23192319
const emitFileNames: EmitFileNames = {

0 commit comments

Comments
 (0)