Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release-3.3] Supports incremental build in tsc --b --w mode #29467

Merged
merged 21 commits into from
Jan 17, 2019
Merged
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
8d2c359
Use watch factory instead of direct host functions in tsbuild to prov…
sheetalkamat Dec 14, 2018
9fcfa28
Make BuilderProgram as Program
sheetalkamat Dec 15, 2018
5d6ecb5
Make SolutionBuilder handle BuilderProgram in preparation to handle i…
sheetalkamat Dec 19, 2018
900dc8c
Revert BuilderProgram to be redirected object to Program in preparati…
sheetalkamat Dec 19, 2018
b6e6b99
Add method to release held Program in BuilderProgram
sheetalkamat Dec 19, 2018
2d712e3
Use oldProgram to create the new Program.
sheetalkamat Dec 19, 2018
6be4439
Use emit builder to emit only changed files.
sheetalkamat Dec 20, 2018
e00df32
Update the timestamps of outputs that dont need to be written because…
sheetalkamat Dec 20, 2018
122339b
Handle prepend in incremental build. Always emit when program uses pr…
sheetalkamat Dec 22, 2018
82f8411
Write the tests for incremental build and declaration emit errors han…
sheetalkamat Dec 26, 2018
75e2e2e
Handle declaration emit errors in tsbuild mode by backing up builder …
sheetalkamat Dec 26, 2018
66018ea
Use DirectoryStructureHost for fileExists and readFile
sheetalkamat Dec 27, 2018
1470a7c
Fix typo
sheetalkamat Jan 10, 2019
19cec03
Rename indexing variable
sheetalkamat Jan 14, 2019
72069a7
CompilerHostLikeForCache rename
sheetalkamat Jan 14, 2019
2b97802
Fix typo
sheetalkamat Jan 14, 2019
dcce3c3
Fix typo
sheetalkamat Jan 14, 2019
0427ad0
PR feedback
sheetalkamat Jan 14, 2019
5a368ae
PR feedback
sheetalkamat Jan 17, 2019
a93b51a
add missing type annotation
sheetalkamat Jan 17, 2019
3921921
renames
sheetalkamat Jan 17, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
PR feedback
sheetalkamat committed Jan 17, 2019

Verified

This commit was signed with the committer’s verified signature.
ssddanbrown Dan Brown
commit 5a368ae31b374d6ffa217fe93d7032452bd40420
24 changes: 14 additions & 10 deletions src/compiler/builder.ts
Original file line number Diff line number Diff line change
@@ -717,22 +717,26 @@ namespace ts {
getState: notImplemented,
backupCurrentState: noop,
useBackupState: noop,
getProgram: () => Debug.assertDefined(state.program),
getProgram,
getProgramOrUndefined: () => state.program,
releaseProgram: () => state.program = undefined,
getCompilerOptions: () => state.compilerOptions,
getSourceFile: fileName => Debug.assertDefined(state.program).getSourceFile(fileName),
getSourceFiles: () => Debug.assertDefined(state.program).getSourceFiles(),
getOptionsDiagnostics: cancellationToken => Debug.assertDefined(state.program).getOptionsDiagnostics(cancellationToken),
getGlobalDiagnostics: cancellationToken => Debug.assertDefined(state.program).getGlobalDiagnostics(cancellationToken),
getSourceFile: fileName => getProgram().getSourceFile(fileName),
getSourceFiles: () => getProgram().getSourceFiles(),
getOptionsDiagnostics: cancellationToken => getProgram().getOptionsDiagnostics(cancellationToken),
getGlobalDiagnostics: cancellationToken => getProgram().getGlobalDiagnostics(cancellationToken),
getConfigFileParsingDiagnostics: () => configFileParsingDiagnostics,
getSyntacticDiagnostics: (sourceFile, cancellationToken) => Debug.assertDefined(state.program).getSyntacticDiagnostics(sourceFile, cancellationToken),
getDeclarationDiagnostics: (sourceFile, cancellationToken) => Debug.assertDefined(state.program).getDeclarationDiagnostics(sourceFile, cancellationToken),
getSemanticDiagnostics: (sourceFile, cancellationToken) => Debug.assertDefined(state.program).getSemanticDiagnostics(sourceFile, cancellationToken),
emit: (sourceFile, writeFile, cancellationToken, emitOnlyDts, customTransformers) => Debug.assertDefined(state.program).emit(sourceFile, writeFile, cancellationToken, emitOnlyDts, customTransformers),
getSyntacticDiagnostics: (sourceFile, cancellationToken) => getProgram().getSyntacticDiagnostics(sourceFile, cancellationToken),
getDeclarationDiagnostics: (sourceFile, cancellationToken) => getProgram().getDeclarationDiagnostics(sourceFile, cancellationToken),
getSemanticDiagnostics: (sourceFile, cancellationToken) => getProgram().getSemanticDiagnostics(sourceFile, cancellationToken),
emit: (sourceFile, writeFile, cancellationToken, emitOnlyDts, customTransformers) => getProgram().emit(sourceFile, writeFile, cancellationToken, emitOnlyDts, customTransformers),
getAllDependencies: notImplemented,
getCurrentDirectory: () => Debug.assertDefined(state.program).getCurrentDirectory()
getCurrentDirectory: () => getProgram().getCurrentDirectory()
};

