parent
93206993ed
commit
a27b29f025
2 changed files with 144 additions and 1 deletions
|
@ -38,6 +38,10 @@ namespace ts {
|
|||
* Already seen affected files
|
||||
*/
|
||||
seenAffectedFiles: Map<true> | undefined;
|
||||
/**
|
||||
* program corresponding to this state
|
||||
*/
|
||||
cleanedDiagnosticsOfLibFiles?: boolean;
|
||||
/**
|
||||
* True if the semantic diagnostics were copied from the old state
|
||||
*/
|
||||
|
@ -83,6 +87,8 @@ namespace ts {
|
|||
// Update changed files and copy semantic diagnostics if we can
|
||||
const referencedMap = state.referencedMap;
|
||||
const oldReferencedMap = useOldState ? oldState!.referencedMap : undefined;
|
||||
const copyDeclarationFileDiagnostics = canCopySemanticDiagnostics && !compilerOptions.skipLibCheck === !oldState!.program.getCompilerOptions().skipLibCheck;
|
||||
const copyLibFileDiagnostics = copyDeclarationFileDiagnostics && !compilerOptions.skipDefaultLibCheck === !oldState!.program.getCompilerOptions().skipDefaultLibCheck;
|
||||
state.fileInfos.forEach((info, sourceFilePath) => {
|
||||
let oldInfo: Readonly<BuilderState.FileInfo> | undefined;
|
||||
let newReferences: BuilderState.ReferencedSet | undefined;
|
||||
|
@ -101,6 +107,11 @@ namespace ts {
|
|||
state.changedFilesSet.set(sourceFilePath, true);
|
||||
}
|
||||
else if (canCopySemanticDiagnostics) {
|
||||
const sourceFile = state.program.getSourceFileByPath(sourceFilePath as Path)!;
|
||||
|
||||
if (sourceFile.isDeclarationFile && !copyDeclarationFileDiagnostics) { return; }
|
||||
if (sourceFile.hasNoDefaultLib && !copyLibFileDiagnostics) { return; }
|
||||
|
||||
// Unchanged file copy diagnostics
|
||||
const diagnostics = oldState!.semanticDiagnosticsPerFile!.get(sourceFilePath);
|
||||
if (diagnostics) {
|
||||
|
@ -193,6 +204,19 @@ namespace ts {
|
|||
return;
|
||||
}
|
||||
|
||||
// Clean lib file diagnostics if its all files excluding default files to emit
|
||||
if (state.allFilesExcludingDefaultLibraryFile === state.affectedFiles && !state.cleanedDiagnosticsOfLibFiles) {
|
||||
state.cleanedDiagnosticsOfLibFiles = true;
|
||||
const options = state.program.getCompilerOptions();
|
||||
if (forEach(state.program.getSourceFiles(), f =>
|
||||
!contains(state.allFilesExcludingDefaultLibraryFile, f) &&
|
||||
!skipTypeChecking(f, options) &&
|
||||
removeSemanticDiagnosticsOf(state, f.path)
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If there was change in signature for the changed file,
|
||||
// then delete the semantic diagnostics for files that are affected by using exports of this module
|
||||
|
||||
|
@ -268,7 +292,7 @@ namespace ts {
|
|||
*/
|
||||
function removeSemanticDiagnosticsOf(state: BuilderProgramState, path: Path) {
|
||||
if (!state.semanticDiagnosticsFromOldState) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
state.semanticDiagnosticsFromOldState.delete(path);
|
||||
state.semanticDiagnosticsPerFile!.delete(path);
|
||||
|
|
|
@ -1564,6 +1564,125 @@ export class Data2 {
|
|||
verifyTransitiveExports([libFile, app, lib2Public, lib2Data, lib2Data2, lib1Public, lib1ToolsPublic, lib1ToolsInterface]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("updates errors in lib file when non module file changes", () => {
|
||||
const currentDirectory = "/user/username/projects/myproject";
|
||||
const field = "fullscreen";
|
||||
const aFile: File = {
|
||||
path: `${currentDirectory}/a.ts`,
|
||||
content: `interface Document {
|
||||
${field}: boolean;
|
||||
}`
|
||||
};
|
||||
const libFileWithDocument: File = {
|
||||
path: libFile.path,
|
||||
content: `${libFile.content}
|
||||
interface Document {
|
||||
readonly ${field}: boolean;
|
||||
}`
|
||||
};
|
||||
|
||||
function getDiagnostic(program: Program, file: File) {
|
||||
return getDiagnosticOfFileFromProgram(program, file.path, file.content.indexOf(field), field.length, Diagnostics.All_declarations_of_0_must_have_identical_modifiers, field);
|
||||
}
|
||||
|
||||
const files = [aFile, libFileWithDocument];
|
||||
|
||||
function verifyLibErrors(options: CompilerOptions) {
|
||||
const host = createWatchedSystem(files, { currentDirectory });
|
||||
const watch = createWatchOfFilesAndCompilerOptions([aFile.path], host, options);
|
||||
checkProgramActualFiles(watch(), [aFile.path, libFile.path]);
|
||||
checkOutputErrorsInitial(host, getErrors());
|
||||
|
||||
host.writeFile(aFile.path, "var x = 10;");
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkProgramActualFiles(watch(), [aFile.path, libFile.path]);
|
||||
checkOutputErrorsIncremental(host, emptyArray);
|
||||
|
||||
host.writeFile(aFile.path, aFile.content);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkProgramActualFiles(watch(), [aFile.path, libFile.path]);
|
||||
checkOutputErrorsIncremental(host, getErrors());
|
||||
|
||||
function getErrors() {
|
||||
return [
|
||||
...(options.skipLibCheck || options.skipDefaultLibCheck ? [] : [getDiagnostic(watch(), libFileWithDocument)]),
|
||||
getDiagnostic(watch(), aFile)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
it("with default options", () => {
|
||||
verifyLibErrors({});
|
||||
});
|
||||
it("with skipLibCheck", () => {
|
||||
verifyLibErrors({ skipLibCheck: true });
|
||||
});
|
||||
it("with skipDefaultLibCheck", () => {
|
||||
verifyLibErrors({ skipDefaultLibCheck: true });
|
||||
});
|
||||
});
|
||||
|
||||
it("when skipLibCheck and skipDefaultLibCheck changes", () => {
|
||||
const currentDirectory = "/user/username/projects/myproject";
|
||||
const field = "fullscreen";
|
||||
const aFile: File = {
|
||||
path: `${currentDirectory}/a.ts`,
|
||||
content: `interface Document {
|
||||
${field}: boolean;
|
||||
}`
|
||||
};
|
||||
const bFile: File = {
|
||||
path: `${currentDirectory}/b.d.ts`,
|
||||
content: `interface Document {
|
||||
${field}: boolean;
|
||||
}`
|
||||
};
|
||||
const libFileWithDocument: File = {
|
||||
path: libFile.path,
|
||||
content: `${libFile.content}
|
||||
interface Document {
|
||||
readonly ${field}: boolean;
|
||||
}`
|
||||
};
|
||||
const configFile: File = {
|
||||
path: `${currentDirectory}/tsconfig.json`,
|
||||
content: "{}"
|
||||
};
|
||||
|
||||
const files = [aFile, bFile, configFile, libFileWithDocument];
|
||||
|
||||
const host = createWatchedSystem(files, { currentDirectory });
|
||||
const watch = createWatchOfConfigFile("tsconfig.json", host);
|
||||
verifyProgramFiles();
|
||||
checkOutputErrorsInitial(host, [
|
||||
getDiagnostic(libFileWithDocument),
|
||||
getDiagnostic(aFile),
|
||||
getDiagnostic(bFile)
|
||||
]);
|
||||
|
||||
verifyConfigChange({ skipLibCheck: true }, [aFile]);
|
||||
verifyConfigChange({ skipDefaultLibCheck: true }, [aFile, bFile]);
|
||||
verifyConfigChange({}, [libFileWithDocument, aFile, bFile]);
|
||||
verifyConfigChange({ skipDefaultLibCheck: true }, [aFile, bFile]);
|
||||
verifyConfigChange({ skipLibCheck: true }, [aFile]);
|
||||
verifyConfigChange({}, [libFileWithDocument, aFile, bFile]);
|
||||
|
||||
function verifyConfigChange(compilerOptions: CompilerOptions, errorInFiles: ReadonlyArray<File>) {
|
||||
host.writeFile(configFile.path, JSON.stringify({ compilerOptions }));
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
verifyProgramFiles();
|
||||
checkOutputErrorsIncremental(host, errorInFiles.map(getDiagnostic));
|
||||
}
|
||||
|
||||
function getDiagnostic(file: File) {
|
||||
return getDiagnosticOfFileFromProgram(watch(), file.path, file.content.indexOf(field), field.length, Diagnostics.All_declarations_of_0_must_have_identical_modifiers, field);
|
||||
}
|
||||
|
||||
function verifyProgramFiles() {
|
||||
checkProgramActualFiles(watch(), [aFile.path, bFile.path, libFile.path]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("tsc-watch emit with outFile or out setting", () => {
|
||||
|
|
Loading…
Reference in a new issue