More updates to program reuse with different option changes (#44276)

This commit is contained in:
Sheetal Nandi 2021-05-26 15:57:43 -07:00 committed by GitHub
parent 3442d311cf
commit 2ffd35de4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 27 additions and 22 deletions

View File

@ -395,7 +395,7 @@ namespace ts {
name: "lib",
type: libMap
},
affectsModuleResolution: true,
affectsProgramStructure: true,
showInSimplifiedHelpView: true,
category: Diagnostics.Basic_Options,
description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation,
@ -755,7 +755,7 @@ namespace ts {
name: "types",
type: "string"
},
affectsModuleResolution: true,
affectsProgramStructure: true,
showInSimplifiedHelpView: true,
category: Diagnostics.Module_Resolution_Options,
description: Diagnostics.Type_declaration_files_to_be_included_in_compilation,
@ -928,7 +928,7 @@ namespace ts {
{
name: "noLib",
type: "boolean",
affectsModuleResolution: true,
affectsProgramStructure: true,
category: Diagnostics.Advanced_Options,
description: Diagnostics.Do_not_include_the_default_library_file_lib_d_ts,
// We are not returning a sourceFile for lib file when asked by the program,
@ -955,7 +955,7 @@ namespace ts {
{
name: "disableSizeLimit",
type: "boolean",
affectsSourceFile: true,
affectsProgramStructure: true,
category: Diagnostics.Advanced_Options,
description: Diagnostics.Disable_size_limitations_on_JavaScript_projects
},
@ -1126,6 +1126,10 @@ namespace ts {
export const sourceFileAffectingCompilerOptions: readonly CommandLineOption[] = optionDeclarations.filter(option =>
!!option.affectsSourceFile || !!option.affectsModuleResolution || !!option.affectsBindDiagnostics);
/* @internal */
export const optionsAffectingProgramStructure: readonly CommandLineOption[] =
optionDeclarations.filter(option => !!option.affectsProgramStructure);
/* @internal */
export const transpileOptionValueCompilerOptions: readonly CommandLineOption[] = optionDeclarations.filter(option =>
hasProperty(option, "transpileOptionValue"));

View File

@ -745,9 +745,7 @@ namespace ts {
if (!program) return false;
// If any compiler options change, we can't reuse old source file even if version match
// The change in options like these could result in change in syntax tree or `sourceFile.bindDiagnostics`.
const oldOptions = program.getCompilerOptions();
return !!sourceFileAffectingCompilerOptions.some(option =>
!isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option)));
return optionsHaveChanges(program.getCompilerOptions(), newOptions, sourceFileAffectingCompilerOptions);
}
function createCreateProgramOptions(rootNames: readonly string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: readonly Diagnostic[]): CreateProgramOptions {
@ -1421,10 +1419,6 @@ namespace ts {
return StructureIsReused.Not;
}
if (!arrayIsEqualTo(options.types, oldOptions.types)) {
return StructureIsReused.Not;
}
// Check if any referenced project tsconfig files are different
if (!canReuseProjectReferences()) {
return StructureIsReused.Not;
@ -1505,7 +1499,7 @@ namespace ts {
if (!arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) {
// 'lib' references has changed. Matches behavior in changesAffectModuleResolution
return StructureIsReused.Not;
structureIsReused = StructureIsReused.SafeModules;
}
if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {
@ -1598,7 +1592,7 @@ namespace ts {
return structureIsReused;
}
if (host.hasChangedAutomaticTypeDirectiveNames?.()) {
if (changesAffectingProgramStructure(oldOptions, options) || host.hasChangedAutomaticTypeDirectiveNames?.()) {
return StructureIsReused.SafeModules;
}

View File

@ -6230,6 +6230,7 @@ namespace ts {
affectsBindDiagnostics?: true; // true if this affects binding (currently same effect as `affectsSourceFile`)
affectsSemanticDiagnostics?: true; // true if option affects semantic diagnostics
affectsEmit?: true; // true if the options affects emit
affectsProgramStructure?: true; // true if program should be reconstructed from root files if option changes and does not affect module resolution as affectsModuleResolution indirectly means program needs to reconstructed
transpileOptionValue?: boolean | undefined; // If set this means that the option should be set to this value when transpiling
extraValidation?: (value: CompilerOptionsValue) => [DiagnosticMessage, ...string[]] | undefined; // Additional validation to be performed for the value to be valid
}

View File

@ -96,7 +96,15 @@ namespace ts {
}
export function optionsHaveModuleResolutionChanges(oldOptions: CompilerOptions, newOptions: CompilerOptions) {
return moduleResolutionOptionDeclarations.some(o =>
return optionsHaveChanges(oldOptions, newOptions, moduleResolutionOptionDeclarations);
}
export function changesAffectingProgramStructure(oldOptions: CompilerOptions, newOptions: CompilerOptions) {
return optionsHaveChanges(oldOptions, newOptions, optionsAffectingProgramStructure);
}
export function optionsHaveChanges(oldOptions: CompilerOptions, newOptions: CompilerOptions, optionDeclarations: readonly CommandLineOption[]) {
return oldOptions !== newOptions && optionDeclarations.some(o =>
!isJsonEqual(getCompilerOptionValue(oldOptions, o), getCompilerOptionValue(newOptions, o)));
}
@ -6125,13 +6133,11 @@ namespace ts {
}
export function compilerOptionsAffectSemanticDiagnostics(newOptions: CompilerOptions, oldOptions: CompilerOptions): boolean {
return oldOptions !== newOptions &&
semanticDiagnosticsOptionDeclarations.some(option => !isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option)));
return optionsHaveChanges(oldOptions, newOptions, semanticDiagnosticsOptionDeclarations);
}
export function compilerOptionsAffectEmit(newOptions: CompilerOptions, oldOptions: CompilerOptions): boolean {
return oldOptions !== newOptions &&
affectsEmitOptionDeclarations.some(option => !isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option)));
return optionsHaveChanges(oldOptions, newOptions, affectsEmitOptionDeclarations);
}
export function getCompilerOptionValue(options: CompilerOptions, option: CommandLineOption): unknown {

View File

@ -262,7 +262,7 @@ namespace ts {
it("fails if change affects type references", () => {
const program1 = newProgram(files, ["a.ts"], { types: ["a"] });
const program2 = updateProgram(program1, ["a.ts"], { types: ["b"] }, noop);
assert.equal(program2.structureIsReused, StructureIsReused.Not);
assert.equal(program2.structureIsReused, StructureIsReused.SafeModules);
});
it("succeeds if change doesn't affect type references", () => {

View File

@ -88,7 +88,7 @@ Output::
Program root files: ["/src/app.ts"]
Program options: {"module":1,"target":1,"noImplicitAny":true,"sourceMap":false,"lib":["lib.es5.d.ts","lib.es2015.promise.d.ts"],"watch":true,"project":"/src/tsconfig.json","configFilePath":"/src/tsconfig.json"}
Program structureReused: Not
Program structureReused: SafeModules
Program files::
/compiler/lib.es5.d.ts
/compiler/lib.es2015.promise.d.ts
@ -112,10 +112,10 @@ WatchedFiles::
FsWatches::
FsWatchesRecursive::
/src:
{"directoryName":"/src","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}}
/src/node_modules/@types:
{"directoryName":"/src/node_modules/@types","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}}
/src:
{"directoryName":"/src","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}}
exitCode:: ExitStatus.undefined