Ensure getEmitOutput only check the file requested
This commit is contained in:
parent
af324d1226
commit
08165c0b17
|
@ -85,7 +85,6 @@ module ts {
|
|||
getDiagnostics,
|
||||
getDeclarationDiagnostics,
|
||||
getGlobalDiagnostics,
|
||||
checkProgram,
|
||||
getParentOfSymbol,
|
||||
getNarrowedTypeOfSymbol,
|
||||
getDeclaredTypeOfSymbol,
|
||||
|
@ -8634,10 +8633,6 @@ module ts {
|
|||
}
|
||||
}
|
||||
|
||||
function checkProgram() {
|
||||
forEach(program.getSourceFiles(), checkSourceFile);
|
||||
}
|
||||
|
||||
function getSortedDiagnostics(): Diagnostic[]{
|
||||
Debug.assert(fullTypeCheck, "diagnostics are available only in the full typecheck mode");
|
||||
|
||||
|
@ -8650,12 +8645,11 @@ module ts {
|
|||
}
|
||||
|
||||
function getDiagnostics(sourceFile?: SourceFile): Diagnostic[]{
|
||||
|
||||
if (sourceFile) {
|
||||
checkSourceFile(sourceFile);
|
||||
return filter(getSortedDiagnostics(), d => d.file === sourceFile);
|
||||
}
|
||||
checkProgram();
|
||||
forEach(program.getSourceFiles(), checkSourceFile);
|
||||
return getSortedDiagnostics();
|
||||
}
|
||||
|
||||
|
@ -9173,9 +9167,9 @@ module ts {
|
|||
return isImportResolvedToValue(getSymbolOfNode(node));
|
||||
}
|
||||
|
||||
function hasSemanticErrors() {
|
||||
function hasSemanticErrors(sourceFile?: SourceFile) {
|
||||
// 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 {
|
||||
|
@ -9293,7 +9287,6 @@ module ts {
|
|||
|
||||
function invokeEmitter(targetSourceFile?: SourceFile) {
|
||||
var resolver = createResolver();
|
||||
checkProgram();
|
||||
return emitFiles(resolver, targetSourceFile);
|
||||
}
|
||||
|
||||
|
|
|
@ -3791,20 +3791,14 @@ module ts {
|
|||
}
|
||||
}
|
||||
|
||||
var hasSemanticErrors = resolver.hasSemanticErrors();
|
||||
var isEmitBlocked = resolver.isEmitBlocked(targetSourceFile);
|
||||
|
||||
function emitFile(jsFilePath: string, sourceFile?: SourceFile) {
|
||||
if (!isEmitBlocked) {
|
||||
emitJavaScript(jsFilePath, sourceFile);
|
||||
if (!hasSemanticErrors && compilerOptions.declaration) {
|
||||
writeDeclarationFile(jsFilePath, sourceFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
var hasSemanticErrors: boolean = false;
|
||||
var isEmitBlocked: boolean = false;
|
||||
|
||||
if (targetSourceFile === undefined) {
|
||||
// No targetSourceFile is specified (e.g. calling emitter from batch compiler)
|
||||
hasSemanticErrors = resolver.hasSemanticErrors();
|
||||
isEmitBlocked = resolver.isEmitBlocked();
|
||||
|
||||
forEach(program.getSourceFiles(), sourceFile => {
|
||||
if (shouldEmitToOwnFile(sourceFile, compilerOptions)) {
|
||||
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)
|
||||
if (shouldEmitToOwnFile(targetSourceFile, compilerOptions)) {
|
||||
// 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");
|
||||
emitFile(jsFilePath, targetSourceFile);
|
||||
}
|
||||
else if (!isDeclarationFile(targetSourceFile) && compilerOptions.out) {
|
||||
// Otherwise, if --out is specified and targetSourceFile is not a declaration 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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
diagnostics.sort(compareDiagnostics);
|
||||
diagnostics = deduplicateSortedDiagnostics(diagnostics);
|
||||
|
|
|
@ -861,7 +861,6 @@ module ts {
|
|||
getIdentifierCount(): number;
|
||||
getSymbolCount(): number;
|
||||
getTypeCount(): number;
|
||||
checkProgram(): void;
|
||||
emitFiles(targetSourceFile?: SourceFile): EmitResult;
|
||||
getParentOfSymbol(symbol: Symbol): Symbol;
|
||||
getNarrowedTypeOfSymbol(symbol: Symbol, node: Node): Type;
|
||||
|
@ -973,7 +972,7 @@ module ts {
|
|||
isTopLevelValueImportWithEntityName(node: ImportDeclaration): boolean;
|
||||
getNodeCheckFlags(node: Node): NodeCheckFlags;
|
||||
getEnumMemberValue(node: EnumMember): number;
|
||||
hasSemanticErrors(): boolean;
|
||||
hasSemanticErrors(sourceFile?: SourceFile): boolean;
|
||||
isDeclarationVisible(node: Declaration): boolean;
|
||||
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean;
|
||||
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.
|
||||
var program = ts.createProgram([Harness.Compiler.fourslashFilename, fileName], { out: "fourslashTestOutput.js", noResolve: true }, host);
|
||||
var checker = ts.createTypeChecker(program, /*fullTypeCheckMode*/ true);
|
||||
checker.checkProgram();
|
||||
|
||||
var errs = program.getDiagnostics().concat(checker.getDiagnostics());
|
||||
if (errs.length > 0) {
|
||||
throw new Error('Error compiling ' + fileName + ': ' + errs.map(e => e.messageText).join('\r\n'));
|
||||
var errors = program.getDiagnostics().concat(checker.getDiagnostics());
|
||||
if (errors.length > 0) {
|
||||
throw new Error('Error compiling ' + fileName + ': ' + errors.map(e => e.messageText).join('\r\n'));
|
||||
}
|
||||
checker.emitFiles();
|
||||
result = result || ''; // Might have an empty fourslash file
|
||||
|
|
|
@ -801,7 +801,6 @@ module Harness {
|
|||
useCaseSensitiveFileNames));
|
||||
|
||||
var checker = program.getTypeChecker(/*fullTypeCheckMode*/ true);
|
||||
checker.checkProgram();
|
||||
|
||||
var isEmitBlocked = checker.isEmitBlocked();
|
||||
|
||||
|
|
|
@ -4665,18 +4665,14 @@ module ts {
|
|||
|
||||
function getEmitOutput(filename: string): EmitOutput {
|
||||
synchronizeHostData();
|
||||
|
||||
filename = normalizeSlashes(filename);
|
||||
var compilerOptions = program.getCompilerOptions();
|
||||
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 shouldEmitToOwnFile = ts.shouldEmitToOwnFile(targetSourceFile, compilerOptions);
|
||||
var emitOutput: EmitOutput = {
|
||||
outputFiles: [],
|
||||
emitOutputStatus: undefined,
|
||||
};
|
||||
var sourceFile = getSourceFile(filename);
|
||||
|
||||
var outputFiles: OutputFile[] = [];
|
||||
|
||||
function getEmitOutputWriter(filename: string, data: string, writeByteOrderMark: boolean) {
|
||||
emitOutput.outputFiles.push({
|
||||
outputFiles.push({
|
||||
name: filename,
|
||||
writeByteOrderMark: writeByteOrderMark,
|
||||
text: data
|
||||
|
@ -4686,41 +4682,15 @@ module ts {
|
|||
// Initialize writer for CompilerHost.writeFile
|
||||
writer = getEmitOutputWriter;
|
||||
|
||||
var containSyntacticErrors = false;
|
||||
|
||||
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;
|
||||
var emitOutput = getFullTypeCheckChecker().emitFiles(sourceFile);
|
||||
|
||||
// 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;
|
||||
return emitOutput;
|
||||
|
||||
return {
|
||||
outputFiles,
|
||||
emitOutputStatus: emitOutput.emitResultStatus
|
||||
};
|
||||
}
|
||||
|
||||
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