From 95378aa39971b2edc8dd237d7b552aa888a3894f Mon Sep 17 00:00:00 2001 From: Zhengbo Li Date: Wed, 31 Aug 2016 12:11:32 -0700 Subject: [PATCH] Fix compile on save issues (#10615) * only return .ts and .tsx files for affected document list * Return all files exclude mixed-content files for CoS affected list --- src/server/builder.ts | 32 ++++++++++++++++++++++---------- src/server/editorServices.ts | 7 ++++++- src/server/project.ts | 13 ++++++++++--- src/server/scriptInfo.ts | 2 +- src/server/session.ts | 2 +- 5 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/server/builder.ts b/src/server/builder.ts index 9310976ddc0..1c5ceaf8eb2 100644 --- a/src/server/builder.ts +++ b/src/server/builder.ts @@ -15,6 +15,10 @@ namespace ts.server { createHash(algorithm: string): Hash } = require("crypto"); + export function shouldEmitFile(scriptInfo: ScriptInfo) { + return !scriptInfo.hasMixedContent; + } + /** * An abstract file info that maintains a shape signature. */ @@ -160,16 +164,17 @@ namespace ts.server { */ getFilesAffectedBy(scriptInfo: ScriptInfo): string[] { const info = this.getOrCreateFileInfo(scriptInfo.path); + const singleFileResult = scriptInfo.hasMixedContent ? [] : [scriptInfo.fileName]; if (info.updateShapeSignature()) { const options = this.project.getCompilerOptions(); // If `--out` or `--outFile` is specified, any new emit will result in re-emitting the entire project, // so returning the file itself is good enough. if (options && (options.out || options.outFile)) { - return [scriptInfo.fileName]; + return singleFileResult; } - return this.project.getFileNamesWithoutDefaultLib(); + return this.project.getAllEmittableFiles(); } - return [scriptInfo.fileName]; + return singleFileResult; } } @@ -319,18 +324,19 @@ namespace ts.server { getFilesAffectedBy(scriptInfo: ScriptInfo): string[] { this.ensureProjectDependencyGraphUpToDate(); + const singleFileResult = scriptInfo.hasMixedContent ? [] : [scriptInfo.fileName]; const fileInfo = this.getFileInfo(scriptInfo.path); if (!fileInfo || !fileInfo.updateShapeSignature()) { - return [scriptInfo.fileName]; + return singleFileResult; } if (!fileInfo.isExternalModuleOrHasOnlyAmbientExternalModules()) { - return this.project.getFileNamesWithoutDefaultLib(); + return this.project.getAllEmittableFiles(); } const options = this.project.getCompilerOptions(); if (options && (options.isolatedModules || options.out || options.outFile)) { - return [scriptInfo.fileName]; + return singleFileResult; } // Now we need to if each file in the referencedBy list has a shape change as well. @@ -339,8 +345,8 @@ namespace ts.server { // Use slice to clone the array to avoid manipulating in place const queue = fileInfo.referencedBy.slice(0); - const fileNameSet = createMap(); - fileNameSet[scriptInfo.fileName] = true; + const fileNameSet = createMap(); + fileNameSet[scriptInfo.fileName] = scriptInfo; while (queue.length > 0) { const processingFileInfo = queue.pop(); if (processingFileInfo.updateShapeSignature() && processingFileInfo.referencedBy.length > 0) { @@ -350,9 +356,15 @@ namespace ts.server { } } } - fileNameSet[processingFileInfo.scriptInfo.fileName] = true; + fileNameSet[processingFileInfo.scriptInfo.fileName] = processingFileInfo.scriptInfo; } - return Object.keys(fileNameSet); + const result: string[] = []; + for (const fileName in fileNameSet) { + if (shouldEmitFile(fileNameSet[fileName])) { + result.push(fileName); + } + } + return result; } } diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index fe8c11d262e..bd46f269239 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -871,7 +871,12 @@ namespace ts.server { project.setCompilerOptions(newOptions); (project).setTypingOptions(newTypingOptions); - project.compileOnSaveEnabled = !!compileOnSave; + + // VS only set the CompileOnSaveEnabled option in the request if the option was changed recently + // therefore if it is undefined, it should not be updated. + if (compileOnSave !== undefined) { + project.compileOnSaveEnabled = compileOnSave; + } project.setProjectErrors(concatenate(configFileErrors, projectErrors)); project.updateGraph(); diff --git a/src/server/project.ts b/src/server/project.ts index 73418607107..a627373f2f6 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -225,12 +225,19 @@ namespace ts.server { return sourceFiles.map(sourceFile => asNormalizedPath(sourceFile.fileName)); } - getFileNamesWithoutDefaultLib() { + getAllEmittableFiles() { if (!this.languageServiceEnabled) { - return this.getRootFiles(); + return []; } const defaultLibraryFileName = getDefaultLibFileName(this.compilerOptions); - return filter(this.getFileNames(), file => getBaseFileName(file) !== defaultLibraryFileName); + const infos = this.getScriptInfos(); + const result: string[] = []; + for (const info of infos) { + if (getBaseFileName(info.fileName) !== defaultLibraryFileName && shouldEmitFile(info)) { + result.push(info.fileName); + } + } + return result; } containsScriptInfo(info: ScriptInfo): boolean { diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index 6e09247924d..ceb879a40c5 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -20,7 +20,7 @@ namespace ts.server { content: string, readonly scriptKind: ScriptKind, public isOpen = false, - private hasMixedContent = false) { + public hasMixedContent = false) { this.path = toPath(fileName, host.getCurrentDirectory(), createGetCanonicalFileName(host.useCaseSensitiveFileNames)); this.svc = ScriptVersionCache.fromString(host, content); diff --git a/src/server/session.ts b/src/server/session.ts index 3da87f40631..4d9c7892b10 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -958,7 +958,7 @@ namespace ts.server { // if specified a project, we only return affected file list in this project const projectsToSearch = args.projectFileName ? [this.projectService.findProject(args.projectFileName)] : info.containingProjects; for (const project of projectsToSearch) { - if (project.compileOnSaveEnabled) { + if (project.compileOnSaveEnabled && project.languageServiceEnabled) { result.push({ projectFileName: project.getProjectName(), fileNames: project.getCompileOnSaveAffectedFileList(info)