mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Move checking semantic diagnostics into emitFiles function rather than
getEmitOutput
This commit is contained in:
@@ -7181,6 +7181,11 @@ module ts {
|
||||
return target !== unknownSymbol && ((target.flags & SymbolFlags.Value) !== 0);
|
||||
}
|
||||
|
||||
function hasSemanticErrors() {
|
||||
// Return true if there is any semantic error in a file or globally
|
||||
return (getDiagnostics().length > 0) || (getGlobalDiagnostics().length > 0);
|
||||
}
|
||||
|
||||
function shouldEmitDeclarations() {
|
||||
// If the declaration emit and there are no errors being reported in program or by checker
|
||||
// declarations can be emitted
|
||||
@@ -7258,6 +7263,7 @@ module ts {
|
||||
getNodeCheckFlags: getNodeCheckFlags,
|
||||
getEnumMemberValue: getEnumMemberValue,
|
||||
isTopLevelValueImportedViaEntityName: isTopLevelValueImportedViaEntityName,
|
||||
hasSemanticErrors: hasSemanticErrors,
|
||||
shouldEmitDeclarations: shouldEmitDeclarations,
|
||||
isDeclarationVisible: isDeclarationVisible,
|
||||
isImplementationOfOverload: isImplementationOfOverload,
|
||||
|
||||
+22
-2
@@ -48,8 +48,8 @@ module ts {
|
||||
}
|
||||
|
||||
function getOwnEmitOutputFilePath(sourceFile: SourceFile, extension: string) {
|
||||
if (program.getCompilerOptions().outDir) {
|
||||
var emitOutputFilePathWithoutExtension = getModuleNameFromFilename(getSourceFilePathInNewDir(program.getCompilerOptions().outDir, sourceFile));
|
||||
if (compilerOptions.outDir) {
|
||||
var emitOutputFilePathWithoutExtension = getModuleNameFromFilename(getSourceFilePathInNewDir(compilerOptions.outDir, sourceFile));
|
||||
}
|
||||
else {
|
||||
var emitOutputFilePathWithoutExtension = getModuleNameFromFilename(sourceFile.filename);
|
||||
@@ -3183,7 +3183,27 @@ module ts {
|
||||
diagnostics.sort(compareDiagnostics);
|
||||
diagnostics = deduplicateSortedDiagnostics(diagnostics);
|
||||
|
||||
var returnCode = EmitReturnStatus.Succeeded;
|
||||
|
||||
// Check if there is any diagnostic in an error category; if so, there is an emitter error
|
||||
var hasEmitterError = forEach(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error);
|
||||
|
||||
if (resolver.hasSemanticErrors() && !compilerOptions.declaration) {
|
||||
// There is an semantic errror when output javascript file
|
||||
// Output JS file with semantic error
|
||||
returnCode = EmitReturnStatus.JSGeneratedWithSemanticErrors;
|
||||
}
|
||||
else if (resolver.hasSemanticErrors() && compilerOptions.declaration) {
|
||||
// There is an semantic errror when output javascript and declaration file
|
||||
// Output JS file with semantic error, not output declaration file
|
||||
returnCode = EmitReturnStatus.DeclarationGenerationSkipped;
|
||||
}
|
||||
else if (hasEmitterError) {
|
||||
returnCode = EmitReturnStatus.EmitErrorsEncountered;
|
||||
}
|
||||
|
||||
return {
|
||||
emitResultStatus: returnCode,
|
||||
errors: diagnostics,
|
||||
sourceMaps: sourceMapDataList
|
||||
};
|
||||
|
||||
@@ -588,7 +588,17 @@ module ts {
|
||||
sourceMapDecodedMappings: SourceMapSpan[];
|
||||
}
|
||||
|
||||
// Return code used by getEmitOutput function to indicate status of the function
|
||||
export enum EmitReturnStatus {
|
||||
Succeeded = 0, // All outputs generated as requested (.js, .map, .d.ts), no errors reported
|
||||
AllOutputGenerationSkipped = 1, // No .js generated because of syntax errors, or compiler options errors, nothing generated
|
||||
JSGeneratedWithSemanticErrors = 2, // .js and .map generated with semantic errors
|
||||
DeclarationGenerationSkipped = 3, // .d.ts generation skipped because of semantic errors or declaration emitter specific errors; Output .js with semantic errors
|
||||
EmitErrorsEncountered = 4 // Emitter errors occured during emitting process
|
||||
}
|
||||
|
||||
export interface EmitResult {
|
||||
emitResultStatus: EmitReturnStatus;
|
||||
errors: Diagnostic[];
|
||||
sourceMaps: SourceMapData[]; // Array of sourceMapData if compiler emitted sourcemaps
|
||||
}
|
||||
@@ -660,6 +670,7 @@ module ts {
|
||||
isTopLevelValueImportedViaEntityName(node: ImportDeclaration): boolean;
|
||||
getNodeCheckFlags(node: Node): NodeCheckFlags;
|
||||
getEnumMemberValue(node: EnumMember): number;
|
||||
hasSemanticErrors(): boolean;
|
||||
shouldEmitDeclarations(): boolean;
|
||||
isDeclarationVisible(node: Declaration): boolean;
|
||||
isImplementationOfOverload(node: FunctionDeclaration): boolean;
|
||||
|
||||
@@ -458,7 +458,7 @@ module FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public verifyEmitOutput(state: ts.EmitOutputResult, filename?: string) {
|
||||
public verifyEmitOutput(state: ts.EmitReturnStatus, filename?: string) {
|
||||
if (this.enableDeclaration) {
|
||||
this.languageServiceShimHost.setCompilationSettings({ generateDeclarationFiles: true });
|
||||
}
|
||||
@@ -474,8 +474,8 @@ module FourSlash {
|
||||
|
||||
var emit = this.languageService.getEmitOutput(this.activeFile.fileName);
|
||||
|
||||
if (emit.emitOutputResult !== state) {
|
||||
throw new Error("Expected emitOutputResult '" + state + "', but actual emitOutputResult '" + emit.emitOutputResult + "'");
|
||||
if (emit.emitOutputStatus !== state) {
|
||||
throw new Error("Expected emitOutputResult '" + state + "', but actual emitOutputResult '" + emit.emitOutputStatus + "'");
|
||||
}
|
||||
|
||||
var passed = true;
|
||||
|
||||
+15
-35
@@ -663,16 +663,9 @@ module ts {
|
||||
docComment: string;
|
||||
}
|
||||
|
||||
export enum EmitOutputResult {
|
||||
Succeeded,
|
||||
FailedBecauseOfSyntaxErrors,
|
||||
FailedBecauseOfCompilerOptionsErrors,
|
||||
FailedToGenerateDeclarationsBecauseOfSemanticErrors
|
||||
}
|
||||
|
||||
export interface EmitOutput {
|
||||
outputFiles: OutputFile[];
|
||||
emitOutputResult: EmitOutputResult;
|
||||
emitOutputStatus: EmitReturnStatus;
|
||||
}
|
||||
|
||||
export enum OutputFileType {
|
||||
@@ -2846,56 +2839,43 @@ module ts {
|
||||
function getEmitOutput(filename: string): EmitOutput {
|
||||
synchronizeHostData();
|
||||
filename = TypeScript.switchToForwardSlashes(filename);
|
||||
var sourceFile = getSourceFile(filename);
|
||||
var sourceFile = program.getSourceFile(filename);
|
||||
var compilerOptions = program.getCompilerOptions();
|
||||
var emitToSingleFile = ts.shouldEmitToOwnFile(program.getSourceFile(filename), compilerOptions);
|
||||
var emitToSingleFile = ts.shouldEmitToOwnFile(sourceFile, compilerOptions);
|
||||
var emitDeclaration = compilerOptions.declaration;
|
||||
var emitResult: EmitOutput = {
|
||||
var emitOutput: EmitOutput = {
|
||||
outputFiles: [],
|
||||
emitOutputResult: undefined,
|
||||
emitOutputStatus: undefined,
|
||||
};
|
||||
|
||||
// Initialize writer for CompilerHost.writeFile
|
||||
writer = function (fileName: string, data: string, writeByteOrderMark: boolean) {
|
||||
var outputFile: OutputFile = {
|
||||
emitOutput.outputFiles.push({
|
||||
name: fileName,
|
||||
writeByteOrderMark: writeByteOrderMark,
|
||||
text: data
|
||||
}
|
||||
emitResult.outputFiles.push(outputFile);
|
||||
});
|
||||
}
|
||||
|
||||
var syntacticDiagnostics = emitToSingleFile
|
||||
? program.getDiagnostics(sourceFile)
|
||||
: program.getDiagnostics();
|
||||
program.getGlobalDiagnostics();
|
||||
var globalSyntacticDiagnostics = program.getGlobalDiagnostics();
|
||||
|
||||
// If there is any syntactic error, terminate the process
|
||||
if (containErrors(syntacticDiagnostics)) {
|
||||
emitResult.emitOutputResult = EmitOutputResult.FailedBecauseOfSyntaxErrors;
|
||||
return emitResult;
|
||||
emitOutput.emitOutputStatus = EmitReturnStatus.AllOutputGenerationSkipped;
|
||||
return emitOutput;
|
||||
}
|
||||
|
||||
// Perform semantic and force a type check before emit to ensure that all symbols are updated
|
||||
var semanticDiagnostics = emitToSingleFile
|
||||
? getFullTypeCheckChecker().getDiagnostics(getSourceFile(filename).getSourceFile())
|
||||
: getFullTypeCheckChecker().getDiagnostics();
|
||||
getFullTypeCheckChecker().getGlobalDiagnostics();
|
||||
var emitOutput = getFullTypeCheckChecker().emitFiles();
|
||||
// EmitFiles will report if there is an error from TypeChecker and Emitter
|
||||
var emitFilesResult = getFullTypeCheckChecker().emitFiles();
|
||||
emitOutput.emitOutputStatus = emitFilesResult.emitResultStatus;
|
||||
|
||||
if (emitDeclaration && containErrors(semanticDiagnostics)) {
|
||||
emitResult.emitOutputResult = EmitOutputResult.FailedToGenerateDeclarationsBecauseOfSemanticErrors;
|
||||
}
|
||||
else if (emitDeclaration && containErrors(emitOutput.errors)) {
|
||||
emitResult.emitOutputResult = EmitOutputResult.FailedToGenerateDeclarationsBecauseOfSemanticErrors;
|
||||
}
|
||||
else {
|
||||
emitResult.emitOutputResult = EmitOutputResult.Succeeded;
|
||||
}
|
||||
|
||||
// Reset writer back to underfined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in an emitting stage
|
||||
// Reset writer back to underfined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in getEmitOutput
|
||||
this.writer = undefined;
|
||||
return emitResult;
|
||||
return emitOutput;
|
||||
}
|
||||
|
||||
/// Syntactic features
|
||||
|
||||
@@ -44,14 +44,17 @@ enum TypingFidelity {
|
||||
High = FourSlash.TypingFidelity.High
|
||||
}
|
||||
|
||||
// We have to duplicate EmitOutputResult from Services.ts to expose the enum to getEmitOutput testcases in fourslah
|
||||
enum EmitOutputResult {
|
||||
Succeeded,
|
||||
FailedBecauseOfSyntaxErrors,
|
||||
FailedBecauseOfCompilerOptionsErrors,
|
||||
FailedToGenerateDeclarationsBecauseOfSemanticErrors
|
||||
// Return code used by getEmitOutput function to indicate status of the function
|
||||
// It is a duplicate of the one in types.ts to expose it to testcases in fourslash
|
||||
enum EmitReturnStatus {
|
||||
Succeeded = 0, // All outputs generated as requested (.js, .map, .d.ts), no errors reported
|
||||
AllOutputGenerationSkipped = 1, // No .js generated because of syntax errors, or compiler options errors, nothing generated
|
||||
JSGeneratedWithSemanticErrors = 2, // .js and .map generated with semantic errors
|
||||
DeclarationGenerationSkipped = 3, // .d.ts generation skipped because of semantic errors or declaration emitter specific errors; Output .js with semantic errors
|
||||
EmitErrorsEncountered = 4 // Emitter errors occured during emitting process
|
||||
}
|
||||
|
||||
|
||||
module FourSlashInterface {
|
||||
declare var FourSlash;
|
||||
|
||||
@@ -263,7 +266,7 @@ module FourSlashInterface {
|
||||
FourSlash.currentTestState.verifyEval(expr, value);
|
||||
}
|
||||
|
||||
public emitOutput(expectedState: EmitOutputResult, expectedFilename?: string) {
|
||||
public emitOutput(expectedState: EmitReturnStatus, expectedFilename?: string) {
|
||||
FourSlash.currentTestState.verifyEmitOutput(expectedState, expectedFilename);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user