From 3b5555862c7bfd34cea586d47e437c8a2cd92a5d Mon Sep 17 00:00:00 2001 From: zhengbli Date: Fri, 11 Mar 2016 15:56:36 -0800 Subject: [PATCH] Add upper limit for the program size, fix readDirectory for the symlink files --- src/compiler/commandLineParser.ts | 2 +- src/compiler/diagnosticMessages.json | 4 ++++ src/compiler/program.ts | 16 ++++++++++++- src/compiler/sys.ts | 12 +++++----- src/compiler/utilities.ts | 6 +++++ src/server/editorServices.ts | 36 ++++++++++++++++++++++++---- 6 files changed, 63 insertions(+), 13 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index b3a081d6b05..652582c270f 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -534,7 +534,7 @@ namespace ts { } else { // by default exclude node_modules, and any specificied output directory - exclude = ["node_modules"]; + exclude = ["node_modules", "bower_components"]; const outDir = json["compilerOptions"] && json["compilerOptions"]["outDir"]; if (outDir) { exclude.push(outDir); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index ce9303a85c9..d54cddb245c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2661,5 +2661,9 @@ "Unknown typing option '{0}'.": { "category": "Error", "code": 17010 + }, + "Too many javascript files in the project. Consider add to the `exclude` list in the config file.": { + "category": "Error", + "code": 17012 } } \ No newline at end of file diff --git a/src/compiler/program.ts b/src/compiler/program.ts index f93801e123a..59b6a1512fe 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -400,7 +400,21 @@ namespace ts { } if (!tryReuseStructureFromOldProgram()) { - forEach(rootNames, name => processRootFile(name, /*isDefaultLib*/ false)); + let programSize = 0; + for (const name of rootNames) { + const path = toPath(name, currentDirectory, getCanonicalFileName); + if (programSize <= maxProgramSize) { + processRootFile(name, /*isDefaultLib*/ false); + if (!hasTypeScriptFileExtension(name) && filesByName.get(path)) { + programSize += filesByName.get(path).text.length; + } + } + else { + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Too_many_javascript_files_in_the_project_Consider_add_to_the_exclude_list_in_the_config_file)); + break; + } + } + // Do not process the default library if: // - The '--noLib' flag is used. // - A 'no-default-lib' reference comment is encountered in diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 34de18aeaa3..7916559ed11 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -74,7 +74,7 @@ namespace ts { watchDirectory?(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher; }; - export var sys: System = (function () { + export var sys: System = (function() { function getWScriptSystem(): System { @@ -407,8 +407,8 @@ namespace ts { const watchedFileSet = createWatchedFileSet(); function isNode4OrLater(): boolean { - return parseInt(process.version.charAt(1)) >= 4; - } + return parseInt(process.version.charAt(1)) >= 4; + } const platform: string = _os.platform(); // win32\win64 are case insensitive platforms, MacOS (darwin) by default is also case insensitive @@ -477,7 +477,7 @@ namespace ts { for (const current of files) { const name = combinePaths(path, current); if (!contains(exclude, getCanonicalPath(name))) { - const stat = _fs.statSync(name); + const stat = _fs.lstatSync(name); if (stat.isFile()) { if (!extension || fileExtensionIs(name, extension)) { result.push(name); @@ -509,7 +509,7 @@ namespace ts { // and https://github.com/Microsoft/TypeScript/issues/4643), therefore // if the current node.js version is newer than 4, use `fs.watch` instead. const watchSet = isNode4OrLater() ? watchedFileSet : pollingWatchedFileSet; - const watchedFile = watchSet.addFile(filePath, callback); + const watchedFile = watchSet.addFile(filePath, callback); return { close: () => watchSet.removeFile(watchedFile) }; @@ -539,7 +539,7 @@ namespace ts { } ); }, - resolvePath: function (path: string): string { + resolvePath: function(path: string): string { return _path.resolve(path); }, fileExists(path: string): boolean { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 42f439e0ded..22fc5b73e55 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2476,6 +2476,10 @@ namespace ts { return forEach(supportedJavascriptExtensions, extension => fileExtensionIs(fileName, extension)); } + export function hasTypeScriptFileExtension(fileName: string) { + return forEach(supportedTypeScriptExtensions, extension => fileExtensionIs(fileName, extension)); + } + /** * Replace each instance of non-ascii characters by one, two, three, or four escape sequences * representing the UTF-8 encoding of the character, and return the expanded char code list. @@ -2858,4 +2862,6 @@ namespace ts { export function isParameterPropertyDeclaration(node: ParameterDeclaration): boolean { return node.flags & NodeFlags.AccessibilityModifier && node.parent.kind === SyntaxKind.Constructor && isClassLike(node.parent.parent); } + + export const maxProgramSize = 35 * 1024 * 1024; } diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 42a2bded6a5..3ab1ef57f7e 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1217,13 +1217,35 @@ namespace ts.server { } else { const project = this.createProject(configFilename, projectOptions); + let programSize = 0; + + // As the project openning might not be complete if there are too many files, + // therefore to surface the diagnostics we need to make sure the given client file is opened. + if (clientFileName) { + const currentClientFileInfo = this.openFile(clientFileName, /*openedByClient*/ true); + project.addRoot(currentClientFileInfo); + programSize += currentClientFileInfo.content.length; + } + for (const rootFilename of projectOptions.files) { - if (this.host.fileExists(rootFilename)) { - const info = this.openFile(rootFilename, /*openedByClient*/ clientFileName == rootFilename); - project.addRoot(info); + if (rootFilename === clientFileName) { + continue; + } + + if (programSize <= maxProgramSize) { + if (this.host.fileExists(rootFilename)) { + const info = this.openFile(rootFilename, /*openedByClient*/ false); + project.addRoot(info); + if (!hasTypeScriptFileExtension(rootFilename)) { + programSize += info.content.length; + } + } + else { + return { errorMsg: "specified file " + rootFilename + " not found" }; + } } else { - return { errorMsg: "specified file " + rootFilename + " not found" }; + break; } } project.finishGraph(); @@ -1251,11 +1273,15 @@ namespace ts.server { return error; } else { - const oldFileNames = project.compilerService.host.roots.map(info => info.fileName); + const oldFileNames = project.projectOptions ? project.projectOptions.files : project.compilerService.host.roots.map(info => info.fileName); const newFileNames = projectOptions.files; const fileNamesToRemove = oldFileNames.filter(f => newFileNames.indexOf(f) < 0); const fileNamesToAdd = newFileNames.filter(f => oldFileNames.indexOf(f) < 0); + if (fileNamesToAdd.length === 0 && fileNamesToRemove.length === 0) { + return; + } + for (const fileName of fileNamesToRemove) { const info = this.getScriptInfo(fileName); if (info) {