Simplify the API for emitting code from the Program instance.

This commit is contained in:
Cyrus Najmabadi
2015-02-04 16:53:14 -08:00
parent b6d083fa40
commit bb307f8163
19 changed files with 263 additions and 152 deletions

View File

@@ -1504,8 +1504,9 @@ module ts {
return diagnostics;
}
// @internal
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compilerOnSave feature
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile?: SourceFile): EmitResult {
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile): EmitResult {
var compilerOptions = host.getCompilerOptions();
var languageVersion = compilerOptions.target || ScriptTarget.ES3;
var sourceMapDataList: SourceMapData[] = compilerOptions.sourceMap ? [] : undefined;

View File

@@ -90,7 +90,6 @@ module ts {
var diagnosticsProducingTypeChecker: TypeChecker;
var noDiagnosticsTypeChecker: TypeChecker;
var emitHost: EmitHost;
program = {
getSourceFile: getSourceFile,
@@ -105,7 +104,7 @@ module ts {
getTypeChecker,
getDiagnosticsProducingTypeChecker,
getCommonSourceDirectory: () => commonSourceDirectory,
emitFiles: invokeEmitter,
emit,
isEmitBlocked,
getCurrentDirectory: host.getCurrentDirectory,
getEmitResolver: () => getDiagnosticsProducingTypeChecker().getEmitResolver(),
@@ -116,10 +115,22 @@ module ts {
};
return program;
function getEmitHost() {
return emitHost || (emitHost = createEmitHostFromProgram(program));
function getEmitHost(writeFileCallback?: WriteFileCallback) {
var compilerHost = program.getCompilerHost();
return {
getCanonicalFileName: compilerHost.getCanonicalFileName,
getCommonSourceDirectory: program.getCommonSourceDirectory,
getCompilerOptions: program.getCompilerOptions,
getCurrentDirectory: compilerHost.getCurrentDirectory,
getNewLine: compilerHost.getNewLine,
getSourceFile: program.getSourceFile,
getSourceFiles: program.getSourceFiles,
isEmitBlocked: program.isEmitBlocked,
writeFile: writeFileCallback || compilerHost.writeFile,
};
}
function isEmitBlocked(sourceFile?: SourceFile): boolean {
if (options.noEmitOnError) {
return getDiagnostics(sourceFile).length !== 0 || getTypeCheckerDiagnostics(sourceFile).length !== 0;
@@ -143,9 +154,10 @@ module ts {
return ts.getDeclarationDiagnostics(getEmitHost(), resolver, targetSourceFile);
}
function invokeEmitter(targetSourceFile?: SourceFile) {
function emit(targetSourceFile?: SourceFile, writeFileCallback?: WriteFileCallback) {
var resolver = getDiagnosticsProducingTypeChecker().getEmitResolver();
return emitFiles(resolver, getEmitHost(), targetSourceFile);
var host = getEmitHost(writeFileCallback);
return emitFiles(resolver, host, targetSourceFile);
}
function getSourceFile(fileName: string) {

View File

@@ -346,7 +346,7 @@ module ts {
}
else {
var emitStart = new Date().getTime();
var emitOutput = program.emitFiles();
var emitOutput = program.emit();
var emitErrors = emitOutput.diagnostics;
exitStatus = emitOutput.emitResultStatus;
var reportStart = new Date().getTime();

View File

@@ -927,10 +927,27 @@ module ts {
getCurrentDirectory(): string;
}
export interface WriteFileCallback {
(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void): void;
}
export interface Program extends ScriptReferenceHost {
getSourceFiles(): SourceFile[];
getCompilerHost(): CompilerHost;
getEmitResolver(): EmitResolver;
/**
* Emits the javascript and declaration files. If targetSourceFile is not specified, then
* the javascript and declaration files will be produced for all the files in this program.
* If targetSourceFile is specified, then only the javascript and declaration for that
* specific file will be generated.
*
* If writeFile is not specified then the writeFile callback from getCompilerHost() will be
* used for writing the javascript and declaration files. Otherwise, the writeFile parameter
* will be invoked when writing the javascript and declaration files.
*/
emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback): EmitResult;
isEmitBlocked(sourceFile?: SourceFile): boolean;
// These will merge with the below diagnostics function in a followup checkin.
getTypeCheckerDiagnostics(sourceFile?: SourceFile): Diagnostic[];
@@ -951,9 +968,6 @@ module ts {
getTypeChecker(): TypeChecker;
getCommonSourceDirectory(): string;
emitFiles(targetSourceFile?: SourceFile): EmitResult;
isEmitBlocked(sourceFile?: SourceFile): boolean;
// For testing purposes only. Should not be used by any other consumers (including the
// language service).
/* @internal */ getDiagnosticsProducingTypeChecker(): TypeChecker;
@@ -1671,7 +1685,7 @@ module ts {
getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile;
getDefaultLibFileName(options: CompilerOptions): string;
getCancellationToken? (): CancellationToken;
writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void): void;
writeFile: WriteFileCallback;
getCurrentDirectory(): string;
getCanonicalFileName(fileName: string): string;
useCaseSensitiveFileNames(): boolean;

View File

@@ -31,7 +31,7 @@ module ts {
getCanonicalFileName(fileName: string): string;
getNewLine(): string;
writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void): void;
writeFile: WriteFileCallback;
}
// Pool writers to avoid needing to allocate them for every symbol we write.
@@ -843,21 +843,6 @@ module ts {
return false;
}
export function createEmitHostFromProgram(program: Program): EmitHost {
var compilerHost = program.getCompilerHost();
return {
getCanonicalFileName: compilerHost.getCanonicalFileName,
getCommonSourceDirectory: program.getCommonSourceDirectory,
getCompilerOptions: program.getCompilerOptions,
getCurrentDirectory: compilerHost.getCurrentDirectory,
getNewLine: compilerHost.getNewLine,
getSourceFile: program.getSourceFile,
getSourceFiles: program.getSourceFiles,
isEmitBlocked: program.isEmitBlocked,
writeFile: compilerHost.writeFile,
};
}
export function textSpanEnd(span: TextSpan) {
return span.start + span.length
}