Make all the codegen we do incremental - #64331
Wesley Wigham (weswigham) merged 10 commits into
Conversation
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Stringer can reuse stale output for package-wide changes, direct Go generation can lose formatter resolution, and duplicate broken test files remain.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 1
Open (3)
What changed in this PR
Adds hash-based incremental caching and force-regeneration support across repository code generators.
Changes:
- Introduces shared generated-file caching and generator utilities.
- Wraps Go and TypeScript generators with cache-aware entry points.
- Adds extensive code-generation integration tests.
| File | Description |
|---|---|
tsc/internal/vfs/vfsmatch/vfsmatch.go |
Uses cached stringer wrapper. |
tsc/internal/vfs/vfs.go |
Uses cached moq wrapper. |
tsc/internal/testutil/projecttestutil/projecttestutil.go |
Migrates mock generation. |
tsc/internal/stringutil/generate.go |
Consolidates Unicode formatting. |
tsc/internal/stringutil/_scripts/generate-unicode-data.mts |
Caches Unicode outputs. |
tsc/internal/project/project.go |
Migrates stringer generation. |
tsc/internal/ls/autoimport/export.go |
Migrates stringer generation. |
tsc/internal/diagnostics/diagnostics.go |
Uses cached diagnostics generator. |
tsc/internal/core/tristate.go |
Migrates stringer generation. |
tsc/internal/core/scriptkind.go |
Migrates stringer generation. |
tsc/internal/core/languagevariant.go |
Migrates stringer generation. |
tsc/internal/core/compileroptions.go |
Migrates stringer generation. |
tsc/internal/checker/types.go |
Migrates stringer generation. |
tsc/internal/bundled/bundled.go |
Uses cached bundle generator. |
tsc/internal/ast/kind_generated.go |
Updates generated directive. |
tools/scripts/tsc/tsconfig.json |
Extends shared generator config. |
tools/scripts/tsc/schema.ts |
Reuses shared repository root. |
tools/scripts/tsc/generate.ts |
Propagates forced regeneration. |
tools/scripts/tsc/generate-ts-ast.ts |
Caches TypeScript AST outputs. |
tools/scripts/tsc/generate-go-ast.ts |
Caches Go AST outputs. |
tools/scripts/tsc/generate-encoder.ts |
Caches protocol encoder outputs. |
tools/scripts/generatedFile.test.mts |
Adds duplicate root-level tests. |
tools/scripts/generatedFile.mts |
Adds duplicate cache implementation. |
tools/scripts/gen/utils.mts |
Adds shared generator utilities. |
tools/scripts/gen/tsconfig.json |
Configures generator type checking. |
tools/scripts/gen/generateStringer.mts |
Adds cached stringer wrapper. |
tools/scripts/gen/generateMoq.mts |
Adds cached moq wrapper. |
tools/scripts/gen/generateDiagnostics.mts |
Adds cached diagnostics generation. |
tools/scripts/gen/generatedFile.test.mts |
Tests incremental generation. |
tools/scripts/gen/generatedFile.mts |
Implements generated-output caching. |
tools/scripts/gen/generateBundled.mts |
Adds cached library bundling. |
tools/scripts/gen/generateAPI.mts |
Adds cached API generation. |
packages/typescript/scripts/generateSync.ts |
Caches sync API outputs. |
packages/typescript/scripts/generate.ts |
Coordinates package generators. |
packages/typescript/package.json |
Uses unified package generator. |
Herebyfile.mjs |
Adds force handling and cached tasks. |
Files not reviewed (1)
- tsc/internal/ast/kind_generated.go: Generated file
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The cache implementation validates inputs and outputs, handles failed or concurrent input changes safely, supports forced regeneration, and includes broad integration coverage.
Review effort: Balanced
Findings: None
Resolved since last review (3)
Files not reviewed (1)
- tsc/internal/ast/kind_generated.go: Generated file
…asks - go:generate directives only for compat
Jake Bailey (jakebailey)
left a comment
There was a problem hiding this comment.
We're doing a bunch of discussion off thread on Teams; I'm sort of leaning back to "maybe we should just move code generation into scripts and leave go generate for convenience" to avoid this getting too complicated and avoid the go generate overhead... Then just have hereby generate as "the thing to run" and it's incremental and that's that.
I do think that this is maybe a bit too complicated. But maybe it's whatever and we could just later future changes on it?
| npx hereby generate # Regenerate compiler sources and bundled assets | ||
| npx hereby generate:all # Also regenerate AST, LSP, APIs, localization, and vendored files |
There was a problem hiding this comment.
I think these might be out of date, if hereby generate now does everything for you, right?
Why would we want :all at all?
There was a problem hiding this comment.
hereby generate does everything go generate would find, hereby generate:all does all generate-prefixed tasks, which is a handful more.
There was a problem hiding this comment.
I don't think back compat really matters, is there any reason we wouldn't always run generate:all and therefore it should just be generate, and the Go code is relegated to generate:go?
There was a problem hiding this comment.
I can rename 'em if you'd like. Just left 'em like that because npx hereby generate just called out to go generate before.
There was a problem hiding this comment.
I think renaming is a good idea. When I introduced hereby generate, the only code we had to generate was go generate generated.
There was a problem hiding this comment.
I pushed the rename for ya.
Yep - I just pushed those changes (and a merge commit fix) - I think I actually raced Andrew Branch (@andrewbranch) 's review there, so I'll re-request. I'm still collecting metrics, but it's promising thus far - cold generate calls are 5-10% faster, and warm ones are like 30%+ faster (which cascades into making |
ed9b879 to
072ae95
Compare
|
I think this is looking good, my only suggestion would be that the logging doesn't show much what's going on, like: Compared to |
|
That's pretty fair - the logging got simplified as I merged helpers from the first version and it got a wee bit too simple. |
|
Jake Bailey (@jakebailey) There ya go, output of the cache layer's a bit more verbose. |



This PR adds incremental cache wrappers around all of the codegen we perform in the repo, which, experimentally, can cut up to 80% of the time off of some
generatesubtasks if the cached results are reusable. Very useful if you have an agent repeatedly running them just in case it modified a file that affects codegen.