function getProgram() {
return Debug.assertDefined(state.program);
}
}
}

8 changes: 4 additions & 4 deletions src/compiler/core.ts
Original file line number Diff line number Diff line change
@@ -1370,10 +1370,6 @@ namespace ts {
return result;
}

export function createRedirectObject<T extends object>(redirectTarget: T): T {
return Object.create(redirectTarget);
}

export function extend<T1, T2>(first: T1, second: T2): T1 & T2 {
const result: T1 & T2 = <any>{};
for (const id in second) {
@@ -1399,6 +1395,10 @@ namespace ts {
}
}

export function maybeBind<T, A extends any[], R>(obj: T, fn: ((this: T, ...args: A) => R) | undefined): ((...args: A) => R) | undefined {
return fn ? fn.bind(obj) : undefined;
}

export interface MultiMap<T> extends Map<T[]> {
/**
* Adds the value to an array of values associated with the key, and returns the array.
2 changes: 1 addition & 1 deletion src/compiler/program.ts
Original file line number Diff line number Diff line change
@@ -2187,7 +2187,7 @@ namespace ts {
}

function createRedirectSourceFile(redirectTarget: SourceFile, unredirected: SourceFile, fileName: string, path: Path, resolvedPath: Path, originalFileName: string): SourceFile {
const redirect = createRedirectObject(redirectTarget);
const redirect = Object.create(redirectTarget);
redirect.fileName = fileName;
redirect.path = path;
redirect.resolvedPath = resolvedPath;
8 changes: 4 additions & 4 deletions src/compiler/tsbuild.ts
Original file line number Diff line number Diff line change
@@ -447,7 +447,7 @@ namespace ts {
let nextProjectToBuild = 0;
let timerToBuildInvalidatedProject: any;
let reportFileChangeDetected = false;
const { watchFile, watchFilePath, watchDirectory } = createWatchFactory<ResolvedConfigFileName>(host, options);
const { watchFile, watchFilePath, watchDirectory, writeLog } = createWatchFactory<ResolvedConfigFileName>(host, options);

// Watches for the solution
const allWatchedWildcardDirectories = createFileMap<Map<WildcardDirectoryWatcher>>(toPath);
@@ -593,12 +593,12 @@ namespace ts {
fileOrDirectory => {
const fileOrDirectoryPath = toPath(fileOrDirectory);
if (fileOrDirectoryPath !== toPath(dir) && hasExtension(fileOrDirectoryPath) && !isSupportedSourceFileName(fileOrDirectory, parsed.options)) {
// writeLog(`Project: ${configFileName} Detected file add/remove of non supported extension: ${fileOrDirectory}`);
writeLog(`Project: ${resolved} Detected file add/remove of non supported extension: ${fileOrDirectory}`);
return;
}

if (isOutputFile(fileOrDirectory, parsed)) {
// writeLog(`${fileOrDirectory} is output file`);
writeLog(`${fileOrDirectory} is output file`);
return;
}

@@ -991,7 +991,7 @@ namespace ts {
}

if (status.type === UpToDateStatusType.UpToDateWithUpstreamTypes) {
// Fake build
// Fake that files have been built by updating output file stamps
updateOutputTimestamps(proj);
return;
}
1 change: 0 additions & 1 deletion src/compiler/types.ts
Original file line number Diff line number Diff line change
@@ -5002,7 +5002,6 @@ namespace ts {
getDefaultLibLocation?(): string;
writeFile: WriteFileCallback;
getCurrentDirectory(): string;
getDirectories(path: string): string[];
getCanonicalFileName(fileName: string): string;
useCaseSensitiveFileNames(): boolean;
getNewLine(): string;
35 changes: 18 additions & 17 deletions src/compiler/watch.ts
Original file line number Diff line number Diff line change
@@ -187,10 +187,10 @@ namespace ts {
const onWatchStatusChange = reportWatchStatus || createWatchStatusReporter(system);
return {
onWatchStatusChange,
watchFile: system.watchFile ? ((path, callback, pollingInterval) => system.watchFile!(path, callback, pollingInterval)) : () => noopFileWatcher,
watchDirectory: system.watchDirectory ? ((path, callback, recursive) => system.watchDirectory!(path, callback, recursive)) : () => noopFileWatcher,
setTimeout: system.setTimeout ? ((callback, ms, ...args: any[]) => system.setTimeout!.call(system, callback, ms, ...args)) : noop,
clearTimeout: system.clearTimeout ? (timeoutId => system.clearTimeout!(timeoutId)) : noop
watchFile: maybeBind(system, system.watchFile) || (() => noopFileWatcher),
watchDirectory: maybeBind(system, system.watchDirectory) || (() => noopFileWatcher),
setTimeout: maybeBind(system, system.setTimeout) || noop,
clearTimeout: maybeBind(system, system.clearTimeout) || noop
};
}

@@ -217,6 +217,7 @@ namespace ts {

export function createCompilerHostFromProgramHost(host: ProgramHost<any>, getCompilerOptions: () => CompilerOptions, directoryStructureHost: DirectoryStructureHost = host): CompilerHost {
const useCaseSensitiveFileNames = host.useCaseSensitiveFileNames();
const hostGetNewLine = memoize(() => host.getNewLine());
return {
getSourceFile: (fileName, languageVersion, onError) => {
let text: string | undefined;
@@ -235,22 +236,22 @@ namespace ts {

return text !== undefined ? createSourceFile(fileName, text, languageVersion) : undefined;
},
getDefaultLibLocation: host.getDefaultLibLocation && (() => host.getDefaultLibLocation!()),
getDefaultLibLocation: maybeBind(host, host.getDefaultLibLocation),
getDefaultLibFileName: options => host.getDefaultLibFileName(options),
writeFile,
getCurrentDirectory: memoize(() => host.getCurrentDirectory()),
useCaseSensitiveFileNames: () => useCaseSensitiveFileNames,
getCanonicalFileName: createGetCanonicalFileName(useCaseSensitiveFileNames),
getNewLine: memoize(() => getNewLineCharacter(getCompilerOptions(), () => host.getNewLine())),
getNewLine: () => getNewLineCharacter(getCompilerOptions(), hostGetNewLine),
fileExists: f => host.fileExists(f),
readFile: f => host.readFile(f),
trace: host.trace && (s => host.trace!(s)),
directoryExists: directoryStructureHost.directoryExists && (path => directoryStructureHost.directoryExists!(path)),
getDirectories: (directoryStructureHost.getDirectories && ((path: string) => directoryStructureHost.getDirectories!(path)))!, // TODO: GH#18217
realpath: host.realpath && (s => host.realpath!(s)),
getEnvironmentVariable: host.getEnvironmentVariable ? (name => host.getEnvironmentVariable!(name)) : (() => ""),
createHash: host.createHash && (data => host.createHash!(data)),
readDirectory: (path, extensions, exclude, include, depth?) => directoryStructureHost.readDirectory!(path, extensions, exclude, include, depth),
trace: maybeBind(host, host.trace),
directoryExists: maybeBind(directoryStructureHost, directoryStructureHost.directoryExists),
getDirectories: maybeBind(directoryStructureHost, directoryStructureHost.getDirectories),
realpath: maybeBind(host, host.realpath),
getEnvironmentVariable: maybeBind(host, host.getEnvironmentVariable) || (() => ""),
createHash: maybeBind(host, host.createHash),
readDirectory: maybeBind(host, host.readDirectory),
};

function ensureDirectoriesExist(directoryPath: string) {
@@ -297,13 +298,13 @@ namespace ts {
directoryExists: path => system.directoryExists(path),
getDirectories: path => system.getDirectories(path),
readDirectory: (path, extensions, exclude, include, depth) => system.readDirectory(path, extensions, exclude, include, depth),
realpath: system.realpath && (path => system.realpath!(path)),
getEnvironmentVariable: system.getEnvironmentVariable && (name => system.getEnvironmentVariable(name)),
realpath: maybeBind(system, system.realpath),
getEnvironmentVariable: maybeBind(system, system.getEnvironmentVariable),
trace: s => system.write(s + system.newLine),
createDirectory: path => system.createDirectory(path),
writeFile: (path, data, writeByteOrderMark) => system.writeFile(path, data, writeByteOrderMark),
onCachedDirectoryStructureHostCreate: cacheHost => host = cacheHost || system,
createHash: system.createHash && (s => system.createHash!(s)),
createHash: maybeBind(system, system.createHash),
createProgram
};
}
@@ -758,7 +759,7 @@ namespace ts {

// Create new source file if requested or the versions dont match
if (!hostSourceFile || shouldCreateNewSourceFile || !isFilePresentOnHost(hostSourceFile) || hostSourceFile.version.toString() !== hostSourceFile.sourceFile.version) {
const sourceFile = getNewSourceFile.call(compilerHost, fileName, languageVersion, onError);
const sourceFile = getNewSourceFile(fileName, languageVersion, onError);
if (hostSourceFile) {
if (shouldCreateNewSourceFile) {
hostSourceFile.version++;
1 change: 0 additions & 1 deletion tests/baselines/reference/api/tsserverlibrary.d.ts
Original file line number Diff line number Diff line change
@@ -2689,7 +2689,6 @@ declare namespace ts {
getDefaultLibLocation?(): string;
writeFile: WriteFileCallback;
getCurrentDirectory(): string;
getDirectories(path: string): string[];
getCanonicalFileName(fileName: string): string;
useCaseSensitiveFileNames(): boolean;
getNewLine(): string;
1 change: 0 additions & 1 deletion tests/baselines/reference/api/typescript.d.ts
Original file line number Diff line number Diff line change
@@ -2689,7 +2689,6 @@ declare namespace ts {
getDefaultLibLocation?(): string;
writeFile: WriteFileCallback;
getCurrentDirectory(): string;
getDirectories(path: string): string[];
getCanonicalFileName(fileName: string): string;
useCaseSensitiveFileNames(): boolean;
getNewLine(): string;