Skip to content

Commit 89c61e7

Browse files
committed
Modify the api in builder so that it tracks changed files
1 parent 2dd6aed commit 89c61e7

8 files changed

Lines changed: 336 additions & 320 deletions

File tree

src/compiler/builder.ts

Lines changed: 114 additions & 72 deletions
Large diffs are not rendered by default.

src/compiler/core.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -473,12 +473,14 @@ namespace ts {
473473
return result;
474474
}
475475

476-
export function flatMapIter<T, U>(iter: Iterator<T>, mapfn: (x: T) => U | U[] | undefined): U[] {
477-
const result: U[] = [];
476+
export function flatMapIter<T>(iter: Iterator<T>): T[];
477+
export function flatMapIter<T, U>(iter: Iterator<T>, mapfn: (x: T) => U | U[] | undefined): U[];
478+
export function flatMapIter<T>(iter: Iterator<T>, mapfn?: (x: any) => any): any[] {
479+
const result = [];
478480
while (true) {
479481
const { value, done } = iter.next();
480482
if (done) break;
481-
const res = mapfn(value);
483+
const res = mapfn ? mapfn(value) : value;
482484
if (res) {
483485
if (isArray(res)) {
484486
result.push(...res);

src/compiler/tscLib.ts

Lines changed: 32 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,6 @@ namespace ts {
248248
let timerToUpdateProgram: any; // timer callback to recompile the program
249249

250250
const sourceFilesCache = createMap<HostFileInfo | string>(); // Cache that stores the source file and version info
251-
let changedFilePaths: Path[] = [];
252251

253252
let host: System;
254253
if (configFileName) {
@@ -262,7 +261,7 @@ namespace ts {
262261
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames);
263262

264263
// There is no extra check needed since we can just rely on the program to decide emit
265-
const builder = createBuilder(getCanonicalFileName, getDetailedEmitOutput, computeHash, _sourceFile => true);
264+
const builder = createBuilder(getCanonicalFileName, getFileEmitOutput, computeHash, _sourceFile => true);
266265

267266
if (compilerOptions.pretty) {
268267
reportDiagnosticWorker = reportDiagnosticWithColorAndContext;
@@ -352,51 +351,44 @@ namespace ts {
352351

353352
function emitWithBuilder(program: Program): EmitResult {
354353
builder.onProgramUpdateGraph(program);
355-
const filesPendingToEmit = changedFilePaths;
356-
changedFilePaths = [];
357-
358-
const seenFiles = createMap<true>();
359-
360-
let emitSkipped: boolean;
361-
const diagnostics: Diagnostic[] = [];
362354
const emittedFiles: string[] = program.getCompilerOptions().listEmittedFiles ? [] : undefined;
363355
let sourceMaps: SourceMapData[];
364-
while (filesPendingToEmit.length) {
365-
const filePath = filesPendingToEmit.pop();
366-
const affectedFiles = builder.getFilesAffectedBy(program, filePath);
367-
for (const file of affectedFiles) {
368-
if (!seenFiles.has(file)) {
369-
seenFiles.set(file, true);
370-
const sourceFile = program.getSourceFile(file);
371-
if (sourceFile) {
372-
writeFiles(<EmitOutputDetailed>builder.emitFile(program, sourceFile.path));
356+
let emitSkipped: boolean;
357+
let diagnostics: Diagnostic[];
358+
359+
const result = builder.emitChangedFiles(program);
360+
switch (result.length) {
361+
case 0:
362+
emitSkipped = true;
363+
break;
364+
case 1:
365+
const emitOutput = result[0];
366+
({ diagnostics, sourceMaps, emitSkipped } = emitOutput);
367+
writeOutputFiles(emitOutput.outputFiles);
368+
break;
369+
default:
370+
for (const emitOutput of result) {
371+
if (emitOutput.emitSkipped) {
372+
emitSkipped = true;
373373
}
374+
diagnostics = concatenate(diagnostics, emitOutput.diagnostics);
375+
sourceMaps = concatenate(sourceMaps, emitOutput.sourceMaps);
376+
writeOutputFiles(emitOutput.outputFiles);
374377
}
375-
}
376378
}
377379

378-
return { emitSkipped, diagnostics, emittedFiles, sourceMaps };
379-
380-
function writeFiles(emitOutput: EmitOutputDetailed) {
381-
if (emitOutput.emitSkipped) {
382-
emitSkipped = true;
383-
}
380+
return { emitSkipped, diagnostics: diagnostics || [], emittedFiles, sourceMaps };
384381

385-
diagnostics.push(...emitOutput.diagnostics);
386-
sourceMaps = concatenate(sourceMaps, emitOutput.sourceMaps);
387-
// If it emitted more than one source files, just mark all those source files as seen
388-
if (emitOutput.emittedSourceFiles && emitOutput.emittedSourceFiles.length > 1) {
389-
for (const file of emitOutput.emittedSourceFiles) {
390-
seenFiles.set(file.fileName, true);
391-
}
392-
}
393-
for (const outputFile of emitOutput.outputFiles) {
394-
const error = writeFile(outputFile.name, outputFile.text, outputFile.writeByteOrderMark);
395-
if (error) {
396-
diagnostics.push(error);
397-
}
398-
if (emittedFiles) {
399-
emittedFiles.push(outputFile.name);
382+
function writeOutputFiles(outputFiles: OutputFile[]) {
383+
if (outputFiles) {
384+
for (const outputFile of outputFiles) {
385+
const error = writeFile(outputFile.name, outputFile.text, outputFile.writeByteOrderMark);
386+
if (error) {
387+
diagnostics.push(error);
388+
}
389+
if (emittedFiles) {
390+
emittedFiles.push(outputFile.name);
391+
}
400392
}
401393
}
402394
}
@@ -430,8 +422,6 @@ namespace ts {
430422

431423
// Create new source file if requested or the versions dont match
432424
if (!hostSourceFile || shouldCreateNewSourceFile || hostSourceFile.version.toString() !== hostSourceFile.sourceFile.version) {
433-
changedFilePaths.push(path);
434-
435425
const sourceFile = getNewSourceFile();
436426
if (hostSourceFile) {
437427
if (shouldCreateNewSourceFile) {

src/compiler/utilities.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3656,13 +3656,27 @@ namespace ts {
36563656
);
36573657
}
36583658

3659+
export function mutateExistingMapWithSameExistingValues<T, U>(
3660+
existingMap: Map<T>, newMap: Map<U>,
3661+
createNewValue: (key: string, valueInNewMap: U) => T,
3662+
onDeleteExistingValue: (key: string, existingValue: T) => void,
3663+
onExistingValue?: (existingValue: T, valueInNewMap: U) => void
3664+
): Map<T> {
3665+
return mutateExistingMap(
3666+
existingMap, newMap,
3667+
createNewValue, onDeleteExistingValue,
3668+
/*isSameValue*/ undefined, /*onDeleteExistingMismatchValue*/ undefined,
3669+
onExistingValue
3670+
);
3671+
}
3672+
36593673
export function mutateExistingMap<T, U>(
36603674
existingMap: Map<T>, newMap: Map<U>,
36613675
createNewValue: (key: string, valueInNewMap: U) => T,
36623676
onDeleteExistingValue: (key: string, existingValue: T) => void,
36633677
isSameValue?: (existingValue: T, valueInNewMap: U) => boolean,
36643678
OnDeleteExistingMismatchValue?: (key: string, existingValue: T) => void,
3665-
onSameExistingValue?: (existingValue: T, valueInNewMap: U) => void
3679+
onExistingValue?: (existingValue: T, valueInNewMap: U) => void
36663680
): Map<T> {
36673681
// If there are new values update them
36683682
if (newMap) {
@@ -3680,8 +3694,8 @@ namespace ts {
36803694
existingMap.delete(key);
36813695
OnDeleteExistingMismatchValue(key, existingValue);
36823696
}
3683-
else if (onSameExistingValue) {
3684-
onSameExistingValue(existingValue, valueInNewMap);
3697+
else if (onExistingValue) {
3698+
onExistingValue(existingValue, valueInNewMap);
36853699
}
36863700
});
36873701
}

0 commit comments

Comments
 (0)