Always get diagnostics when emitting irrespective of whether its declaration only emit

The diagnostics reporting and expression resolution caching is quite intermingled at present.
Hence when we tried to get the declaration output without getting diagnostics, the resolution for functions return expression is cached but errors arent reported
Symbols arent marked as referenced. So at later time when trying to get the diagnostics since the expression resolution is cached, it doesnt even go through all checks
For now get diagnostics irrespective of declaration only output to avoid this issue.
Fixes #21518
This commit is contained in:
Sheetal Nandi 2018-01-31 16:22:27 -08:00
parent d0ab1642fe
commit cf540198e6
4 changed files with 31 additions and 6 deletions

View file

@ -749,12 +749,10 @@ namespace ts {
return _jsxNamespace;
}
function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken, ignoreDiagnostics?: boolean) {
function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken) {
// Ensure we have all the type information in place for this file so that all the
// emitter questions of this resolver will return the right information.
if (!ignoreDiagnostics) {
getDiagnostics(sourceFile, cancellationToken);
}
getDiagnostics(sourceFile, cancellationToken);
return emitResolver;
}

View file

@ -1179,7 +1179,7 @@ namespace ts {
// This is because in the -out scenario all files need to be emitted, and therefore all
// files need to be type checked. And the way to specify that all files need to be type
// checked is to not pass the file to getEmitResolver.
const emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile, cancellationToken, emitOnlyDtsFiles);
const emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile, cancellationToken);
performance.mark("beforeEmit");

View file

@ -2892,7 +2892,7 @@ namespace ts {
// Should not be called directly. Should only be accessed through the Program instance.
/* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
/* @internal */ getGlobalDiagnostics(): Diagnostic[];
/* @internal */ getEmitResolver(sourceFile?: SourceFile, cancellationToken?: CancellationToken, ignoreDiagnostics?: boolean): EmitResolver;
/* @internal */ getEmitResolver(sourceFile?: SourceFile, cancellationToken?: CancellationToken): EmitResolver;
/* @internal */ getNodeCount(): number;
/* @internal */ getIdentifierCount(): number;

View file

@ -1086,6 +1086,33 @@ namespace ts.tscWatch {
// This should be 0
host.checkTimeoutQueueLengthAndRun(0);
});
it("shouldnt report error about unused function incorrectly when file changes from global to module", () => {
const getFileContent = (asModule: boolean) => `
function one() {}
${asModule ? "export " : ""}function two() {
return function three() {
one();
}
}`;
const file: FileOrFolder = {
path: "/a/b/file.ts",
content: getFileContent(/*asModule*/ false)
};
const files = [file, libFile];
const host = createWatchedSystem(files);
const watch = createWatchOfFilesAndCompilerOptions([file.path], host, {
noUnusedLocals: true
});
checkProgramActualFiles(watch(), files.map(file => file.path));
checkOutputErrors(host, [], ExpectedOutputErrorsPosition.AfterCompilationStarting);
file.content = getFileContent(/*asModule*/ true);
host.reloadFS(files);
host.runQueuedTimeoutCallbacks();
checkProgramActualFiles(watch(), files.map(file => file.path));
checkOutputErrors(host, [], ExpectedOutputErrorsPosition.AfterFileChangeDetected);
});
});
describe("tsc-watch emit with outFile or out setting", () => {