Skip to content

Commit

Permalink
Merge pull request #497 from ivogabe/perf
Browse files Browse the repository at this point in the history
Fix performance issues
  • Loading branch information
ivogabe authored Mar 16, 2017
2 parents 161c806 + 489f54c commit cfdd86a
Showing 1 changed file with 70 additions and 43 deletions.
113 changes: 70 additions & 43 deletions lib/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ export interface ICompiler {
inputDone(): void;
}

interface OutputFile {
file: File | undefined;

jsFileName?: string;
dtsFileName?: string;
jsContent?: string;
jsMapContent?: string;
dtsContent?: string;
}

/**
* Compiles a whole project, with full type checking
*/
Expand Down Expand Up @@ -61,69 +71,85 @@ export class ProjectCompiler implements ICompiler {
);

this.program = this.project.typescript.createProgram(rootFilenames, this.project.options, this.host, this.program);
const preEmitDiagnostics = this.project.typescript.getPreEmitDiagnostics(this.program);


const result = emptyCompilationResult();
result.optionsErrors = this.program.getOptionsDiagnostics().length;
result.syntaxErrors = this.program.getSyntacticDiagnostics().length;
result.globalErrors = this.program.getGlobalDiagnostics().length;
result.semanticErrors = this.program.getSemanticDiagnostics().length;
result.optionsErrors = this.reportDiagnostics(this.program.getOptionsDiagnostics());
result.syntaxErrors = this.reportDiagnostics(this.program.getSyntacticDiagnostics());
result.globalErrors = this.reportDiagnostics(this.program.getGlobalDiagnostics());
result.semanticErrors = this.reportDiagnostics(this.program.getSemanticDiagnostics());
if (this.project.options.declaration) {
result.declarationErrors = this.program.getDeclarationDiagnostics().length;
}

this.reportDiagnostics(preEmitDiagnostics);
if (this.project.singleOutput) {
const output: OutputFile = {
file: undefined
};

const emitOutput = this.program.emit();
result.emitErrors = emitOutput.diagnostics.length;
result.emitSkipped = emitOutput.emitSkipped;
this.emit(result, (fileName, content) => {
this.attachContentToFile(output, fileName, content);
});

if (this.project.singleOutput) {
this.emitFile(result, currentDirectory);
this.emitFile(output, currentDirectory);
} else {
// Emit files one by one
for (const fileName of this.host.input.getFileNames(true)) {
const output: utils.Map<OutputFile> = {};

const input = this.host.input.getFileNames(true);

for (let i = 0; i < input.length; i++) {
const fileName = utils.normalizePath(input[i]);
const file = this.project.input.getFile(fileName);

this.emitFile(result, currentDirectory, file);
output[fileName] = { file };
}

this.emit(result, (fileName, content, writeByteOrderMark, onError, sourceFiles) => {
if (sourceFiles.length !== 1) {
throw new Error("Failure: sourceFiles in WriteFileCallback should have length 1, got " + sourceFiles.length);
}

const fileNameOriginal = utils.normalizePath(sourceFiles[0].fileName);
const file = output[fileNameOriginal];
if (!file) return;

this.attachContentToFile(file, fileName, content);
});

for (let i = 0; i < input.length; i++) {
const fileName = utils.normalizePath(input[i]);
this.emitFile(output[fileName], currentDirectory);
}
}

this.project.output.finish(result);
}

private emitFile(result: CompilationResult, currentDirectory: string, file?: File) {
let jsFileName: string;
let dtsFileName: string;
let jsContent: string;
let dtsContent: string;
let jsMapContent: string;

const emitOutput = this.program.emit(file && file.ts, (fileName: string, content: string) => {
const [, extension] = utils.splitExtension(fileName, ['d.ts']);
switch (extension) {
case 'js':
case 'jsx':
jsFileName = fileName;
jsContent = content;
break;
case 'd.ts':
dtsFileName = fileName;
dtsContent = content;
break;
case 'map':
jsMapContent = content;
break;
}
});
private attachContentToFile(file: OutputFile, fileName: string, content: string) {
const [, extension] = utils.splitExtension(fileName, ['d.ts']);
switch (extension) {
case 'js':
case 'jsx':
file.jsFileName = fileName;
file.jsContent = content;
break;
case 'd.ts':
file.dtsFileName = fileName;
file.dtsContent = content;
break;
case 'map':
file.jsMapContent = content;
break;
}
}
private emit(result: CompilationResult, callback: ts.WriteFileCallback) {
const emitOutput = this.program.emit(undefined, callback);

result.emitErrors += emitOutput.diagnostics.length;
this.reportDiagnostics(emitOutput.diagnostics);

if (emitOutput.emitSkipped) {
result.emitSkipped = true;
}

result.emitSkipped = emitOutput.emitSkipped;
}
private emitFile({ file, jsFileName, dtsFileName, jsContent, dtsContent, jsMapContent }: OutputFile, currentDirectory: string) {
if (!jsFileName) return;

let base: string;
Expand Down Expand Up @@ -163,6 +189,7 @@ export class ProjectCompiler implements ICompiler {
for (const error of diagnostics) {
this.project.output.diagnostic(error);
}
return diagnostics.length;
}

private removeSourceMapComment(content: string): string {
Expand Down

0 comments on commit cfdd86a

Please sign in to comment.