Do not cache semantic diagnostics with --isolated modules

Fixes #28332
This commit is contained in:
Sheetal Nandi
2019-01-03 14:07:25 -08:00
parent 8dff98dda0
commit a633f95da7
2 changed files with 66 additions and 8 deletions

View File

@@ -64,7 +64,9 @@ namespace ts {
const state = BuilderState.create(newProgram, getCanonicalFileName, oldState) as BuilderProgramState;
state.program = newProgram;
const compilerOptions = newProgram.getCompilerOptions();
if (!compilerOptions.outFile && !compilerOptions.out) {
// With --out or --outFile, any change affects all semantic diagnostics so no need to cache them
// With --isolatedModules, emitting changed file doesnt emit dependent files so we cant know of dependent files to retrieve errors so dont cache the errors
if (!compilerOptions.outFile && !compilerOptions.out && !compilerOptions.isolatedModules) {
state.semanticDiagnosticsPerFile = createMap<ReadonlyArray<Diagnostic>>();
}
state.changedFilesSet = createMap<true>();
@@ -338,15 +340,19 @@ namespace ts {
*/
function getSemanticDiagnosticsOfFile(state: BuilderProgramState, sourceFile: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic> {
const path = sourceFile.path;
const cachedDiagnostics = state.semanticDiagnosticsPerFile!.get(path);
// Report the semantic diagnostics from the cache if we already have those diagnostics present
if (cachedDiagnostics) {
return cachedDiagnostics;
if (state.semanticDiagnosticsPerFile) {
const cachedDiagnostics = state.semanticDiagnosticsPerFile.get(path);
// Report the semantic diagnostics from the cache if we already have those diagnostics present
if (cachedDiagnostics) {
return cachedDiagnostics;
}
}
// Diagnostics werent cached, get them from program, and cache the result
const diagnostics = state.program.getSemanticDiagnostics(sourceFile, cancellationToken);
state.semanticDiagnosticsPerFile!.set(path, diagnostics);
if (state.semanticDiagnosticsPerFile) {
state.semanticDiagnosticsPerFile.set(path, diagnostics);
}
return diagnostics;
}

View File

@@ -1281,7 +1281,59 @@ interface Document {
checkProgramActualFiles(watch(), [aFile.path, bFile.path, libFile.path]);
}
});
it("reports errors correctly with isolatedModules", () => {
const currentDirectory = "/user/username/projects/myproject";
const aFile: File = {
path: `${currentDirectory}/a.ts`,
content: `export const a: string = "";`
};
const bFile: File = {
path: `${currentDirectory}/b.ts`,
content: `import { a } from "./a";
const b: string = a;`
};
const configFile: File = {
path: `${currentDirectory}/tsconfig.json`,
content: JSON.stringify({
compilerOptions: {
isolatedModules: true
}
})
};
const files = [aFile, bFile, libFile, configFile];
const host = createWatchedSystem(files, { currentDirectory });
const watch = createWatchOfConfigFile("tsconfig.json", host);
verifyProgramFiles();
checkOutputErrorsInitial(host, emptyArray);
assert.equal(host.readFile(`${currentDirectory}/a.js`), `"use strict";
exports.__esModule = true;
exports.a = "";
`, "Contents of a.js");
assert.equal(host.readFile(`${currentDirectory}/b.js`), `"use strict";
exports.__esModule = true;
var a_1 = require("./a");
var b = a_1.a;
`, "Contents of b.js");
const modifiedTime = host.getModifiedTime(`${currentDirectory}/b.js`);
host.writeFile(aFile.path, `export const a: number = 1`);
host.runQueuedTimeoutCallbacks();
verifyProgramFiles();
checkOutputErrorsIncremental(host, [
getDiagnosticOfFileFromProgram(watch(), bFile.path, bFile.content.indexOf("b"), 1, Diagnostics.Type_0_is_not_assignable_to_type_1, "number", "string")
]);
assert.equal(host.readFile(`${currentDirectory}/a.js`), `"use strict";
exports.__esModule = true;
exports.a = 1;
`, "Contents of a.js");
assert.equal(host.getModifiedTime(`${currentDirectory}/b.js`), modifiedTime, "Timestamp of b.js");
function verifyProgramFiles() {
checkProgramActualFiles(watch(), [aFile.path, bFile.path, libFile.path]);
}
});
});
}