Skip to content

Commit 95378aa

Browse files
author
Zhengbo Li
authored
Fix compile on save issues (microsoft#10615)
* only return .ts and .tsx files for affected document list * Return all files exclude mixed-content files for CoS affected list
1 parent 01caa69 commit 95378aa

5 files changed

Lines changed: 40 additions & 16 deletions

File tree

src/server/builder.ts

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ namespace ts.server {
1515
createHash(algorithm: string): Hash
1616
} = require("crypto");
1717

18+
export function shouldEmitFile(scriptInfo: ScriptInfo) {
19+
return !scriptInfo.hasMixedContent;
20+
}
21+
1822
/**
1923
* An abstract file info that maintains a shape signature.
2024
*/
@@ -160,16 +164,17 @@ namespace ts.server {
160164
*/
161165
getFilesAffectedBy(scriptInfo: ScriptInfo): string[] {
162166
const info = this.getOrCreateFileInfo(scriptInfo.path);
167+
const singleFileResult = scriptInfo.hasMixedContent ? [] : [scriptInfo.fileName];
163168
if (info.updateShapeSignature()) {
164169
const options = this.project.getCompilerOptions();
165170
// If `--out` or `--outFile` is specified, any new emit will result in re-emitting the entire project,
166171
// so returning the file itself is good enough.
167172
if (options && (options.out || options.outFile)) {
168-
return [scriptInfo.fileName];
173+
return singleFileResult;
169174
}
170-
return this.project.getFileNamesWithoutDefaultLib();
175+
return this.project.getAllEmittableFiles();
171176
}
172-
return [scriptInfo.fileName];
177+
return singleFileResult;
173178
}
174179
}
175180

@@ -319,18 +324,19 @@ namespace ts.server {
319324
getFilesAffectedBy(scriptInfo: ScriptInfo): string[] {
320325
this.ensureProjectDependencyGraphUpToDate();
321326

327+
const singleFileResult = scriptInfo.hasMixedContent ? [] : [scriptInfo.fileName];
322328
const fileInfo = this.getFileInfo(scriptInfo.path);
323329
if (!fileInfo || !fileInfo.updateShapeSignature()) {
324-
return [scriptInfo.fileName];
330+
return singleFileResult;
325331
}
326332

327333
if (!fileInfo.isExternalModuleOrHasOnlyAmbientExternalModules()) {
328-
return this.project.getFileNamesWithoutDefaultLib();
334+
return this.project.getAllEmittableFiles();
329335
}
330336

331337
const options = this.project.getCompilerOptions();
332338
if (options && (options.isolatedModules || options.out || options.outFile)) {
333-
return [scriptInfo.fileName];
339+
return singleFileResult;
334340
}
335341

336342
// Now we need to if each file in the referencedBy list has a shape change as well.
@@ -339,8 +345,8 @@ namespace ts.server {
339345

340346
// Use slice to clone the array to avoid manipulating in place
341347
const queue = fileInfo.referencedBy.slice(0);
342-
const fileNameSet = createMap<boolean>();
343-
fileNameSet[scriptInfo.fileName] = true;
348+
const fileNameSet = createMap<ScriptInfo>();
349+
fileNameSet[scriptInfo.fileName] = scriptInfo;
344350
while (queue.length > 0) {
345351
const processingFileInfo = queue.pop();
346352
if (processingFileInfo.updateShapeSignature() && processingFileInfo.referencedBy.length > 0) {
@@ -350,9 +356,15 @@ namespace ts.server {
350356
}
351357
}
352358
}
353-
fileNameSet[processingFileInfo.scriptInfo.fileName] = true;
359+
fileNameSet[processingFileInfo.scriptInfo.fileName] = processingFileInfo.scriptInfo;
360+
}
361+
const result: string[] = [];
362+
for (const fileName in fileNameSet) {
363+
if (shouldEmitFile(fileNameSet[fileName])) {
364+
result.push(fileName);
365+
}
354366
}
355-
return Object.keys(fileNameSet);
367+
return result;
356368
}
357369
}
358370

src/server/editorServices.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,12 @@ namespace ts.server {
871871

872872
project.setCompilerOptions(newOptions);
873873
(<ExternalProject | ConfiguredProject>project).setTypingOptions(newTypingOptions);
874-
project.compileOnSaveEnabled = !!compileOnSave;
874+
875+
// VS only set the CompileOnSaveEnabled option in the request if the option was changed recently
876+
// therefore if it is undefined, it should not be updated.
877+
if (compileOnSave !== undefined) {
878+
project.compileOnSaveEnabled = compileOnSave;
879+
}
875880
project.setProjectErrors(concatenate(configFileErrors, projectErrors));
876881

877882
project.updateGraph();

src/server/project.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,12 +225,19 @@ namespace ts.server {
225225
return sourceFiles.map(sourceFile => asNormalizedPath(sourceFile.fileName));
226226
}
227227

228-
getFileNamesWithoutDefaultLib() {
228+
getAllEmittableFiles() {
229229
if (!this.languageServiceEnabled) {
230-
return this.getRootFiles();
230+
return [];
231231
}
232232
const defaultLibraryFileName = getDefaultLibFileName(this.compilerOptions);
233-
return filter(this.getFileNames(), file => getBaseFileName(file) !== defaultLibraryFileName);
233+
const infos = this.getScriptInfos();
234+
const result: string[] = [];
235+
for (const info of infos) {
236+
if (getBaseFileName(info.fileName) !== defaultLibraryFileName && shouldEmitFile(info)) {
237+
result.push(info.fileName);
238+
}
239+
}
240+
return result;
234241
}
235242

236243
containsScriptInfo(info: ScriptInfo): boolean {

src/server/scriptInfo.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace ts.server {
2020
content: string,
2121
readonly scriptKind: ScriptKind,
2222
public isOpen = false,
23-
private hasMixedContent = false) {
23+
public hasMixedContent = false) {
2424

2525
this.path = toPath(fileName, host.getCurrentDirectory(), createGetCanonicalFileName(host.useCaseSensitiveFileNames));
2626
this.svc = ScriptVersionCache.fromString(host, content);

src/server/session.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,7 @@ namespace ts.server {
958958
// if specified a project, we only return affected file list in this project
959959
const projectsToSearch = args.projectFileName ? [this.projectService.findProject(args.projectFileName)] : info.containingProjects;
960960
for (const project of projectsToSearch) {
961-
if (project.compileOnSaveEnabled) {
961+
if (project.compileOnSaveEnabled && project.languageServiceEnabled) {
962962
result.push({
963963
projectFileName: project.getProjectName(),
964964
fileNames: project.getCompileOnSaveAffectedFileList(info)

0 commit comments

Comments
 (0)