Skip to content

Commit 48baa42

Browse files
committed
Make SolutionBuilder handle BuilderProgram in preparation to handle incremental builds
1 parent 9e05abc commit 48baa42

File tree

11 files changed

+251
-219
lines changed

11 files changed

+251
-219
lines changed

src/compiler/core.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,6 +1391,14 @@ namespace ts {
13911391
return result;
13921392
}
13931393

1394+
export function copyProperities<T1 extends T2, T2>(first: T1, second: T2) {
1395+
for (const id in second) {
1396+
if (hasOwnProperty.call(second, id)) {
1397+
(first as any)[id] = second[id];
1398+
}
1399+
}
1400+
}
1401+
13941402
export interface MultiMap<T> extends Map<T[]> {
13951403
/**
13961404
* Adds the value to an array of values associated with the key, and returns the array.

src/compiler/program.ts

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ namespace ts {
6969
export function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost {
7070
return createCompilerHostWorker(options, setParentNodes);
7171
}
72+
7273
/*@internal*/
7374
// TODO(shkamat): update this after reworking ts build API
7475
export function createCompilerHostWorker(options: CompilerOptions, setParentNodes?: boolean, system = sys): CompilerHost {
@@ -93,7 +94,6 @@ namespace ts {
9394
}
9495
text = "";
9596
}
96-
9797
return text !== undefined ? createSourceFile(fileName, text, languageVersion, setParentNodes) : undefined;
9898
}
9999

@@ -203,18 +203,25 @@ namespace ts {
203203
return compilerHost;
204204
}
205205

