Skip to content

Commit 2ffd35d

Browse files
authored
More updates to program reuse with different option changes (#44276)
1 parent 3442d31 commit 2ffd35d

File tree

6 files changed

+27
-22
lines changed

6 files changed

+27
-22
lines changed

src/compiler/commandLineParser.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ namespace ts {
395395
name: "lib",
396396
type: libMap
397397
},
398-
affectsModuleResolution: true,
398+
affectsProgramStructure: true,
399399
showInSimplifiedHelpView: true,
400400
category: Diagnostics.Basic_Options,
401401
description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation,
@@ -755,7 +755,7 @@ namespace ts {
755755
name: "types",
756756
type: "string"
757757
},
758-
affectsModuleResolution: true,
758+
affectsProgramStructure: true,
759759
showInSimplifiedHelpView: true,
760760
category: Diagnostics.Module_Resolution_Options,
761761
description: Diagnostics.Type_declaration_files_to_be_included_in_compilation,
@@ -928,7 +928,7 @@ namespace ts {
928928
{
929929
name: "noLib",
930930
type: "boolean",
931-
affectsModuleResolution: true,
931+
affectsProgramStructure: true,
932932
category: Diagnostics.Advanced_Options,
933933
description: Diagnostics.Do_not_include_the_default_library_file_lib_d_ts,
934934
// We are not returning a sourceFile for lib file when asked by the program,
@@ -955,7 +955,7 @@ namespace ts {
955955
{
956956
name: "disableSizeLimit",
957957
type: "boolean",
958-
affectsSourceFile: true,
958+
affectsProgramStructure: true,
959959
category: Diagnostics.Advanced_Options,
960960
description: Diagnostics.Disable_size_limitations_on_JavaScript_projects
961961
},
@@ -1126,6 +1126,10 @@ namespace ts {
11261126
export const sourceFileAffectingCompilerOptions: readonly CommandLineOption[] = optionDeclarations.filter(option =>
11271127
!!option.affectsSourceFile || !!option.affectsModuleResolution || !!option.affectsBindDiagnostics);
11281128

1129+
/* @internal */
1130+
export const optionsAffectingProgramStructure: readonly CommandLineOption[] =
1131+
optionDeclarations.filter(option => !!option.affectsProgramStructure);
1132+
11291133
/* @internal */
11301134
export const transpileOptionValueCompilerOptions: readonly CommandLineOption[] = optionDeclarations.filter(option =>
11311135
hasProperty(option, "transpileOptionValue"));

src/compiler/program.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -745,9 +745,7 @@ namespace ts {
745745
if (!program) return false;
746746
// If any compiler options change, we can't reuse old source file even if version match
747747
// The change in options like these could result in change in syntax tree or `sourceFile.bindDiagnostics`.
748-
const oldOptions = program.getCompilerOptions();
749-
return !!sourceFileAffectingCompilerOptions.some(option =>
750-
!isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option)));
748+
return optionsHaveChanges(program.getCompilerOptions(), newOptions, sourceFileAffectingCompilerOptions);
751749
}
752750

753751
function createCreateProgramOptions(rootNames: readonly string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: readonly Diagnostic[]): CreateProgramOptions {
@@ -1421,10 +1419,6 @@ namespace ts {
14211419
return StructureIsReused.Not;
14221420
}
14231421

1424-
if (!arrayIsEqualTo(options.types, oldOptions.types)) {
1425-
return StructureIsReused.Not;
1426-
}
1427-
14281422
// Check if any referenced project tsconfig files are different
14291423
if (!canReuseProjectReferences()) {
14301424
return StructureIsReused.Not;
@@ -1505,7 +1499,7 @@ namespace ts {
15051499

15061500
if (!arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) {
15071501
// 'lib' references has changed. Matches behavior in changesAffectModuleResolution
1508-
return StructureIsReused.Not;
1502+
structureIsReused = StructureIsReused.SafeModules;
15091503
}
15101504

15111505
if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {
@@ -1598,7 +1592,7 @@ namespace ts {
15981592
return structureIsReused;
15991593
}
16001594

1601-
if (host.hasChangedAutomaticTypeDirectiveNames?.()) {
1595+
if (changesAffectingProgramStructure(oldOptions, options) || host.hasChangedAutomaticTypeDirectiveNames?.()) {
16021596
return StructureIsReused.SafeModules;
16031597
}
16041598

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6230,6 +6230,7 @@ namespace ts {
62306230
affectsBindDiagnostics?: true; // true if this affects binding (currently same effect as `affectsSourceFile`)
62316231
affectsSemanticDiagnostics?: true; // true if option affects semantic diagnostics
62326232
affectsEmit?: true; // true if the options affects emit
6233+
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
62336234
transpileOptionValue?: boolean | undefined; // If set this means that the option should be set to this value when transpiling
62346235
extraValidation?: (value: CompilerOptionsValue) => [DiagnosticMessage, ...string[]] | undefined; // Additional validation to be performed for the value to be valid
62356236
}

src/compiler/utilities.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,15 @@ namespace ts {
9696
}
9797

9898
export function optionsHaveModuleResolutionChanges(oldOptions: CompilerOptions, newOptions: CompilerOptions) {
99-
return moduleResolutionOptionDeclarations.some(o =>
99+
return optionsHaveChanges(oldOptions, newOptions, moduleResolutionOptionDeclarations);
100+
}
101+
102+
export function changesAffectingProgramStructure(oldOptions: CompilerOptions, newOptions: CompilerOptions) {
103+
return optionsHaveChanges(oldOptions, newOptions, optionsAffectingProgramStructure);
104+
}
105+
106+
export function optionsHaveChanges(oldOptions: CompilerOptions, newOptions: CompilerOptions, optionDeclarations: readonly CommandLineOption[]) {
107+
return oldOptions !== newOptions && optionDeclarations.some(o =>
100108
!isJsonEqual(getCompilerOptionValue(oldOptions, o), getCompilerOptionValue(newOptions, o)));
101109
}
102110

@@ -6125,13 +6133,11 @@ namespace ts {
61256133
}
61266134

61276135
export function compilerOptionsAffectSemanticDiagnostics(newOptions: CompilerOptions, oldOptions: CompilerOptions): boolean {
6128-
return oldOptions !== newOptions &&
6129-
semanticDiagnosticsOptionDeclarations.some(option => !isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option)));
6136+
return optionsHaveChanges(oldOptions, newOptions, semanticDiagnosticsOptionDeclarations);
61306137
}
61316138

61326139
export function compilerOptionsAffectEmit(newOptions: CompilerOptions, oldOptions: CompilerOptions): boolean {
6133-
return oldOptions !== newOptions &&
6134-
affectsEmitOptionDeclarations.some(option => !isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option)));
6140+
return optionsHaveChanges(oldOptions, newOptions, affectsEmitOptionDeclarations);
61356141
}
61366142

61376143
export function getCompilerOptionValue(options: CompilerOptions, option: CommandLineOption): unknown {

src/testRunner/unittests/reuseProgramStructure.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ namespace ts {
262262
it("fails if change affects type references", () => {
263263
const program1 = newProgram(files, ["a.ts"], { types: ["a"] });
264264
const program2 = updateProgram(program1, ["a.ts"], { types: ["b"] }, noop);
265-
assert.equal(program2.structureIsReused, StructureIsReused.Not);
265+
assert.equal(program2.structureIsReused, StructureIsReused.SafeModules);
266266
});
267267

268268
it("succeeds if change doesn't affect type references", () => {

tests/baselines/reference/tscWatch/programUpdates/correctly-handles-changes-in-lib-section-of-config-file.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ Output::
8888

8989
Program root files: ["/src/app.ts"]
9090
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"}
91-
Program structureReused: Not
91+
Program structureReused: SafeModules
9292
Program files::
9393
/compiler/lib.es5.d.ts
9494
/compiler/lib.es2015.promise.d.ts
@@ -112,10 +112,10 @@ WatchedFiles::
112112
FsWatches::
113113

114114
FsWatchesRecursive::
115-
/src:
116-
{"directoryName":"/src","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}}
117115
/src/node_modules/@types:
118116
{"directoryName":"/src/node_modules/@types","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}}
117+
/src:
118+
{"directoryName":"/src","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}}
119119

120120
exitCode:: ExitStatus.undefined
121121

0 commit comments

Comments
 (0)