Refresh semantic diagnostics when compiler options affecting semantic diagnostics generation changes

Fixes #26195
This commit is contained in:
Sheetal Nandi 2018-08-03 16:27:25 -07:00
parent c6ca96bdcf
commit d419968c0d
3 changed files with 88 additions and 1 deletions

View File

@ -65,7 +65,8 @@ namespace ts {
}
state.changedFilesSet = createMap<true>();
const useOldState = BuilderState.canReuseOldState(state.referencedMap, oldState);
const canCopySemanticDiagnostics = useOldState && oldState!.semanticDiagnosticsPerFile && !!state.semanticDiagnosticsPerFile;
const canCopySemanticDiagnostics = useOldState && oldState!.semanticDiagnosticsPerFile && !!state.semanticDiagnosticsPerFile &&
!compilerOptionsAffectSemanticDiagnostics(compilerOptions, oldState!.program.getCompilerOptions());
if (useOldState) {
// Verify the sanity of old state
if (!oldState!.currentChangedFilePath) {

View File

@ -6967,6 +6967,49 @@ namespace ts {
return compilerOptions[flag] === undefined ? !!compilerOptions.strict : !!compilerOptions[flag];
}
export function compilerOptionsAffectSemanticDiagnostics(newOptions: CompilerOptions, oldOptions: CompilerOptions) {
if (oldOptions === newOptions) {
return false;
}
return changedCompileOptionValueOf(newOptions, oldOptions, [
"noImplicitReturns",
"strict",
"suppressExcessPropertyErrors",
"suppressImplicitAnyIndexErrors",
"noFallthroughCasesInSwitch",
"noStrictGenericChecks",
"noUnusedLocals",
"noUnusedParameters",
"noImplicitUseStrict"
]) || changedStrictOptionValueOf(newOptions, oldOptions, [
"noImplicitAny",
"noImplicitThis",
"strictNullChecks",
"strictFunctionTypes",
"strictPropertyInitialization",
"alwaysStrict"
]);
}
function changedStrictOptionValueOf(newOptions: CompilerOptions, oldOptions: CompilerOptions, flags: StrictOptionName[]) {
for (const flag of flags) {
if (getStrictOptionValue(newOptions, flag) !== getStrictOptionValue(oldOptions, flag)) {
return true;
}
}
return false;
}
function changedCompileOptionValueOf(newOptions: CompilerOptions, oldOptions: CompilerOptions, optionKeys: (keyof CompilerOptions)[]) {
for (const optionKey of optionKeys) {
if (newOptions[optionKey] !== oldOptions[optionKey]) {
return true;
}
}
return false;
}
export function hasZeroOrOneAsteriskCharacter(str: string): boolean {
let seenAsterisk = false;
for (let i = 0; i < str.length; i++) {

View File

@ -1312,6 +1312,49 @@ export class B
// File a need not be rewritten
assert.equal(host.getModifiedTime(`${currentDirectory}/a.js`), modifiedTimeOfAJs);
});
it("updates errors when strictNullChecks changes", () => {
const currentDirectory = "/user/username/projects/myproject";
const aFile: File = {
path: `${currentDirectory}/a.ts`,
content: `declare function foo(): null | { hello: any };
foo().hello`
};
const compilerOptions: CompilerOptions = {
};
const config: File = {
path: `${currentDirectory}/tsconfig.json`,
content: JSON.stringify({ compilerOptions })
};
const files = [aFile, config, libFile];
const host = createWatchedSystem(files, { currentDirectory });
const watch = createWatchOfConfigFile("tsconfig.json", host);
checkProgramActualFiles(watch(), [aFile.path, libFile.path]);
checkOutputErrorsInitial(host, emptyArray);
const modifiedTimeOfAJs = host.getModifiedTime(`${currentDirectory}/a.js`);
compilerOptions.strictNullChecks = true;
host.writeFile(config.path, JSON.stringify({ compilerOptions }));
host.runQueuedTimeoutCallbacks();
const expectedStrictNullErrors = [
getDiagnosticOfFileFromProgram(watch(), aFile.path, aFile.content.lastIndexOf("foo()"), 5, Diagnostics.Object_is_possibly_null)
];
checkOutputErrorsIncremental(host, expectedStrictNullErrors);
// File a need not be rewritten
assert.equal(host.getModifiedTime(`${currentDirectory}/a.js`), modifiedTimeOfAJs);
compilerOptions.strict = true;
delete (compilerOptions.strictNullChecks);
host.writeFile(config.path, JSON.stringify({ compilerOptions }));
host.runQueuedTimeoutCallbacks();
checkOutputErrorsIncremental(host, expectedStrictNullErrors);
// File a need not be rewritten
assert.equal(host.getModifiedTime(`${currentDirectory}/a.js`), modifiedTimeOfAJs);
delete (compilerOptions.strict);
host.writeFile(config.path, JSON.stringify({ compilerOptions }));
host.runQueuedTimeoutCallbacks();
checkOutputErrorsIncremental(host, emptyArray);
// File a need not be rewritten
assert.equal(host.getModifiedTime(`${currentDirectory}/a.js`), modifiedTimeOfAJs);
});
});
describe("tsc-watch emit with outFile or out setting", () => {