Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fixed bugs and linting
  • Loading branch information
billti committed Jun 27, 2016
commit e9a0c56d3c01ff684ebdd026c3dd5d966abba85c
40 changes: 34 additions & 6 deletions src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1073,9 +1073,16 @@ namespace ts {
// - This calls resolveModuleNames, and then calls findSourceFile for each resolved module.
// As all these operations happen - and are nested - within the createProgram call, they close over the below variables.
// The current resolution depth is tracked by incrementing/decrementing as the depth first search progresses.
const maxNodeModulesJsDepth = options.maxNodeModuleJsDepth || 2;
const maxNodeModulesJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 2;
let currentNodeModulesJsDepth = 0;

// If a module has some of its imports skipped due to being at the depth limit under node_modules, then track
// this, as it may be imported at a shallower depth later, and then it will need its skipped imports processed.
const modulesWithElidedImports: Map<boolean> = {};

// Track source files that are JavaScript files found by searching under node_modules, as these shouldn't be compiled.
const jsFilesFoundSearchingNodeModules: Map<boolean> = {};

const start = new Date().getTime();

host = host || createCompilerHost(options);
Expand Down Expand Up @@ -1230,6 +1237,7 @@ namespace ts {
(oldOptions.rootDir !== options.rootDir) ||
(oldOptions.configFilePath !== options.configFilePath) ||
(oldOptions.baseUrl !== options.baseUrl) ||
(oldOptions.maxNodeModuleJsDepth !== options.maxNodeModuleJsDepth) ||
!arrayIsEqualTo(oldOptions.typeRoots, oldOptions.typeRoots) ||
!arrayIsEqualTo(oldOptions.rootDirs, options.rootDirs) ||
!mapIsEqualTo(oldOptions.paths, options.paths)) {
Expand Down Expand Up @@ -1353,7 +1361,10 @@ namespace ts {
getNewLine: () => host.getNewLine(),
getSourceFile: program.getSourceFile,
getSourceFileByPath: program.getSourceFileByPath,
getSourceFiles: program.getSourceFiles,
getSourceFiles: () => filter(program.getSourceFiles(),
// Remove JavaScript files found by searching node_modules from the source files to emit
sourceFile => !lookUp(jsFilesFoundSearchingNodeModules, sourceFile.path)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do not think we should do this. the file is part of the program. getSourceFle, and getSourceFile, should give an accurate representation of the files in the program. you could get an error in this file, or get a definition in this file, and using the file name you should be able to get to the SourceFile object using getSourceFile and you should also be able to find it if you enumerate the getSourceFiles.

I would say create a new method, Program.jsFilesFoundSearchingNodeModules(path) that the emitter checks and skips emitting if true.

),
writeFile: writeFileCallback || (
(fileName, data, writeByteOrderMark, onError, sourceFiles) => host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles)),
isEmitBlocked,
Expand Down Expand Up @@ -1888,6 +1899,14 @@ namespace ts {
reportFileNamesDifferOnlyInCasingError(fileName, file.fileName, refFile, refPos, refEnd);
}

// See if we need to reprocess the imports due to prior skipped imports
if (file && lookUp(modulesWithElidedImports, file.path)) {
if (currentNodeModulesJsDepth < maxNodeModulesJsDepth) { // TODO: Check for off-by-ones
modulesWithElidedImports[file.path] = false;
processImportedModules(file, getDirectoryPath(fileName));
}
}

return file;
}

Expand Down Expand Up @@ -2026,27 +2045,36 @@ namespace ts {
for (let i = 0; i < moduleNames.length; i++) {
const resolution = resolutions[i];
setResolvedModule(file, moduleNames[i], resolution);
const resolvedPath = resolution ? toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName) : undefined;

// add file to program only if:
// - resolution was successful
// - noResolve is falsy
// - module name comes from the list of imports
// - it's not a top level JavaScript module that exceeded the search max
const isJsFileUnderNodeModules = resolution && resolution.isExternalLibraryImport &&
hasJavaScriptFileExtension(resolution.resolvedFileName);

if (isJsFileUnderNodeModules) {
jsFilesFoundSearchingNodeModules[resolvedPath] = true;
currentNodeModulesJsDepth++;
}
const shouldAddFile = resolution && !options.noResolve && i < file.imports.length &&
!(isJsFileUnderNodeModules && currentNodeModulesJsDepth > maxNodeModulesJsDepth);

if (shouldAddFile) {
const elideImport = isJsFileUnderNodeModules && currentNodeModulesJsDepth > maxNodeModulesJsDepth;
const shouldAddFile = resolution && !options.noResolve && i < file.imports.length && !elideImport;

if (elideImport) {
modulesWithElidedImports[file.path] = true;
}
else if (shouldAddFile) {
findSourceFile(resolution.resolvedFileName,
toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName),
resolvedPath,
/*isDefaultLib*/ false, /*isReference*/ false,
file,
skipTrivia(file.text, file.imports[i].pos),
file.imports[i].end);
}

if (isJsFileUnderNodeModules) {
currentNodeModulesJsDepth--;
}
Expand Down
3 changes: 1 addition & 2 deletions src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2275,7 +2275,7 @@ namespace ts {
else {
const sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile];
for (const sourceFile of sourceFiles) {
// Don't emit if source file is a declaration file, or TODO: was found by a search under 'node_modules'
// Don't emit if source file is a declaration file
if (!isDeclarationFile(sourceFile)) {
onSingleFileEmit(host, sourceFile);
}
Expand Down Expand Up @@ -2310,7 +2310,6 @@ namespace ts {
function onBundledEmit(host: EmitHost) {
// Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified
const bundledSources = filter(host.getSourceFiles(),
// TODO: Don't emit from source resolved by searching under node_modules
sourceFile => !isDeclarationFile(sourceFile) && // Not a declaration file
(!isExternalModule(sourceFile) || // non module file
!!getEmitModuleKind(options))); // module that can emit - note falsy value from getEmitModuleKind means the module kind that shouldn't be emitted
Expand Down