206+
interface ComplierHostLikeForCache {
207+
fileExists(fileName: string): boolean;
208+
readFile(fileName: string, encoding?: string): string | undefined;
209+
directoryExists?(directory: string): boolean;
210+
createDirectory?(directory: string): void;
211+
writeFile?: WriteFileCallback;
212+
}
213+
206214
/*@internal*/
207-
export function changeCompilerHostToUseCache(
208-
host: CompilerHost,
215+
export function changeCompilerHostLikeToUseCache(
216+
host: ComplierHostLikeForCache,
209217
toPath: (fileName: string) => Path,
210-
useCacheForSourceFile: boolean
218+
getSourceFile?: CompilerHost["getSourceFile"]
211219
) {
212220
const originalReadFile = host.readFile;
213221
const originalFileExists = host.fileExists;
214222
const originalDirectoryExists = host.directoryExists;
215223
const originalCreateDirectory = host.createDirectory;
216224
const originalWriteFile = host.writeFile;
217-
const originalGetSourceFile = host.getSourceFile;
218225
const readFileCache = createMap<string | false>();
219226
const fileExistsCache = createMap<boolean>();
220227
const directoryExistsCache = createMap<boolean>();
@@ -242,19 +249,17 @@ namespace ts {
242249
return setReadFileCache(key, fileName);
243250
};
244251

245-
if (useCacheForSourceFile) {
246-
host.getSourceFile = (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {
247-
const key = toPath(fileName);
248-
const value = sourceFileCache.get(key);
249-
if (value) return value;
252+
const getSourceFileWithCache: CompilerHost["getSourceFile"] | undefined = getSourceFile ? (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {
253+
const key = toPath(fileName);
254+
const value = sourceFileCache.get(key);
255+
if (value) return value;
250256

251-
const sourceFile = originalGetSourceFile.call(host, fileName, languageVersion, onError, shouldCreateNewSourceFile);
252-
if (sourceFile && (isDeclarationFileName(fileName) || fileExtensionIs(fileName, Extension.Json))) {
253-
sourceFileCache.set(key, sourceFile);
254-
}
255-
return sourceFile;
256-
};
257-
}
257+
const sourceFile = getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
258+
if (sourceFile && (isDeclarationFileName(fileName) || fileExtensionIs(fileName, Extension.Json))) {
259+
sourceFileCache.set(key, sourceFile);
260+
}
261+
return sourceFile;
262+
} : undefined;
258263

259264
// fileExists for any kind of extension
260265
host.fileExists = fileName => {
@@ -265,23 +270,25 @@ namespace ts {
265270
fileExistsCache.set(key, !!newValue);
266271
return newValue;
267272
};
268-
host.writeFile = (fileName, data, writeByteOrderMark, onError, sourceFiles) => {
269-
const key = toPath(fileName);
270-
fileExistsCache.delete(key);
273+
if (originalWriteFile) {
274+
host.writeFile = (fileName, data, writeByteOrderMark, onError, sourceFiles) => {
275+
const key = toPath(fileName);
276+
fileExistsCache.delete(key);
271277

272-
const value = readFileCache.get(key);
273-
if (value && value !== data) {
274-
readFileCache.delete(key);
275-
sourceFileCache.delete(key);
276-
}
277-
else if (useCacheForSourceFile) {
278-
const sourceFile = sourceFileCache.get(key);
279-
if (sourceFile && sourceFile.text !== data) {
278+
const value = readFileCache.get(key);
279+
if (value && value !== data) {
280+
readFileCache.delete(key);
280281
sourceFileCache.delete(key);
281282
}
282-
}
283-
originalWriteFile.call(host, fileName, data, writeByteOrderMark, onError, sourceFiles);
284-
};
283+
else if (getSourceFileWithCache) {
284+
const sourceFile = sourceFileCache.get(key);
285+
if (sourceFile && sourceFile.text !== data) {
286+
sourceFileCache.delete(key);
287+
}
288+
}
289+
originalWriteFile.call(host, fileName, data, writeByteOrderMark, onError, sourceFiles);
290+
};
291+
}
285292

286293
// directoryExists
287294
if (originalDirectoryExists && originalCreateDirectory) {
@@ -306,7 +313,7 @@ namespace ts {
306313
originalDirectoryExists,
307314
originalCreateDirectory,
308315
originalWriteFile,
309-
originalGetSourceFile,
316+
getSourceFileWithCache,
310317
readFileWithCache
311318
};
312319
}
@@ -735,7 +742,7 @@ namespace ts {
735742
performance.mark("beforeProgram");
736743

737744
const host = createProgramOptions.host || createCompilerHost(options);
738-
const configParsingHost = parseConfigHostFromCompilerHost(host);
745+
const configParsingHost = parseConfigHostFromCompilerHostLike(host);
739746

740747
let skipDefaultLib = options.noLib;
741748
const getDefaultLibraryFileName = memoize(() => host.getDefaultLibFileName(options));
@@ -3101,18 +3108,28 @@ namespace ts {
31013108
}
31023109
}
31033110

3111+
interface CompilerHostLike {
3112+
useCaseSensitiveFileNames(): boolean;
3113+
getCurrentDirectory(): string;
3114+
fileExists(fileName: string): boolean;
3115+
readFile(fileName: string): string | undefined;
3116+
readDirectory?(rootDir: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string> | undefined, includes: ReadonlyArray<string>, depth?: number): string[];
3117+
trace?(s: string): void;
3118+
onUnRecoverableConfigFileDiagnostic?: DiagnosticReporter;
3119+
}
3120+
31043121
/* @internal */
3105-
export function parseConfigHostFromCompilerHost(host: CompilerHost): ParseConfigFileHost {
3122+
export function parseConfigHostFromCompilerHostLike(host: CompilerHostLike, directoryStructureHost: DirectoryStructureHost = host): ParseConfigFileHost {
31063123
return {
31073124
fileExists: f => host.fileExists(f),
31083125
readDirectory(root, extensions, excludes, includes, depth) {
3109-
Debug.assertDefined(host.readDirectory, "'CompilerHost.readDirectory' must be implemented to correctly process 'projectReferences'");
3110-
return host.readDirectory!(root, extensions, excludes, includes, depth);
3126+
Debug.assertDefined(directoryStructureHost.readDirectory, "'CompilerHost.readDirectory' must be implemented to correctly process 'projectReferences'");
3127+
return directoryStructureHost.readDirectory!(root, extensions, excludes, includes, depth);
31113128
},
31123129
readFile: f => host.readFile(f),
31133130
useCaseSensitiveFileNames: host.useCaseSensitiveFileNames(),
31143131
getCurrentDirectory: () => host.getCurrentDirectory(),
3115-
onUnRecoverableConfigFileDiagnostic: () => undefined,
3132+
onUnRecoverableConfigFileDiagnostic: host.onUnRecoverableConfigFileDiagnostic || (() => undefined),
31163133
trace: host.trace ? (s) => host.trace!(s) : undefined
31173134
};
31183135
}

0 commit comments

Comments
 (0)