Ensure getEmitOutput only check the file requested
This commit is contained in:
parent
af324d1226
commit
08165c0b17
|
@ -85,7 +85,6 @@ module ts {
|
||||||
getDiagnostics,
|
getDiagnostics,
|
||||||
getDeclarationDiagnostics,
|
getDeclarationDiagnostics,
|
||||||
getGlobalDiagnostics,
|
getGlobalDiagnostics,
|
||||||
checkProgram,
|
|
||||||
getParentOfSymbol,
|
getParentOfSymbol,
|
||||||
getNarrowedTypeOfSymbol,
|
getNarrowedTypeOfSymbol,
|
||||||
getDeclaredTypeOfSymbol,
|
getDeclaredTypeOfSymbol,
|
||||||
|
@ -8634,10 +8633,6 @@ module ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkProgram() {
|
|
||||||
forEach(program.getSourceFiles(), checkSourceFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSortedDiagnostics(): Diagnostic[]{
|
function getSortedDiagnostics(): Diagnostic[]{
|
||||||
Debug.assert(fullTypeCheck, "diagnostics are available only in the full typecheck mode");
|
Debug.assert(fullTypeCheck, "diagnostics are available only in the full typecheck mode");
|
||||||
|
|
||||||
|
@ -8650,12 +8645,11 @@ module ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDiagnostics(sourceFile?: SourceFile): Diagnostic[]{
|
function getDiagnostics(sourceFile?: SourceFile): Diagnostic[]{
|
||||||
|
|
||||||
if (sourceFile) {
|
if (sourceFile) {
|
||||||
checkSourceFile(sourceFile);
|
checkSourceFile(sourceFile);
|
||||||
return filter(getSortedDiagnostics(), d => d.file === sourceFile);
|
return filter(getSortedDiagnostics(), d => d.file === sourceFile);
|
||||||
}
|
}
|
||||||
checkProgram();
|
forEach(program.getSourceFiles(), checkSourceFile);
|
||||||
return getSortedDiagnostics();
|
return getSortedDiagnostics();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9173,9 +9167,9 @@ module ts {
|
||||||
return isImportResolvedToValue(getSymbolOfNode(node));
|
return isImportResolvedToValue(getSymbolOfNode(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasSemanticErrors() {
|
function hasSemanticErrors(sourceFile?: SourceFile) {
|
||||||
// Return true if there is any semantic error in a file or globally
|
// Return true if there is any semantic error in a file or globally
|
||||||
return getDiagnostics().length > 0 || getGlobalDiagnostics().length > 0;
|
return getDiagnostics(sourceFile).length > 0 || getGlobalDiagnostics().length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isEmitBlocked(sourceFile?: SourceFile): boolean {
|
function isEmitBlocked(sourceFile?: SourceFile): boolean {
|
||||||
|
@ -9293,7 +9287,6 @@ module ts {
|
||||||
|
|
||||||
function invokeEmitter(targetSourceFile?: SourceFile) {
|
function invokeEmitter(targetSourceFile?: SourceFile) {
|
||||||
var resolver = createResolver();
|
var resolver = createResolver();
|
||||||
checkProgram();
|
|
||||||
return emitFiles(resolver, targetSourceFile);
|
return emitFiles(resolver, targetSourceFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3791,20 +3791,14 @@ module ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasSemanticErrors = resolver.hasSemanticErrors();
|
var hasSemanticErrors: boolean = false;
|
||||||
var isEmitBlocked = resolver.isEmitBlocked(targetSourceFile);
|
var isEmitBlocked: boolean = false;
|
||||||
|
|
||||||
function emitFile(jsFilePath: string, sourceFile?: SourceFile) {
|
|
||||||
if (!isEmitBlocked) {
|
|
||||||
emitJavaScript(jsFilePath, sourceFile);
|
|
||||||
if (!hasSemanticErrors && compilerOptions.declaration) {
|
|
||||||
writeDeclarationFile(jsFilePath, sourceFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targetSourceFile === undefined) {
|
if (targetSourceFile === undefined) {
|
||||||
// No targetSourceFile is specified (e.g. calling emitter from batch compiler)
|
// No targetSourceFile is specified (e.g. calling emitter from batch compiler)
|
||||||
|
hasSemanticErrors = resolver.hasSemanticErrors();
|
||||||
|
isEmitBlocked = resolver.isEmitBlocked();
|
||||||
|
|
||||||
forEach(program.getSourceFiles(), sourceFile => {
|
forEach(program.getSourceFiles(), sourceFile => {
|
||||||
if (shouldEmitToOwnFile(sourceFile, compilerOptions)) {
|
if (shouldEmitToOwnFile(sourceFile, compilerOptions)) {
|
||||||
var jsFilePath = getOwnEmitOutputFilePath(sourceFile, program, ".js");
|
var jsFilePath = getOwnEmitOutputFilePath(sourceFile, program, ".js");
|
||||||
|
@ -3820,16 +3814,35 @@ module ts {
|
||||||
// targetSourceFile is specified (e.g calling emitter from language service or calling getSemanticDiagnostic from language service)
|
// targetSourceFile is specified (e.g calling emitter from language service or calling getSemanticDiagnostic from language service)
|
||||||
if (shouldEmitToOwnFile(targetSourceFile, compilerOptions)) {
|
if (shouldEmitToOwnFile(targetSourceFile, compilerOptions)) {
|
||||||
// If shouldEmitToOwnFile returns true or targetSourceFile is an external module file, then emit targetSourceFile in its own output file
|
// If shouldEmitToOwnFile returns true or targetSourceFile is an external module file, then emit targetSourceFile in its own output file
|
||||||
|
hasSemanticErrors = resolver.hasSemanticErrors(targetSourceFile);
|
||||||
|
isEmitBlocked = resolver.isEmitBlocked(targetSourceFile);
|
||||||
|
|
||||||
var jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, program, ".js");
|
var jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, program, ".js");
|
||||||
emitFile(jsFilePath, targetSourceFile);
|
emitFile(jsFilePath, targetSourceFile);
|
||||||
}
|
}
|
||||||
else if (!isDeclarationFile(targetSourceFile) && compilerOptions.out) {
|
else if (!isDeclarationFile(targetSourceFile) && compilerOptions.out) {
|
||||||
// Otherwise, if --out is specified and targetSourceFile is not a declaration file,
|
// Otherwise, if --out is specified and targetSourceFile is not a declaration file,
|
||||||
// Emit all, non-external-module file, into one single output file
|
// Emit all, non-external-module file, into one single output file
|
||||||
|
forEach(program.getSourceFiles(), sourceFile => {
|
||||||
|
if (!shouldEmitToOwnFile(sourceFile, compilerOptions)) {
|
||||||
|
hasSemanticErrors = hasSemanticErrors || resolver.hasSemanticErrors(sourceFile);
|
||||||
|
isEmitBlocked = isEmitBlocked || resolver.isEmitBlocked(sourceFile);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
emitFile(compilerOptions.out);
|
emitFile(compilerOptions.out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function emitFile(jsFilePath: string, sourceFile?: SourceFile) {
|
||||||
|
if (!isEmitBlocked) {
|
||||||
|
emitJavaScript(jsFilePath, sourceFile);
|
||||||
|
if (!hasSemanticErrors && compilerOptions.declaration) {
|
||||||
|
writeDeclarationFile(jsFilePath, sourceFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Sort and make the unique list of diagnostics
|
// Sort and make the unique list of diagnostics
|
||||||
diagnostics.sort(compareDiagnostics);
|
diagnostics.sort(compareDiagnostics);
|
||||||
diagnostics = deduplicateSortedDiagnostics(diagnostics);
|
diagnostics = deduplicateSortedDiagnostics(diagnostics);
|
||||||
|
|
|
@ -861,7 +861,6 @@ module ts {
|
||||||
getIdentifierCount(): number;
|
getIdentifierCount(): number;
|
||||||
getSymbolCount(): number;
|
getSymbolCount(): number;
|
||||||
getTypeCount(): number;
|
getTypeCount(): number;
|
||||||
checkProgram(): void;
|
|
||||||
emitFiles(targetSourceFile?: SourceFile): EmitResult;
|
emitFiles(targetSourceFile?: SourceFile): EmitResult;
|
||||||
getParentOfSymbol(symbol: Symbol): Symbol;
|
getParentOfSymbol(symbol: Symbol): Symbol;
|
||||||
getNarrowedTypeOfSymbol(symbol: Symbol, node: Node): Type;
|
getNarrowedTypeOfSymbol(symbol: Symbol, node: Node): Type;
|
||||||
|
@ -973,7 +972,7 @@ module ts {
|
||||||
isTopLevelValueImportWithEntityName(node: ImportDeclaration): boolean;
|
isTopLevelValueImportWithEntityName(node: ImportDeclaration): boolean;
|
||||||
getNodeCheckFlags(node: Node): NodeCheckFlags;
|
getNodeCheckFlags(node: Node): NodeCheckFlags;
|
||||||
getEnumMemberValue(node: EnumMember): number;
|
getEnumMemberValue(node: EnumMember): number;
|
||||||
hasSemanticErrors(): boolean;
|
hasSemanticErrors(sourceFile?: SourceFile): boolean;
|
||||||
isDeclarationVisible(node: Declaration): boolean;
|
isDeclarationVisible(node: Declaration): boolean;
|
||||||
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean;
|
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean;
|
||||||
writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableOrParameterDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
|
writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableOrParameterDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
|
||||||
|
|
|
@ -2217,11 +2217,10 @@ module FourSlash {
|
||||||
// TODO (drosen): We need to enforce checking on these tests.
|
// TODO (drosen): We need to enforce checking on these tests.
|
||||||
var program = ts.createProgram([Harness.Compiler.fourslashFilename, fileName], { out: "fourslashTestOutput.js", noResolve: true }, host);
|
var program = ts.createProgram([Harness.Compiler.fourslashFilename, fileName], { out: "fourslashTestOutput.js", noResolve: true }, host);
|
||||||
var checker = ts.createTypeChecker(program, /*fullTypeCheckMode*/ true);
|
var checker = ts.createTypeChecker(program, /*fullTypeCheckMode*/ true);
|
||||||
checker.checkProgram();
|
|
||||||
|
|
||||||
var errs = program.getDiagnostics().concat(checker.getDiagnostics());
|
var errors = program.getDiagnostics().concat(checker.getDiagnostics());
|
||||||
if (errs.length > 0) {
|
if (errors.length > 0) {
|
||||||
throw new Error('Error compiling ' + fileName + ': ' + errs.map(e => e.messageText).join('\r\n'));
|
throw new Error('Error compiling ' + fileName + ': ' + errors.map(e => e.messageText).join('\r\n'));
|
||||||
}
|
}
|
||||||
checker.emitFiles();
|
checker.emitFiles();
|
||||||
result = result || ''; // Might have an empty fourslash file
|
result = result || ''; // Might have an empty fourslash file
|
||||||
|
|
|
@ -801,7 +801,6 @@ module Harness {
|
||||||
useCaseSensitiveFileNames));
|
useCaseSensitiveFileNames));
|
||||||
|
|
||||||
var checker = program.getTypeChecker(/*fullTypeCheckMode*/ true);
|
var checker = program.getTypeChecker(/*fullTypeCheckMode*/ true);
|
||||||
checker.checkProgram();
|
|
||||||
|
|
||||||
var isEmitBlocked = checker.isEmitBlocked();
|
var isEmitBlocked = checker.isEmitBlocked();
|
||||||
|
|
||||||
|
|
|
@ -4665,18 +4665,14 @@ module ts {
|
||||||
|
|
||||||
function getEmitOutput(filename: string): EmitOutput {
|
function getEmitOutput(filename: string): EmitOutput {
|
||||||
synchronizeHostData();
|
synchronizeHostData();
|
||||||
|
|
||||||
filename = normalizeSlashes(filename);
|
filename = normalizeSlashes(filename);
|
||||||
var compilerOptions = program.getCompilerOptions();
|
var sourceFile = getSourceFile(filename);
|
||||||
var targetSourceFile = program.getSourceFile(filename); // Current selected file to be output
|
|
||||||
// If --out flag is not specified, shouldEmitToOwnFile is true. Otherwise shouldEmitToOwnFile is false.
|
var outputFiles: OutputFile[] = [];
|
||||||
var shouldEmitToOwnFile = ts.shouldEmitToOwnFile(targetSourceFile, compilerOptions);
|
|
||||||
var emitOutput: EmitOutput = {
|
|
||||||
outputFiles: [],
|
|
||||||
emitOutputStatus: undefined,
|
|
||||||
};
|
|
||||||
|
|
||||||
function getEmitOutputWriter(filename: string, data: string, writeByteOrderMark: boolean) {
|
function getEmitOutputWriter(filename: string, data: string, writeByteOrderMark: boolean) {
|
||||||
emitOutput.outputFiles.push({
|
outputFiles.push({
|
||||||
name: filename,
|
name: filename,
|
||||||
writeByteOrderMark: writeByteOrderMark,
|
writeByteOrderMark: writeByteOrderMark,
|
||||||
text: data
|
text: data
|
||||||
|
@ -4686,41 +4682,15 @@ module ts {
|
||||||
// Initialize writer for CompilerHost.writeFile
|
// Initialize writer for CompilerHost.writeFile
|
||||||
writer = getEmitOutputWriter;
|
writer = getEmitOutputWriter;
|
||||||
|
|
||||||
var containSyntacticErrors = false;
|
var emitOutput = getFullTypeCheckChecker().emitFiles(sourceFile);
|
||||||
|
|
||||||
if (shouldEmitToOwnFile) {
|
|
||||||
// Check only the file we want to emit
|
|
||||||
containSyntacticErrors = containErrors(program.getDiagnostics(targetSourceFile));
|
|
||||||
} else {
|
|
||||||
// Check the syntactic of only sourceFiles that will get emitted into single output
|
|
||||||
// Terminate the process immediately if we encounter a syntax error from one of the sourceFiles
|
|
||||||
containSyntacticErrors = forEach(program.getSourceFiles(), sourceFile => {
|
|
||||||
if (!isExternalModuleOrDeclarationFile(sourceFile)) {
|
|
||||||
// If emit to a single file then we will check all files that do not have external module
|
|
||||||
return containErrors(program.getDiagnostics(sourceFile));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (containSyntacticErrors) {
|
|
||||||
// If there is a syntax error, terminate the process and report outputStatus
|
|
||||||
emitOutput.emitOutputStatus = EmitReturnStatus.AllOutputGenerationSkipped;
|
|
||||||
// Reset writer back to undefined to make sure that we produce an error message
|
|
||||||
// if CompilerHost.writeFile is called when we are not in getEmitOutput
|
|
||||||
writer = undefined;
|
|
||||||
return emitOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform semantic and force a type check before emit to ensure that all symbols are updated
|
|
||||||
// EmitFiles will report if there is an error from TypeChecker and Emitter
|
|
||||||
// Depend whether we will have to emit into a single file or not either emit only selected file in the project, emit all files into a single file
|
|
||||||
var emitFilesResult = getFullTypeCheckChecker().emitFiles(targetSourceFile);
|
|
||||||
emitOutput.emitOutputStatus = emitFilesResult.emitResultStatus;
|
|
||||||
|
|
||||||
// Reset writer back to undefined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in getEmitOutput
|
// Reset writer back to undefined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in getEmitOutput
|
||||||
writer = undefined;
|
writer = undefined;
|
||||||
return emitOutput;
|
|
||||||
|
return {
|
||||||
|
outputFiles,
|
||||||
|
emitOutputStatus: emitOutput.emitResultStatus
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMeaningFromDeclaration(node: Node): SemanticMeaning {
|
function getMeaningFromDeclaration(node: Node): SemanticMeaning {
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
EmitOutputStatus : AllOutputGenerationSkipped
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
EmitOutputStatus : Succeeded
|
||||||
|
Filename : tests/cases/fourslash/inputFile1.js
|
||||||
|
// File to emit, does not contain semantic errors
|
||||||
|
// expected to be emitted correctelly regardless of the semantic errors in the other file
|
||||||
|
var noErrors = true;
|
||||||
|
Filename : tests/cases/fourslash/inputFile1.d.ts
|
||||||
|
declare var noErrors: boolean;
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
EmitOutputStatus : DeclarationGenerationSkipped
|
||||||
|
Filename : out.js
|
||||||
|
// File to emit, does not contain semantic errors, but --out is passed
|
||||||
|
// expected to not generate declarations because of the semantic errors in the other file
|
||||||
|
var noErrors = true;
|
||||||
|
// File not emitted, and contains semantic errors
|
||||||
|
var semanticError = "string";
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
EmitOutputStatus : Succeeded
|
||||||
|
Filename : tests/cases/fourslash/inputFile1.js
|
||||||
|
// File to emit, does not contain syntactic errors
|
||||||
|
// expected to be emitted correctelly regardless of the syntactic errors in the other file
|
||||||
|
var noErrors = true;
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
EmitOutputStatus : AllOutputGenerationSkipped
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
/// <reference path="fourslash.ts" />
|
||||||
|
|
||||||
|
// @BaselineFile: getEmitOutputWithEarlySyntacticErrors.baseline
|
||||||
|
|
||||||
|
// @Filename: inputFile1.ts
|
||||||
|
// @emitThisFile: true
|
||||||
|
//// // File contains early errors. All outputs should be skipped.
|
||||||
|
//// const uninitialized_const_error;
|
||||||
|
|
||||||
|
verify.baselineGetEmitOutput();
|
|
@ -0,0 +1,16 @@
|
||||||
|
/// <reference path="fourslash.ts" />
|
||||||
|
|
||||||
|
// @BaselineFile: getEmitOutputWithSemanticErrorsForMultipleFiles.baseline
|
||||||
|
// @declaration: true
|
||||||
|
|
||||||
|
// @Filename: inputFile1.ts
|
||||||
|
// @emitThisFile: true
|
||||||
|
//// // File to emit, does not contain semantic errors
|
||||||
|
//// // expected to be emitted correctelly regardless of the semantic errors in the other file
|
||||||
|
//// var noErrors = true;
|
||||||
|
|
||||||
|
// @Filename: inputFile2.ts
|
||||||
|
//// // File not emitted, and contains semantic errors
|
||||||
|
//// var semanticError: boolean = "string";
|
||||||
|
|
||||||
|
verify.baselineGetEmitOutput();
|
|
@ -0,0 +1,17 @@
|
||||||
|
/// <reference path="fourslash.ts" />
|
||||||
|
|
||||||
|
// @BaselineFile: getEmitOutputWithSemanticErrorsForMultipleFiles2.baseline
|
||||||
|
// @declaration: true
|
||||||
|
// @out: out.js
|
||||||
|
|
||||||
|
// @Filename: inputFile1.ts
|
||||||
|
// @emitThisFile: true
|
||||||
|
//// // File to emit, does not contain semantic errors, but --out is passed
|
||||||
|
//// // expected to not generate declarations because of the semantic errors in the other file
|
||||||
|
//// var noErrors = true;
|
||||||
|
|
||||||
|
// @Filename: inputFile2.ts
|
||||||
|
//// // File not emitted, and contains semantic errors
|
||||||
|
//// var semanticError: boolean = "string";
|
||||||
|
|
||||||
|
verify.baselineGetEmitOutput();
|
|
@ -0,0 +1,15 @@
|
||||||
|
/// <reference path="fourslash.ts" />
|
||||||
|
|
||||||
|
// @BaselineFile: getEmitOutputWithSyntacticErrorsForMultipleFiles.baseline
|
||||||
|
|
||||||
|
// @Filename: inputFile1.ts
|
||||||
|
// @emitThisFile: true
|
||||||
|
//// // File to emit, does not contain syntactic errors
|
||||||
|
//// // expected to be emitted correctelly regardless of the syntactic errors in the other file
|
||||||
|
//// var noErrors = true;
|
||||||
|
|
||||||
|
// @Filename: inputFile2.ts
|
||||||
|
//// // File not emitted, and contains syntactic errors
|
||||||
|
//// var syntactic Error;
|
||||||
|
|
||||||
|
verify.baselineGetEmitOutput();
|
|
@ -0,0 +1,16 @@
|
||||||
|
/// <reference path="fourslash.ts" />
|
||||||
|
|
||||||
|
// @BaselineFile: getEmitOutputWithSyntacticErrorsForMultipleFiles2.baseline
|
||||||
|
// @out: out.js
|
||||||
|
|
||||||
|
// @Filename: inputFile1.ts
|
||||||
|
// @emitThisFile: true
|
||||||
|
//// // File to emit, does not contain syntactic errors, but --out is passed
|
||||||
|
//// // expected to not generate outputs because of the syntactic errors in the other file.
|
||||||
|
//// var noErrors = true;
|
||||||
|
|
||||||
|
// @Filename: inputFile2.ts
|
||||||
|
//// // File not emitted, and contains syntactic errors
|
||||||
|
//// var syntactic Error;
|
||||||
|
|
||||||
|
verify.baselineGetEmitOutput();
|
Loading…
Reference in a new issue