Skip to content

Commit f9c901a

Browse files
committed
Use get files affected by internally and hence use file paths as input
1 parent d3f954e commit f9c901a

2 files changed

Lines changed: 66 additions & 79 deletions

File tree

src/compiler/builder.ts

Lines changed: 59 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ namespace ts {
4747
/* @internal */
4848
namespace ts {
4949
export interface Builder {
50-
/**
51-
* Call this to feed new program
52-
*/
50+
/** Called to inform builder about new program */
5351
updateProgram(newProgram: Program): void;
54-
getFilesAffectedBy(program: Program, path: Path): string[];
52+
/** Gets the files affected by the file path */
53+
getFilesAffectedBy(program: Program, path: Path): ReadonlyArray<SourceFile>;
54+
/** Emits the given file */
5555
emitFile(program: Program, path: Path): EmitOutput;
5656

5757
/** Emit the changed files and clear the cache of the changed files */
@@ -88,11 +88,10 @@ namespace ts {
8888
/**
8989
* Gets the files affected by the script info which has updated shape from the known one
9090
*/
91-
getFilesAffectedByUpdatedShape(program: Program, sourceFile: SourceFile, singleFileResult: string[]): string[];
91+
getFilesAffectedByUpdatedShape(program: Program, sourceFile: SourceFile): ReadonlyArray<SourceFile>;
9292
}
9393

9494
interface FileInfo {
95-
fileName: string;
9695
version: string;
9796
signature: string;
9897
}
@@ -109,7 +108,7 @@ namespace ts {
109108
const fileInfos = createMap<FileInfo>();
110109
const semanticDiagnosticsPerFile = createMap<ReadonlyArray<Diagnostic>>();
111110
/** The map has key by source file's path that has been changed */
112-
const changedFileNames = createMap<string>();
111+
const changedFileNames = createMap<true>();
113112
let emitHandler: EmitHandler;
114113
return {
115114
updateProgram,
@@ -142,31 +141,31 @@ namespace ts {
142141
);
143142
}
144143

145-
function registerChangedFile(path: Path, fileName: string) {
146-
changedFileNames.set(path, fileName);
144+
function registerChangedFile(path: Path) {
145+
changedFileNames.set(path, true);
147146
// All changed files need to re-evaluate its semantic diagnostics
148147
semanticDiagnosticsPerFile.delete(path);
149148
}
150149

151150
function addNewFileInfo(program: Program, sourceFile: SourceFile): FileInfo {
152-
registerChangedFile(sourceFile.path, sourceFile.fileName);
151+
registerChangedFile(sourceFile.path);
153152
emitHandler.onAddSourceFile(program, sourceFile);
154-
return { fileName: sourceFile.fileName, version: sourceFile.version, signature: undefined };
153+
return { version: sourceFile.version, signature: undefined };
155154
}
156155

157-
function removeExistingFileInfo(existingFileInfo: FileInfo, path: Path) {
158-
registerChangedFile(path, existingFileInfo.fileName);
156+
function removeExistingFileInfo(_existingFileInfo: FileInfo, path: Path) {
157+
registerChangedFile(path);
159158
emitHandler.onRemoveSourceFile(path);
160159
}
161160

162161
function updateExistingFileInfo(program: Program, existingInfo: FileInfo, sourceFile: SourceFile) {
163162
if (existingInfo.version !== sourceFile.version) {
164-
registerChangedFile(sourceFile.path, sourceFile.fileName);
163+
registerChangedFile(sourceFile.path);
165164
existingInfo.version = sourceFile.version;
166165
emitHandler.onUpdateSourceFile(program, sourceFile);
167166
}
168167
else if (emitHandler.onUpdateSourceFileWithSameVersion(program, sourceFile)) {
169-
registerChangedFile(sourceFile.path, sourceFile.fileName);
168+
registerChangedFile(sourceFile.path);
170169
}
171170
}
172171

@@ -182,23 +181,23 @@ namespace ts {
182181
}
183182
}
184183

185-
function getFilesAffectedBy(program: Program, path: Path): string[] {
184+
function getFilesAffectedBy(program: Program, path: Path): ReadonlyArray<SourceFile> {
186185
ensureProgramGraph(program);
187186

188-
const sourceFile = program.getSourceFile(path);
189-
const singleFileResult = sourceFile && options.shouldEmitFile(sourceFile) ? [sourceFile.fileName] : [];
187+
const sourceFile = program.getSourceFileByPath(path);
190188
const info = fileInfos.get(path);
191189
if (!info || !updateShapeSignature(program, sourceFile, info)) {
192-
return singleFileResult;
190+
return sourceFile && [sourceFile] || emptyArray;
193191
}
194192

195193
Debug.assert(!!sourceFile);
196-
return emitHandler.getFilesAffectedByUpdatedShape(program, sourceFile, singleFileResult);
194+
return emitHandler.getFilesAffectedByUpdatedShape(program, sourceFile);
197195
}
198196

199197
function emitFile(program: Program, path: Path) {
200198
ensureProgramGraph(program);
201-
if (!fileInfos.has(path)) {
199+
const sourceFile = program.getSourceFileByPath(path);
200+
if (!fileInfos.has(path) || options.shouldEmitFile(sourceFile)) {
202201
return { outputFiles: [], emitSkipped: true };
203202
}
204203

@@ -207,51 +206,46 @@ namespace ts {
207206

208207
function enumerateChangedFilesSet(
209208
program: Program,
210-
onChangedFile: (fileName: string, path: Path) => void,
211-
onAffectedFile: (fileName: string, sourceFile: SourceFile) => void
209+
onAffectedFile: (sourceFile: SourceFile) => void
212210
) {
213-
changedFileNames.forEach((fileName, path) => {
214-
onChangedFile(fileName, path as Path);
211+
changedFileNames.forEach((_true, path) => {
215212
const affectedFiles = getFilesAffectedBy(program, path as Path);
216213
for (const file of affectedFiles) {
217-
onAffectedFile(file, program.getSourceFile(file));
214+
onAffectedFile(file);
218215
}
219216
});
220217
}
221218

222219
function enumerateChangedFilesEmitOutput(
223220
program: Program,
224221
emitOnlyDtsFiles: boolean,
225-
onChangedFile: (fileName: string, path: Path) => void,
226-
onEmitOutput: (emitOutput: EmitOutputDetailed, sourceFile: SourceFile) => void
222+
onEmitOutput: (emitOutput: EmitOutputDetailed) => void
227223
) {
228224
const seenFiles = createMap<true>();
229-
enumerateChangedFilesSet(program, onChangedFile, (fileName, sourceFile) => {
230-
if (!seenFiles.has(fileName)) {
231-
seenFiles.set(fileName, true);
232-
if (sourceFile) {
233-
// Any affected file shouldnt have the cached diagnostics
234-
semanticDiagnosticsPerFile.delete(sourceFile.path);
235-
236-
const emitOutput = options.getEmitOutput(program, sourceFile, emitOnlyDtsFiles, /*isDetailed*/ true) as EmitOutputDetailed;
237-
onEmitOutput(emitOutput, sourceFile);
238-
239-
// mark all the emitted source files as seen
240-
if (emitOutput.emittedSourceFiles) {
241-
for (const file of emitOutput.emittedSourceFiles) {
242-
seenFiles.set(file.fileName, true);
243-
}
225+
enumerateChangedFilesSet(program, sourceFile => {
226+
if (!seenFiles.has(sourceFile.path)) {
227+
seenFiles.set(sourceFile.path, true);
228+
// Any affected file shouldnt have the cached diagnostics
229+
semanticDiagnosticsPerFile.delete(sourceFile.path);
230+
231+
const emitOutput = options.getEmitOutput(program, sourceFile, emitOnlyDtsFiles, /*isDetailed*/ true) as EmitOutputDetailed;
232+
233+
// mark all the emitted source files as seen
234+
if (emitOutput.emittedSourceFiles) {
235+
for (const file of emitOutput.emittedSourceFiles) {
236+
seenFiles.set(file.path, true);
244237
}
245238
}
239+
240+
onEmitOutput(emitOutput);
246241
}
247242
});
248243
}
249244

250245
function emitChangedFiles(program: Program): EmitOutputDetailed[] {
251246
ensureProgramGraph(program);
252247
const result: EmitOutputDetailed[] = [];
253-
enumerateChangedFilesEmitOutput(program, /*emitOnlyDtsFiles*/ false,
254-
/*onChangedFile*/ noop, emitOutput => result.push(emitOutput));
248+
enumerateChangedFilesEmitOutput(program, /*emitOnlyDtsFiles*/ false, emitOutput => result.push(emitOutput));
255249
changedFileNames.clear();
256250
return result;
257251
}
@@ -260,11 +254,7 @@ namespace ts {
260254
ensureProgramGraph(program);
261255

262256
// Ensure that changed files have cleared their respective
263-
enumerateChangedFilesSet(program, /*onChangedFile*/ noop, (_affectedFileName, sourceFile) => {
264-
if (sourceFile) {
265-
semanticDiagnosticsPerFile.delete(sourceFile.path);
266-
}
267-
});
257+
enumerateChangedFilesSet(program, sourceFile => semanticDiagnosticsPerFile.delete(sourceFile.path));
268258

269259
let diagnostics: Diagnostic[];
270260
for (const sourceFile of program.getSourceFiles()) {
@@ -386,24 +376,20 @@ namespace ts {
386376
}
387377

388378
/**
389-
* Gets all the emittable files from the program.
390-
* @param firstSourceFile This one will be emitted first. See https://github.com/Microsoft/TypeScript/issues/16888
379+
* Gets all files of the program excluding the default library file
391380
*/
392-
function getAllEmittableFiles(program: Program, firstSourceFile: SourceFile): string[] {
393-
const defaultLibraryFileName = getDefaultLibFileName(program.getCompilerOptions());
394-
const sourceFiles = program.getSourceFiles();
395-
const result: string[] = [];
396-
add(firstSourceFile);
397-
for (const sourceFile of sourceFiles) {
381+
function getAllFilesExcludingDefaultLibraryFile(program: Program, firstSourceFile: SourceFile): ReadonlyArray<SourceFile> {
382+
let result: SourceFile[];
383+
for (const sourceFile of program.getSourceFiles()) {
398384
if (sourceFile !== firstSourceFile) {
399-
add(sourceFile);
385+
addSourceFile(sourceFile);
400386
}
401387
}
402-
return result;
388+
return result || emptyArray;
403389

404-
function add(sourceFile: SourceFile): void {
405-
if (getBaseFileName(sourceFile.fileName) !== defaultLibraryFileName && options.shouldEmitFile(sourceFile)) {
406-
result.push(sourceFile.fileName);
390+
function addSourceFile(sourceFile: SourceFile) {
391+
if (!program.isSourceFileDefaultLibrary(sourceFile)) {
392+
(result || (result = [])).push(sourceFile);
407393
}
408394
}
409395
}
@@ -417,14 +403,14 @@ namespace ts {
417403
getFilesAffectedByUpdatedShape
418404
};
419405

420-
function getFilesAffectedByUpdatedShape(program: Program, sourceFile: SourceFile, singleFileResult: string[]): string[] {
406+
function getFilesAffectedByUpdatedShape(program: Program, sourceFile: SourceFile): ReadonlyArray<SourceFile> {
421407
const options = program.getCompilerOptions();
422408
// If `--out` or `--outFile` is specified, any new emit will result in re-emitting the entire project,
423409
// so returning the file itself is good enough.
424410
if (options && (options.out || options.outFile)) {
425-
return singleFileResult;
411+
return [sourceFile];
426412
}
427-
return getAllEmittableFiles(program, sourceFile);
413+
return getAllFilesExcludingDefaultLibraryFile(program, sourceFile);
428414
}
429415
}
430416

@@ -481,7 +467,7 @@ namespace ts {
481467
// add files referencing the removedFilePath, as changed files too
482468
const referencedByInfo = fileInfos.get(filePath);
483469
if (referencedByInfo) {
484-
registerChangedFile(filePath as Path, referencedByInfo.fileName);
470+
registerChangedFile(filePath as Path);
485471
}
486472
}
487473
});
@@ -495,37 +481,33 @@ namespace ts {
495481
);
496482
}
497483

498-
function getFilesAffectedByUpdatedShape(program: Program, sourceFile: SourceFile, singleFileResult: string[]): string[] {
484+
function getFilesAffectedByUpdatedShape(program: Program, sourceFile: SourceFile): ReadonlyArray<SourceFile> {
499485
if (!isExternalModule(sourceFile) && !containsOnlyAmbientModules(sourceFile)) {
500-
return getAllEmittableFiles(program, sourceFile);
486+
return getAllFilesExcludingDefaultLibraryFile(program, sourceFile);
501487
}
502488

503489
const compilerOptions = program.getCompilerOptions();
504490
if (compilerOptions && (compilerOptions.isolatedModules || compilerOptions.out || compilerOptions.outFile)) {
505-
return singleFileResult;
491+
return [sourceFile];
506492
}
507493

508494
// Now we need to if each file in the referencedBy list has a shape change as well.
509495
// Because if so, its own referencedBy files need to be saved as well to make the
510496
// emitting result consistent with files on disk.
511-
512-
const seenFileNamesMap = createMap<string>();
513-
const setSeenFileName = (path: Path, sourceFile: SourceFile) => {
514-
seenFileNamesMap.set(path, sourceFile && options.shouldEmitFile(sourceFile) ? sourceFile.fileName : undefined);
515-
};
497+
const seenFileNamesMap = createMap<SourceFile>();
516498

517499
// Start with the paths this file was referenced by
518500
const path = sourceFile.path;
519-
setSeenFileName(path, sourceFile);
501+
seenFileNamesMap.set(path, sourceFile);
520502
const queue = getReferencedByPaths(path);
521503
while (queue.length > 0) {
522504
const currentPath = queue.pop();
523505
if (!seenFileNamesMap.has(currentPath)) {
524506
const currentSourceFile = program.getSourceFileByPath(currentPath);
507+
seenFileNamesMap.set(currentPath, currentSourceFile);
525508
if (currentSourceFile && updateShapeSignature(program, currentSourceFile, fileInfos.get(currentPath))) {
526509
queue.push(...getReferencedByPaths(currentPath));
527510
}
528-
setSeenFileName(currentPath, currentSourceFile);
529511
}
530512
}
531513

src/server/project.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,18 +448,23 @@ namespace ts.server {
448448
computeHash: data =>
449449
this.projectService.host.createHash(data),
450450
shouldEmitFile: sourceFile =>
451-
!this.projectService.getScriptInfoForPath(sourceFile.path).isDynamicOrHasMixedContent()
451+
!this.shouldEmitFile(sourceFile)
452452
});
453453
}
454454
}
455455

456+
private shouldEmitFile(sourceFile: SourceFile) {
457+
return !this.projectService.getScriptInfoForPath(sourceFile.path).isDynamicOrHasMixedContent();
458+
}
459+
456460
getCompileOnSaveAffectedFileList(scriptInfo: ScriptInfo): string[] {
457461
if (!this.languageServiceEnabled) {
458462
return [];
459463
}
460464
this.updateGraph();
461465
this.ensureBuilder();
462-
return this.builder.getFilesAffectedBy(this.program, scriptInfo.path);
466+
return mapDefined(this.builder.getFilesAffectedBy(this.program, scriptInfo.path),
467+
sourceFile => this.shouldEmitFile(sourceFile) ? sourceFile.fileName : undefined);
463468
}
464469

465470
/**

0 commit comments

Comments
 (0)