From 7fb35607bb6eb3e902f6e41e3e739fc20367d608 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 10 Dec 2025 10:00:23 -0800 Subject: [PATCH 1/5] Remove GetOptionsDiagnostics --- internal/compiler/program.go | 23 +++++------------------ internal/execute/incremental/program.go | 7 ------- 2 files changed, 5 insertions(+), 25 deletions(-) diff --git a/internal/compiler/program.go b/internal/compiler/program.go index a9a6b47f3e..ef7642466a 100644 --- a/internal/compiler/program.go +++ b/internal/compiler/program.go @@ -1031,7 +1031,10 @@ func (p *Program) GetGlobalDiagnostics(ctx context.Context) []*ast.Diagnostic { return nil } - pool := p.checkerPool.(*checkerPool) + pool, ok := p.checkerPool.(*checkerPool) + if !ok { + return nil // !!! Global diagnostics in the editor? + } globalDiagnostics := make([][]*ast.Diagnostic, len(pool.checkers)) pool.forEachCheckerParallel(func(idx int, checker *checker.Checker) { @@ -1045,17 +1048,6 @@ func (p *Program) GetDeclarationDiagnostics(ctx context.Context, sourceFile *ast return p.collectDiagnostics(ctx, sourceFile, true /*concurrent*/, p.getDeclarationDiagnosticsForFile) } -func (p *Program) GetOptionsDiagnostics(ctx context.Context) []*ast.Diagnostic { - return SortAndDeduplicateDiagnostics(core.Concatenate(p.GetGlobalDiagnostics(ctx), p.getOptionsDiagnosticsOfConfigFile())) -} - -func (p *Program) getOptionsDiagnosticsOfConfigFile() []*ast.Diagnostic { - if p.Options() == nil || p.Options().ConfigFilePath == "" { - return nil - } - return p.GetConfigFileParsingDiagnostics() -} - func FilterNoEmitSemanticDiagnostics(diagnostics []*ast.Diagnostic, options *core.CompilerOptions) []*ast.Diagnostic { if !options.NoEmit.IsTrue() { return diagnostics @@ -1445,7 +1437,6 @@ type ProgramLike interface { GetConfigFileParsingDiagnostics() []*ast.Diagnostic GetSyntacticDiagnostics(ctx context.Context, file *ast.SourceFile) []*ast.Diagnostic GetBindDiagnostics(ctx context.Context, file *ast.SourceFile) []*ast.Diagnostic - GetOptionsDiagnostics(ctx context.Context) []*ast.Diagnostic GetProgramDiagnostics() []*ast.Diagnostic GetGlobalDiagnostics(ctx context.Context) []*ast.Diagnostic GetSemanticDiagnostics(ctx context.Context, file *ast.SourceFile) []*ast.Diagnostic @@ -1494,13 +1485,9 @@ func GetDiagnosticsOfAnyProgram( allDiagnostics = append(allDiagnostics, program.GetProgramDiagnostics()...) if len(allDiagnostics) == configFileParsingDiagnosticsLength { - // Options diagnostics include global diagnostics (even though we collect them separately), - // and global diagnostics create checkers, which then bind all of the files. Do this binding - // early so we can track the time. + // Do binding early so we can track the time. getBindDiagnostics(ctx, file) - allDiagnostics = append(allDiagnostics, program.GetOptionsDiagnostics(ctx)...) - if program.Options().ListFilesOnly.IsFalseOrUnknown() { allDiagnostics = append(allDiagnostics, program.GetGlobalDiagnostics(ctx)...) diff --git a/internal/execute/incremental/program.go b/internal/execute/incremental/program.go index 2d5e595a6b..08a1aee121 100644 --- a/internal/execute/incremental/program.go +++ b/internal/execute/incremental/program.go @@ -132,12 +132,6 @@ func (p *Program) GetBindDiagnostics(ctx context.Context, file *ast.SourceFile) return p.program.GetBindDiagnostics(ctx, file) } -// GetOptionsDiagnostics implements compiler.AnyProgram interface. -func (p *Program) GetOptionsDiagnostics(ctx context.Context) []*ast.Diagnostic { - p.panicIfNoProgram("GetOptionsDiagnostics") - return p.program.GetOptionsDiagnostics(ctx) -} - func (p *Program) GetProgramDiagnostics() []*ast.Diagnostic { p.panicIfNoProgram("GetProgramDiagnostics") return p.program.GetProgramDiagnostics() @@ -365,7 +359,6 @@ func (p *Program) ensureHasErrorsForState(ctx context.Context, program *compiler len(program.GetConfigFileParsingDiagnostics()) > 0 || len(program.GetSyntacticDiagnostics(ctx, nil)) > 0 || len(program.GetProgramDiagnostics()) > 0 || - len(program.GetOptionsDiagnostics(ctx)) > 0 || len(program.GetGlobalDiagnostics(ctx)) > 0 { p.snapshot.hasErrors = core.TSTrue // Dont need to encode semantic errors state since the syntax and program diagnostics are encoded as present From e533802f20e1751c3e46b74f55e83222d2e69add Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 10 Dec 2025 10:01:02 -0800 Subject: [PATCH 2/5] Baselines --- .../reports-syntax-errors-in-config-file.js | 37 ++++--------------- .../reports-syntax-errors-in-config-file.js | 37 ++++--------------- 2 files changed, 16 insertions(+), 58 deletions(-) diff --git a/testdata/baselines/reference/tsbuild/configFileErrors/reports-syntax-errors-in-config-file.js b/testdata/baselines/reference/tsbuild/configFileErrors/reports-syntax-errors-in-config-file.js index 23310d06e4..fa4e984be8 100644 --- a/testdata/baselines/reference/tsbuild/configFileErrors/reports-syntax-errors-in-config-file.js +++ b/testdata/baselines/reference/tsbuild/configFileErrors/reports-syntax-errors-in-config-file.js @@ -69,7 +69,7 @@ exports.bar = bar; function bar() { } //// [/home/src/workspaces/project/tsconfig.tsbuildinfo] *new* -{"version":"FakeTSVersion","errors":true,"root":[[2,3]],"fileNames":["lib.d.ts","./a.ts","./b.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"b8af959ef8294c415b0415508643e446-export function foo() { }","signature":"7ffb4ea6089b1a385965a214ba412941-export declare function foo(): void;\n","impliedNodeFormat":1},{"version":"492f7ec5be310332dc7e2ef503772d24-export function bar() { }","signature":"2f1e9992435d5724d3e1da8bdbc17eae-export declare function bar(): void;\n","impliedNodeFormat":1}],"options":{"composite":true},"semanticDiagnosticsPerFile":[1,2,3],"latestChangedDtsFile":"./b.d.ts"} +{"version":"FakeTSVersion","errors":true,"root":[[2,3]],"fileNames":["lib.d.ts","./a.ts","./b.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"b8af959ef8294c415b0415508643e446-export function foo() { }","signature":"7ffb4ea6089b1a385965a214ba412941-export declare function foo(): void;\n","impliedNodeFormat":1},{"version":"492f7ec5be310332dc7e2ef503772d24-export function bar() { }","signature":"2f1e9992435d5724d3e1da8bdbc17eae-export declare function bar(): void;\n","impliedNodeFormat":1}],"options":{"composite":true},"latestChangedDtsFile":"./b.d.ts"} //// [/home/src/workspaces/project/tsconfig.tsbuildinfo.readable.baseline.txt] *new* { "version": "FakeTSVersion", @@ -130,20 +130,15 @@ function bar() { } "options": { "composite": true }, - "semanticDiagnosticsPerFile": [ - "lib.d.ts", - "./a.ts", - "./b.ts" - ], "latestChangedDtsFile": "./b.d.ts", - "size": 1345 + "size": 1308 } tsconfig.json:: SemanticDiagnostics:: -*not cached* /home/src/tslibs/TS/Lib/lib.d.ts -*not cached* /home/src/workspaces/project/a.ts -*not cached* /home/src/workspaces/project/b.ts +*refresh* /home/src/tslibs/TS/Lib/lib.d.ts +*refresh* /home/src/workspaces/project/a.ts +*refresh* /home/src/workspaces/project/b.ts Signatures:: (stored at emit) /home/src/workspaces/project/a.ts (stored at emit) /home/src/workspaces/project/b.ts @@ -175,9 +170,6 @@ Found 1 error in tsconfig.json:7 tsconfig.json:: SemanticDiagnostics:: -*not cached* /home/src/tslibs/TS/Lib/lib.d.ts -*not cached* /home/src/workspaces/project/a.ts -*not cached* /home/src/workspaces/project/b.ts Signatures:: @@ -209,7 +201,7 @@ function foo() { } function fooBar() { } //// [/home/src/workspaces/project/tsconfig.tsbuildinfo] *modified* -{"version":"FakeTSVersion","errors":true,"root":[[2,3]],"fileNames":["lib.d.ts","./a.ts","./b.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"12981c250647eb82bb45c5fb79732976-export function foo() { }export function fooBar() { }","signature":"f3ff291f5185ac75eeeb6de19fc28a01-export declare function foo(): void;\nexport declare function fooBar(): void;\n","impliedNodeFormat":1},{"version":"492f7ec5be310332dc7e2ef503772d24-export function bar() { }","signature":"2f1e9992435d5724d3e1da8bdbc17eae-export declare function bar(): void;\n","impliedNodeFormat":1}],"options":{"composite":true,"declaration":true},"semanticDiagnosticsPerFile":[1,2,3],"latestChangedDtsFile":"./a.d.ts"} +{"version":"FakeTSVersion","errors":true,"root":[[2,3]],"fileNames":["lib.d.ts","./a.ts","./b.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"12981c250647eb82bb45c5fb79732976-export function foo() { }export function fooBar() { }","signature":"f3ff291f5185ac75eeeb6de19fc28a01-export declare function foo(): void;\nexport declare function fooBar(): void;\n","impliedNodeFormat":1},{"version":"492f7ec5be310332dc7e2ef503772d24-export function bar() { }","signature":"2f1e9992435d5724d3e1da8bdbc17eae-export declare function bar(): void;\n","impliedNodeFormat":1}],"options":{"composite":true,"declaration":true},"latestChangedDtsFile":"./a.d.ts"} //// [/home/src/workspaces/project/tsconfig.tsbuildinfo.readable.baseline.txt] *modified* { "version": "FakeTSVersion", @@ -271,20 +263,13 @@ function fooBar() { } "composite": true, "declaration": true }, - "semanticDiagnosticsPerFile": [ - "lib.d.ts", - "./a.ts", - "./b.ts" - ], "latestChangedDtsFile": "./a.d.ts", - "size": 1433 + "size": 1396 } tsconfig.json:: SemanticDiagnostics:: -*not cached* /home/src/tslibs/TS/Lib/lib.d.ts -*not cached* /home/src/workspaces/project/a.ts -*not cached* /home/src/workspaces/project/b.ts +*refresh* /home/src/workspaces/project/a.ts Signatures:: (computed .d.ts) /home/src/workspaces/project/a.ts @@ -305,9 +290,6 @@ Found 1 error in tsconfig.json:7 tsconfig.json:: SemanticDiagnostics:: -*not cached* /home/src/tslibs/TS/Lib/lib.d.ts -*not cached* /home/src/workspaces/project/a.ts -*not cached* /home/src/workspaces/project/b.ts Signatures:: @@ -394,7 +376,4 @@ Output:: tsconfig.json:: SemanticDiagnostics:: -*refresh* /home/src/tslibs/TS/Lib/lib.d.ts -*refresh* /home/src/workspaces/project/a.ts -*refresh* /home/src/workspaces/project/b.ts Signatures:: diff --git a/testdata/baselines/reference/tsbuildWatch/configFileErrors/reports-syntax-errors-in-config-file.js b/testdata/baselines/reference/tsbuildWatch/configFileErrors/reports-syntax-errors-in-config-file.js index 1ae2b8dea6..ab961f7a18 100644 --- a/testdata/baselines/reference/tsbuildWatch/configFileErrors/reports-syntax-errors-in-config-file.js +++ b/testdata/baselines/reference/tsbuildWatch/configFileErrors/reports-syntax-errors-in-config-file.js @@ -70,7 +70,7 @@ exports.bar = bar; function bar() { } //// [/home/src/workspaces/project/tsconfig.tsbuildinfo] *new* -{"version":"FakeTSVersion","errors":true,"root":[[2,3]],"fileNames":["lib.d.ts","./a.ts","./b.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"b8af959ef8294c415b0415508643e446-export function foo() { }","signature":"7ffb4ea6089b1a385965a214ba412941-export declare function foo(): void;\n","impliedNodeFormat":1},{"version":"492f7ec5be310332dc7e2ef503772d24-export function bar() { }","signature":"2f1e9992435d5724d3e1da8bdbc17eae-export declare function bar(): void;\n","impliedNodeFormat":1}],"options":{"composite":true},"semanticDiagnosticsPerFile":[1,2,3],"latestChangedDtsFile":"./b.d.ts"} +{"version":"FakeTSVersion","errors":true,"root":[[2,3]],"fileNames":["lib.d.ts","./a.ts","./b.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"b8af959ef8294c415b0415508643e446-export function foo() { }","signature":"7ffb4ea6089b1a385965a214ba412941-export declare function foo(): void;\n","impliedNodeFormat":1},{"version":"492f7ec5be310332dc7e2ef503772d24-export function bar() { }","signature":"2f1e9992435d5724d3e1da8bdbc17eae-export declare function bar(): void;\n","impliedNodeFormat":1}],"options":{"composite":true},"latestChangedDtsFile":"./b.d.ts"} //// [/home/src/workspaces/project/tsconfig.tsbuildinfo.readable.baseline.txt] *new* { "version": "FakeTSVersion", @@ -131,20 +131,15 @@ function bar() { } "options": { "composite": true }, - "semanticDiagnosticsPerFile": [ - "lib.d.ts", - "./a.ts", - "./b.ts" - ], "latestChangedDtsFile": "./b.d.ts", - "size": 1345 + "size": 1308 } tsconfig.json:: SemanticDiagnostics:: -*not cached* /home/src/tslibs/TS/Lib/lib.d.ts -*not cached* /home/src/workspaces/project/a.ts -*not cached* /home/src/workspaces/project/b.ts +*refresh* /home/src/tslibs/TS/Lib/lib.d.ts +*refresh* /home/src/workspaces/project/a.ts +*refresh* /home/src/workspaces/project/b.ts Signatures:: (stored at emit) /home/src/workspaces/project/a.ts (stored at emit) /home/src/workspaces/project/b.ts @@ -176,9 +171,6 @@ Output:: tsconfig.json:: SemanticDiagnostics:: -*not cached* /home/src/tslibs/TS/Lib/lib.d.ts -*not cached* /home/src/workspaces/project/a.ts -*not cached* /home/src/workspaces/project/b.ts Signatures:: @@ -210,7 +202,7 @@ function foo() { } function fooBar() { } //// [/home/src/workspaces/project/tsconfig.tsbuildinfo] *modified* -{"version":"FakeTSVersion","errors":true,"root":[[2,3]],"fileNames":["lib.d.ts","./a.ts","./b.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"12981c250647eb82bb45c5fb79732976-export function foo() { }export function fooBar() { }","signature":"f3ff291f5185ac75eeeb6de19fc28a01-export declare function foo(): void;\nexport declare function fooBar(): void;\n","impliedNodeFormat":1},{"version":"492f7ec5be310332dc7e2ef503772d24-export function bar() { }","signature":"2f1e9992435d5724d3e1da8bdbc17eae-export declare function bar(): void;\n","impliedNodeFormat":1}],"options":{"composite":true,"declaration":true},"semanticDiagnosticsPerFile":[1,2,3],"latestChangedDtsFile":"./a.d.ts"} +{"version":"FakeTSVersion","errors":true,"root":[[2,3]],"fileNames":["lib.d.ts","./a.ts","./b.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"12981c250647eb82bb45c5fb79732976-export function foo() { }export function fooBar() { }","signature":"f3ff291f5185ac75eeeb6de19fc28a01-export declare function foo(): void;\nexport declare function fooBar(): void;\n","impliedNodeFormat":1},{"version":"492f7ec5be310332dc7e2ef503772d24-export function bar() { }","signature":"2f1e9992435d5724d3e1da8bdbc17eae-export declare function bar(): void;\n","impliedNodeFormat":1}],"options":{"composite":true,"declaration":true},"latestChangedDtsFile":"./a.d.ts"} //// [/home/src/workspaces/project/tsconfig.tsbuildinfo.readable.baseline.txt] *modified* { "version": "FakeTSVersion", @@ -272,20 +264,13 @@ function fooBar() { } "composite": true, "declaration": true }, - "semanticDiagnosticsPerFile": [ - "lib.d.ts", - "./a.ts", - "./b.ts" - ], "latestChangedDtsFile": "./a.d.ts", - "size": 1433 + "size": 1396 } tsconfig.json:: SemanticDiagnostics:: -*not cached* /home/src/tslibs/TS/Lib/lib.d.ts -*not cached* /home/src/workspaces/project/a.ts -*not cached* /home/src/workspaces/project/b.ts +*refresh* /home/src/workspaces/project/a.ts Signatures:: (computed .d.ts) /home/src/workspaces/project/a.ts @@ -307,9 +292,6 @@ Output:: tsconfig.json:: SemanticDiagnostics:: -*not cached* /home/src/tslibs/TS/Lib/lib.d.ts -*not cached* /home/src/workspaces/project/a.ts -*not cached* /home/src/workspaces/project/b.ts Signatures:: @@ -399,7 +381,4 @@ Output:: tsconfig.json:: SemanticDiagnostics:: -*refresh* /home/src/tslibs/TS/Lib/lib.d.ts -*refresh* /home/src/workspaces/project/a.ts -*refresh* /home/src/workspaces/project/b.ts Signatures:: From 401c4ba9fd573540dae2e296b52f87849ea552b3 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 10 Dec 2025 10:50:37 -0800 Subject: [PATCH 3/5] Deal with globals --- internal/compiler/program.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/compiler/program.go b/internal/compiler/program.go index ef7642466a..4f15f54766 100644 --- a/internal/compiler/program.go +++ b/internal/compiler/program.go @@ -1493,6 +1493,8 @@ func GetDiagnosticsOfAnyProgram( if len(allDiagnostics) == configFileParsingDiagnosticsLength { allDiagnostics = append(allDiagnostics, getSemanticDiagnostics(ctx, file)...) + // Ask for the global diagnostics again (they were empty above); we may have found new during checking, e.g. missing globals. + allDiagnostics = append(allDiagnostics, program.GetGlobalDiagnostics(ctx)...) } if (skipNoEmitCheckForDtsDiagnostics || program.Options().NoEmit.IsTrue()) && program.Options().GetEmitDeclarations() && len(allDiagnostics) == configFileParsingDiagnosticsLength { From d381d136c0de7dd363a3728edf5f541ae2d9ce8f Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 10 Dec 2025 11:12:45 -0800 Subject: [PATCH 4/5] Also delete GetGlobalDiagnostics --- internal/compiler/program.go | 17 ++++++++--------- internal/execute/incremental/program.go | 8 +------- internal/testutil/harnessutil/harnessutil.go | 1 - 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/internal/compiler/program.go b/internal/compiler/program.go index 4f15f54766..33ebf9dd2e 100644 --- a/internal/compiler/program.go +++ b/internal/compiler/program.go @@ -456,7 +456,11 @@ func (p *Program) GetBindDiagnostics(ctx context.Context, sourceFile *ast.Source } func (p *Program) GetSemanticDiagnostics(ctx context.Context, sourceFile *ast.SourceFile) []*ast.Diagnostic { - return p.collectDiagnostics(ctx, sourceFile, true /*concurrent*/, p.getSemanticDiagnosticsForFile) + diags := p.collectDiagnostics(ctx, sourceFile, true /*concurrent*/, p.getSemanticDiagnosticsForFile) + if sourceFile == nil { + diags = core.Concatenate(diags, p.getGlobalDiagnostics()) + } + return SortAndDeduplicateDiagnostics(diags) } func (p *Program) GetSemanticDiagnosticsWithoutNoEmitFiltering(ctx context.Context, sourceFiles []*ast.SourceFile) map[*ast.SourceFile][]*ast.Diagnostic { @@ -1026,7 +1030,7 @@ func emitModuleKindIsNonNodeESM(moduleKind core.ModuleKind) bool { return moduleKind >= core.ModuleKindES2015 && moduleKind <= core.ModuleKindESNext } -func (p *Program) GetGlobalDiagnostics(ctx context.Context) []*ast.Diagnostic { +func (p *Program) getGlobalDiagnostics() []*ast.Diagnostic { if len(p.files) == 0 { return nil } @@ -1041,7 +1045,7 @@ func (p *Program) GetGlobalDiagnostics(ctx context.Context) []*ast.Diagnostic { globalDiagnostics[idx] = checker.GetGlobalDiagnostics() }) - return SortAndDeduplicateDiagnostics(slices.Concat(globalDiagnostics...)) + return slices.Concat(globalDiagnostics...) } func (p *Program) GetDeclarationDiagnostics(ctx context.Context, sourceFile *ast.SourceFile) []*ast.Diagnostic { @@ -1438,7 +1442,6 @@ type ProgramLike interface { GetSyntacticDiagnostics(ctx context.Context, file *ast.SourceFile) []*ast.Diagnostic GetBindDiagnostics(ctx context.Context, file *ast.SourceFile) []*ast.Diagnostic GetProgramDiagnostics() []*ast.Diagnostic - GetGlobalDiagnostics(ctx context.Context) []*ast.Diagnostic GetSemanticDiagnostics(ctx context.Context, file *ast.SourceFile) []*ast.Diagnostic GetDeclarationDiagnostics(ctx context.Context, file *ast.SourceFile) []*ast.Diagnostic GetSuggestionDiagnostics(ctx context.Context, file *ast.SourceFile) []*ast.Diagnostic @@ -1489,15 +1492,11 @@ func GetDiagnosticsOfAnyProgram( getBindDiagnostics(ctx, file) if program.Options().ListFilesOnly.IsFalseOrUnknown() { - allDiagnostics = append(allDiagnostics, program.GetGlobalDiagnostics(ctx)...) - if len(allDiagnostics) == configFileParsingDiagnosticsLength { allDiagnostics = append(allDiagnostics, getSemanticDiagnostics(ctx, file)...) - // Ask for the global diagnostics again (they were empty above); we may have found new during checking, e.g. missing globals. - allDiagnostics = append(allDiagnostics, program.GetGlobalDiagnostics(ctx)...) } - if (skipNoEmitCheckForDtsDiagnostics || program.Options().NoEmit.IsTrue()) && program.Options().GetEmitDeclarations() && len(allDiagnostics) == configFileParsingDiagnosticsLength { + if len(allDiagnostics) == configFileParsingDiagnosticsLength && (skipNoEmitCheckForDtsDiagnostics || program.Options().NoEmit.IsTrue()) && program.Options().GetEmitDeclarations() { allDiagnostics = append(allDiagnostics, program.GetDeclarationDiagnostics(ctx, file)...) } } diff --git a/internal/execute/incremental/program.go b/internal/execute/incremental/program.go index 08a1aee121..bc8434bd63 100644 --- a/internal/execute/incremental/program.go +++ b/internal/execute/incremental/program.go @@ -137,11 +137,6 @@ func (p *Program) GetProgramDiagnostics() []*ast.Diagnostic { return p.program.GetProgramDiagnostics() } -func (p *Program) GetGlobalDiagnostics(ctx context.Context) []*ast.Diagnostic { - p.panicIfNoProgram("GetGlobalDiagnostics") - return p.program.GetGlobalDiagnostics(ctx) -} - // GetSemanticDiagnostics implements compiler.AnyProgram interface. func (p *Program) GetSemanticDiagnostics(ctx context.Context, file *ast.SourceFile) []*ast.Diagnostic { p.panicIfNoProgram("GetSemanticDiagnostics") @@ -358,8 +353,7 @@ func (p *Program) ensureHasErrorsForState(ctx context.Context, program *compiler if hasIncludeProcessingDiagnostics() || len(program.GetConfigFileParsingDiagnostics()) > 0 || len(program.GetSyntacticDiagnostics(ctx, nil)) > 0 || - len(program.GetProgramDiagnostics()) > 0 || - len(program.GetGlobalDiagnostics(ctx)) > 0 { + len(program.GetProgramDiagnostics()) > 0 { p.snapshot.hasErrors = core.TSTrue // Dont need to encode semantic errors state since the syntax and program diagnostics are encoded as present p.snapshot.hasSemanticErrors = false diff --git a/internal/testutil/harnessutil/harnessutil.go b/internal/testutil/harnessutil/harnessutil.go index 482552a77a..b49ca1f597 100644 --- a/internal/testutil/harnessutil/harnessutil.go +++ b/internal/testutil/harnessutil/harnessutil.go @@ -681,7 +681,6 @@ func compileFilesWithHost( diagnostics = append(diagnostics, program.GetProgramDiagnostics()...) diagnostics = append(diagnostics, program.GetSyntacticDiagnostics(ctx, nil)...) diagnostics = append(diagnostics, program.GetSemanticDiagnostics(ctx, nil)...) - diagnostics = append(diagnostics, program.GetGlobalDiagnostics(ctx)...) if config.CompilerOptions().GetEmitDeclarations() { diagnostics = append(diagnostics, program.GetDeclarationDiagnostics(ctx, nil)...) } From dc8b9936c2449c9416d5c79fd5a1712d3958b6ad Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 10 Dec 2025 11:36:44 -0800 Subject: [PATCH 5/5] Revert "Also delete GetGlobalDiagnostics" This reverts commit d381d136c0de7dd363a3728edf5f541ae2d9ce8f. --- internal/compiler/program.go | 17 +++++++++-------- internal/execute/incremental/program.go | 8 +++++++- internal/testutil/harnessutil/harnessutil.go | 1 + 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/internal/compiler/program.go b/internal/compiler/program.go index 33ebf9dd2e..4f15f54766 100644 --- a/internal/compiler/program.go +++ b/internal/compiler/program.go @@ -456,11 +456,7 @@ func (p *Program) GetBindDiagnostics(ctx context.Context, sourceFile *ast.Source } func (p *Program) GetSemanticDiagnostics(ctx context.Context, sourceFile *ast.SourceFile) []*ast.Diagnostic { - diags := p.collectDiagnostics(ctx, sourceFile, true /*concurrent*/, p.getSemanticDiagnosticsForFile) - if sourceFile == nil { - diags = core.Concatenate(diags, p.getGlobalDiagnostics()) - } - return SortAndDeduplicateDiagnostics(diags) + return p.collectDiagnostics(ctx, sourceFile, true /*concurrent*/, p.getSemanticDiagnosticsForFile) } func (p *Program) GetSemanticDiagnosticsWithoutNoEmitFiltering(ctx context.Context, sourceFiles []*ast.SourceFile) map[*ast.SourceFile][]*ast.Diagnostic { @@ -1030,7 +1026,7 @@ func emitModuleKindIsNonNodeESM(moduleKind core.ModuleKind) bool { return moduleKind >= core.ModuleKindES2015 && moduleKind <= core.ModuleKindESNext } -func (p *Program) getGlobalDiagnostics() []*ast.Diagnostic { +func (p *Program) GetGlobalDiagnostics(ctx context.Context) []*ast.Diagnostic { if len(p.files) == 0 { return nil } @@ -1045,7 +1041,7 @@ func (p *Program) getGlobalDiagnostics() []*ast.Diagnostic { globalDiagnostics[idx] = checker.GetGlobalDiagnostics() }) - return slices.Concat(globalDiagnostics...) + return SortAndDeduplicateDiagnostics(slices.Concat(globalDiagnostics...)) } func (p *Program) GetDeclarationDiagnostics(ctx context.Context, sourceFile *ast.SourceFile) []*ast.Diagnostic { @@ -1442,6 +1438,7 @@ type ProgramLike interface { GetSyntacticDiagnostics(ctx context.Context, file *ast.SourceFile) []*ast.Diagnostic GetBindDiagnostics(ctx context.Context, file *ast.SourceFile) []*ast.Diagnostic GetProgramDiagnostics() []*ast.Diagnostic + GetGlobalDiagnostics(ctx context.Context) []*ast.Diagnostic GetSemanticDiagnostics(ctx context.Context, file *ast.SourceFile) []*ast.Diagnostic GetDeclarationDiagnostics(ctx context.Context, file *ast.SourceFile) []*ast.Diagnostic GetSuggestionDiagnostics(ctx context.Context, file *ast.SourceFile) []*ast.Diagnostic @@ -1492,11 +1489,15 @@ func GetDiagnosticsOfAnyProgram( getBindDiagnostics(ctx, file) if program.Options().ListFilesOnly.IsFalseOrUnknown() { + allDiagnostics = append(allDiagnostics, program.GetGlobalDiagnostics(ctx)...) + if len(allDiagnostics) == configFileParsingDiagnosticsLength { allDiagnostics = append(allDiagnostics, getSemanticDiagnostics(ctx, file)...) + // Ask for the global diagnostics again (they were empty above); we may have found new during checking, e.g. missing globals. + allDiagnostics = append(allDiagnostics, program.GetGlobalDiagnostics(ctx)...) } - if len(allDiagnostics) == configFileParsingDiagnosticsLength && (skipNoEmitCheckForDtsDiagnostics || program.Options().NoEmit.IsTrue()) && program.Options().GetEmitDeclarations() { + if (skipNoEmitCheckForDtsDiagnostics || program.Options().NoEmit.IsTrue()) && program.Options().GetEmitDeclarations() && len(allDiagnostics) == configFileParsingDiagnosticsLength { allDiagnostics = append(allDiagnostics, program.GetDeclarationDiagnostics(ctx, file)...) } } diff --git a/internal/execute/incremental/program.go b/internal/execute/incremental/program.go index bc8434bd63..08a1aee121 100644 --- a/internal/execute/incremental/program.go +++ b/internal/execute/incremental/program.go @@ -137,6 +137,11 @@ func (p *Program) GetProgramDiagnostics() []*ast.Diagnostic { return p.program.GetProgramDiagnostics() } +func (p *Program) GetGlobalDiagnostics(ctx context.Context) []*ast.Diagnostic { + p.panicIfNoProgram("GetGlobalDiagnostics") + return p.program.GetGlobalDiagnostics(ctx) +} + // GetSemanticDiagnostics implements compiler.AnyProgram interface. func (p *Program) GetSemanticDiagnostics(ctx context.Context, file *ast.SourceFile) []*ast.Diagnostic { p.panicIfNoProgram("GetSemanticDiagnostics") @@ -353,7 +358,8 @@ func (p *Program) ensureHasErrorsForState(ctx context.Context, program *compiler if hasIncludeProcessingDiagnostics() || len(program.GetConfigFileParsingDiagnostics()) > 0 || len(program.GetSyntacticDiagnostics(ctx, nil)) > 0 || - len(program.GetProgramDiagnostics()) > 0 { + len(program.GetProgramDiagnostics()) > 0 || + len(program.GetGlobalDiagnostics(ctx)) > 0 { p.snapshot.hasErrors = core.TSTrue // Dont need to encode semantic errors state since the syntax and program diagnostics are encoded as present p.snapshot.hasSemanticErrors = false diff --git a/internal/testutil/harnessutil/harnessutil.go b/internal/testutil/harnessutil/harnessutil.go index b49ca1f597..482552a77a 100644 --- a/internal/testutil/harnessutil/harnessutil.go +++ b/internal/testutil/harnessutil/harnessutil.go @@ -681,6 +681,7 @@ func compileFilesWithHost( diagnostics = append(diagnostics, program.GetProgramDiagnostics()...) diagnostics = append(diagnostics, program.GetSyntacticDiagnostics(ctx, nil)...) diagnostics = append(diagnostics, program.GetSemanticDiagnostics(ctx, nil)...) + diagnostics = append(diagnostics, program.GetGlobalDiagnostics(ctx)...) if config.CompilerOptions().GetEmitDeclarations() { diagnostics = append(diagnostics, program.GetDeclarationDiagnostics(ctx, nil)...) }