diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 5d71ff4c2d3..c5f7a9ac1ce 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1377,9 +1377,10 @@ namespace ts.server { return { projectOptions, configFileErrors: errors, configFileSpecs: parsedCommandLine.configFileSpecs }; } - private exceededTotalSizeLimitForNonTsFiles(name: string, options: CompilerOptions, fileNames: T[], propertyReader: FilePropertyReader) { + /** Get a filename if the language service exceeds the maximum allowed program size; otherwise returns undefined. */ + private getFilenameForExceededTotalSizeLimitForNonTsFiles(name: string, options: CompilerOptions, fileNames: T[], propertyReader: FilePropertyReader): string | undefined { if (options && options.disableSizeLimit || !this.host.getFileSize) { - return false; + return; } let availableSpace = maxProgramSizeForNonTsFiles; @@ -1396,20 +1397,16 @@ namespace ts.server { totalNonTsFileSize += this.host.getFileSize(fileName); - if (totalNonTsFileSize > maxProgramSizeForNonTsFiles) { + if (totalNonTsFileSize > maxProgramSizeForNonTsFiles || totalNonTsFileSize > availableSpace) { this.logger.info(getExceedLimitMessage({ propertyReader, hasTypeScriptFileExtension, host: this.host }, totalNonTsFileSize)); // Keep the size as zero since it's disabled - return true; + return fileName; } } - if (totalNonTsFileSize > availableSpace) { - this.logger.info(getExceedLimitMessage({ propertyReader, hasTypeScriptFileExtension, host: this.host }, totalNonTsFileSize)); - return true; - } - this.projectToSizeMap.set(name, totalNonTsFileSize); - return false; + + return; function getExceedLimitMessage(context: { propertyReader: FilePropertyReader, hasTypeScriptFileExtension: (filename: string) => boolean, host: ServerHost }, totalNonTsFileSize: number) { const files = getTop5LargestFiles(context); @@ -1432,7 +1429,7 @@ namespace ts.server { this, this.documentRegistry, compilerOptions, - /*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(projectFileName, compilerOptions, files, externalFilePropertyReader), + /*exceededFilename*/ this.getFilenameForExceededTotalSizeLimitForNonTsFiles(projectFileName, compilerOptions, files, externalFilePropertyReader), options.compileOnSave === undefined ? true : options.compileOnSave); project.excludedFiles = excludedFiles; @@ -1498,14 +1495,14 @@ namespace ts.server { const cachedDirectoryStructureHost = createCachedDirectoryStructureHost(this.host, this.host.getCurrentDirectory(), this.host.useCaseSensitiveFileNames); const { projectOptions, configFileErrors, configFileSpecs } = this.convertConfigFileContentToProjectOptions(configFileName, cachedDirectoryStructureHost); this.logger.info(`Opened configuration file ${configFileName}`); - const languageServiceEnabled = !this.exceededTotalSizeLimitForNonTsFiles(configFileName, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader); + const exceededFilename = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(configFileName, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader); const project = new ConfiguredProject( configFileName, this, this.documentRegistry, projectOptions.configHasFilesProperty, projectOptions.compilerOptions, - languageServiceEnabled, + exceededFilename, projectOptions.compileOnSave === undefined ? false : projectOptions.compileOnSave, cachedDirectoryStructureHost); @@ -1518,7 +1515,7 @@ namespace ts.server { WatchType.ConfigFilePath, project ); - if (languageServiceEnabled) { + if (!exceededFilename) { project.watchWildcards(projectOptions.wildcardDirectories); } @@ -1631,8 +1628,9 @@ namespace ts.server { // Update the project project.configFileSpecs = configFileSpecs; project.setProjectErrors(configFileErrors); - if (this.exceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader)) { - project.disableLanguageService(); + const exceededFilename = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader); + if (exceededFilename) { + project.disableLanguageService(exceededFilename); project.stopWatchingWildCards(); } else { @@ -2396,8 +2394,9 @@ namespace ts.server { externalProject.excludedFiles = excludedFiles; if (!tsConfigFiles) { const compilerOptions = convertCompilerOptions(proj.options); - if (this.exceededTotalSizeLimitForNonTsFiles(proj.projectFileName, compilerOptions, proj.rootFiles, externalFilePropertyReader)) { - externalProject.disableLanguageService(); + const exceededFilename = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(proj.projectFileName, compilerOptions, proj.rootFiles, externalFilePropertyReader); + if (exceededFilename) { + externalProject.disableLanguageService(exceededFilename); } else { externalProject.enableLanguageService(); diff --git a/src/server/project.ts b/src/server/project.ts index 47365547479..bc8d704d6a0 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -130,6 +130,7 @@ namespace ts.server { protected languageService: LanguageService; public languageServiceEnabled = true; + public exceededFilename: string | undefined; readonly trace?: (s: string) => void; readonly realpath?: (path: string) => string; @@ -212,7 +213,7 @@ namespace ts.server { readonly projectService: ProjectService, private documentRegistry: DocumentRegistry, hasExplicitListOfFiles: boolean, - languageServiceEnabled: boolean, + exceededFilename: string | undefined, private compilerOptions: CompilerOptions, public compileOnSaveEnabled: boolean, directoryStructureHost: DirectoryStructureHost, @@ -244,8 +245,8 @@ namespace ts.server { // Use the current directory as resolution root only if the project created using current directory string this.resolutionCache = createResolutionCache(this, currentDirectory && this.currentDirectory, /*logChangesWhenResolvingModule*/ true); this.languageService = createLanguageService(this, this.documentRegistry); - if (!languageServiceEnabled) { - this.disableLanguageService(); + if (exceededFilename) { + this.disableLanguageService(exceededFilename); } this.markAsDirty(); } @@ -500,12 +501,13 @@ namespace ts.server { this.projectService.onUpdateLanguageServiceStateForProject(this, /*languageServiceEnabled*/ true); } - disableLanguageService() { + disableLanguageService(exceededFilename: string) { if (!this.languageServiceEnabled) { return; } this.languageService.cleanupSemanticCache(); this.languageServiceEnabled = false; + this.exceededFilename = exceededFilename; this.builderState = undefined; this.resolutionCache.closeTypeRootsWatch(); this.projectService.onUpdateLanguageServiceStateForProject(this, /*languageServiceEnabled*/ false); @@ -993,12 +995,12 @@ namespace ts.server { getChangesSinceVersion(lastKnownVersion?: number): ProjectFilesWithTSDiagnostics { this.updateGraph(); - const info = { + const info: protocol.ProjectVersionInfo = { projectName: this.getProjectName(), version: this.projectStructureVersion, isInferred: this.projectKind === ProjectKind.Inferred, options: this.getCompilationSettings(), - languageServiceDisabled: !this.languageServiceEnabled + exceededFilename: this.exceededFilename }; const updatedFileNames = this.updatedFileNames; this.updatedFileNames = undefined; @@ -1182,7 +1184,7 @@ namespace ts.server { projectService, documentRegistry, /*files*/ undefined, - /*languageServiceEnabled*/ true, + /*exceededFileName*/ undefined, compilerOptions, /*compileOnSaveEnabled*/ false, projectService.host, @@ -1261,7 +1263,7 @@ namespace ts.server { documentRegistry: DocumentRegistry, hasExplicitListOfFiles: boolean, compilerOptions: CompilerOptions, - languageServiceEnabled: boolean, + exceededFilename: string | undefined, public compileOnSaveEnabled: boolean, cachedDirectoryStructureHost: CachedDirectoryStructureHost) { super(configFileName, @@ -1269,7 +1271,7 @@ namespace ts.server { projectService, documentRegistry, hasExplicitListOfFiles, - languageServiceEnabled, + exceededFilename, compilerOptions, compileOnSaveEnabled, cachedDirectoryStructureHost, @@ -1456,7 +1458,7 @@ namespace ts.server { projectService: ProjectService, documentRegistry: DocumentRegistry, compilerOptions: CompilerOptions, - languageServiceEnabled: boolean, + exceededFilename: string | undefined, public compileOnSaveEnabled: boolean, projectFilePath?: string) { super(externalProjectName, @@ -1464,7 +1466,7 @@ namespace ts.server { projectService, documentRegistry, /*hasExplicitListOfFiles*/ true, - languageServiceEnabled, + exceededFilename, compilerOptions, compileOnSaveEnabled, projectService.host, diff --git a/src/server/protocol.ts b/src/server/protocol.ts index b4ff0aa4037..fd1aa3df32f 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -1106,9 +1106,9 @@ namespace ts.server.protocol { options: ts.CompilerOptions; /** - * true if project language service is disabled + * Filename of the last file analyzed before disabling the language service. undefined, if the language service is enabled. */ - languageServiceDisabled: boolean; + exceededFilename: string | undefined; } /**