Skip to content

Ditch nodeData interface in favor of generated accessors - #64063

Draft
Jake Bailey (jakebailey) wants to merge 9 commits into
microsoft:mainfrom
jakebailey:redo-ast-method-dispatch-opt
Draft

Ditch nodeData interface in favor of generated accessors#64063
Jake Bailey (jakebailey) wants to merge 9 commits into
microsoft:mainfrom
jakebailey:redo-ast-method-dispatch-opt

Conversation

@jakebailey

@jakebailey Jake Bailey (jakebailey) commented Aug 28, 2026

Copy link
Copy Markdown
Member

WIP

@jakebailey

Copy link
Copy Markdown
Member Author

TypeScript Bot (@typescript-bot) perf test this

@typescript-automation

typescript-automation Bot commented Aug 28, 2026

Copy link
Copy Markdown

Starting jobs; this comment will be updated as builds start and complete.

Command Status Results
perf test this ✅ Started 👀 Results

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Replaces nodeData interface dispatch with generated kind-based AST accessors to reduce binary size and metadata overhead.

Changes:

  • Generates AST visitor, clone, subtree-fact, and accessor dispatch.
  • Updates compiler and language-service consumers for the new representation.
  • Adds canonical token-payload validation and adjusts direct node construction.

Reviewed changes

Copilot reviewed 23 out of 25 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tools/scripts/tsc/generate-go-ast.ts Generates kind-based AST dispatch.
tools/scripts/tsc/generate-encoder.ts Updates generated private-field access.
tsc/internal/ast/ast.go Reworks node storage and common fields.
tsc/internal/ast/ast_generated.go Contains generated factories and dispatch.
tsc/internal/ast/flow.go Adapts synthetic flow-node construction.
tsc/internal/ast/token_test.go Tests canonical token payloads.
tsc/internal/ast/utilities.go Updates type-only checks.
tsc/internal/api/encoder/encoder.go Updates source-file position access.
tsc/internal/api/encoder/encoder_generated.go Updates generated text access.
tsc/internal/checker/grammarchecks.go Uses common node accessors.
tsc/internal/checker/nodebuilder_hover.go Updates optional-token access.
tsc/internal/ls/autoimport/fix.go Updates type-only import access.
tsc/internal/ls/completions.go Updates source-file access.
tsc/internal/ls/lsutil/organizeimports.go Updates import classification.
tsc/internal/ls/organizeimports.go Updates type-only grouping.
tsc/internal/ls/signaturehelp.go Updates type-argument access.
tsc/internal/parser/reparser.go Updates mutable typed-node casts.
tsc/internal/printer/printer_test.go Adapts transformed source-file casts.
tsc/internal/scanner/scanner_test.go Adapts node initialization.
tsc/internal/transformers/declarations/transform.go Updates syntax-list traversal.
tsc/internal/transformers/estransforms/optionalchain.go Updates element-access casting.
tsc/internal/transformers/moduletransforms/commonjsmodule.go Updates common expression/name access.
tsc/internal/transformers/tstransforms/legacydecorators.go Updates decorator access.
tsc/internal/transformers/tstransforms/runtimesyntax.go Updates parameter-list access.
tsc/internal/transformers/tstransforms/typeeraser.go Updates type-only import access.
Files not reviewed (1)
  • tsc/internal/api/encoder/encoder_generated.go: Generated file
Suppressed comments (1)

tsc/internal/ast/flow.go:74

  • This node likewise stores *FlowReduceLabelData under KindUnknown, while the generated Clone and subtree-facts switches assert that every KindUnknown payload is *Token. Those methods now panic for reduce-label nodes; previously dynamic dispatch reached NodeDefault. Use a distinct kind or explicitly handle this synthetic payload in dispatch, with a regression test.
	return newNode(KindUnknown, node.AsNode(), node, NodeFactoryHooks{})

Comment thread tsc/internal/ast/flow.go Outdated
@typescript-automation

Copy link
Copy Markdown

Jake Bailey (@jakebailey)
The results of the perf run you requested are in!

Here they are:

tsc

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
Compiler-Unions - native
Errors 41 41 ~ ~ ~ p=1.000 n=12
Symbols 115,480 115,480 ~ ~ ~ p=1.000 n=12
Types 96,945 96,945 ~ ~ ~ p=1.000 n=12
Memory Used 148,704k (± 0.63%) 148,990k (± 0.61%) ~ 146,603k 150,783k p=0.619 n=12
Memory Allocs 2,271,343 (± 0.00%) 2,271,370 (± 0.01%) ~ 2,271,042 2,271,725 p=0.799 n=12
Config Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Parse Time 0.050s (± 3.10%) 0.049s (± 2.83%) ~ 0.046s 0.053s p=0.525 n=12
Bind Time 0.016s (±13.70%) 0.017s (±12.12%) ~ 0.013s 0.022s p=0.462 n=12
Check Time 0.593s (± 0.79%) 0.602s (± 0.99%) +0.009s (+ 1.50%) 0.592s 0.618s p=0.016 n=12
Emit Time 0.331s (± 2.03%) 0.338s (± 1.95%) ~ 0.322s 0.356s p=0.096 n=12
Total Time 0.997s (± 1.07%) 1.013s (± 0.89%) +0.016s (+ 1.62%) 0.993s 1.038s p=0.011 n=12
angular-1 - native
Errors 3 3 ~ ~ ~ p=1.000 n=12
Symbols 847,457 (± 0.08%) 847,042 (± 0.06%) ~ 845,864 848,120 p=0.242 n=12
Types 249,852 (± 0.00%) 249,853 (± 0.00%) ~ 249,849 249,862 p=0.497 n=12
Memory Used 793,348k (± 0.05%) 793,428k (± 0.06%) ~ 791,771k 794,529k p=0.410 n=12
Memory Allocs 12,951,967 (± 0.02%) 12,954,725 (± 0.04%) ~ 12,948,861 12,981,625 p=0.319 n=12
Config Time 0.020s 0.022s (± 5.61%) 🔻+0.002s (+ 9.17%) 0.020s 0.024s p=0.005 n=12
Parse Time 0.348s (± 2.62%) 0.358s (± 2.93%) ~ 0.331s 0.382s p=0.213 n=12
Bind Time 0.079s (±10.71%) 0.079s (± 1.48%) +0.000s (+ 0.42%) 0.077s 0.084s p=0.014 n=12
Check Time 0s 0s ~ ~ ~ p=1.000 n=12
Emit Time 1.964s (± 1.37%) 2.067s (± 1.06%) 🔻+0.103s (+ 5.23%) 2.020s 2.117s p=0.000 n=12
Total Time 2.430s (± 1.24%) 2.544s (± 1.07%) 🔻+0.114s (+ 4.68%) 2.491s 2.619s p=0.000 n=12
mui-docs - native
Errors 11,277 (± 0.03%) 11,274 (± 0.05%) ~ 11,256 11,281 p=0.656 n=12
Symbols 4,268,528 4,268,528 ~ ~ ~ p=1.000 n=12
Types 1,593,260 1,593,260 ~ ~ ~ p=1.000 n=12
Memory Used 4,727,424k (± 0.04%) 4,726,863k (± 0.04%) ~ 4,722,770k 4,733,595k p=0.514 n=12
Memory Allocs 47,631,206 (± 0.03%) 47,634,270 (± 0.05%) ~ 47,568,063 47,703,849 p=0.977 n=12
Config Time 0.019s (± 1.60%) 0.019s (± 1.60%) ~ 0.019s 0.020s p=1.000 n=12
Parse Time 0.679s (± 2.38%) 0.686s (± 1.47%) ~ 0.655s 0.706s p=0.451 n=12
Bind Time 0.002s (±12.64%) 0.002s (±13.40%) ~ 0.002s 0.003s p=0.667 n=12
Check Time 19.824s (± 0.54%) 19.921s (± 0.51%) ~ 19.751s 20.285s p=0.071 n=12
Emit Time 0.556s (±14.37%) 0.517s (± 0.44%) ~ 0.512s 0.524s p=0.053 n=12
Total Time 22.005s (± 0.72%) 22.063s (± 0.55%) ~ 21.839s 22.492s p=0.443 n=12
strada-build-src - native
Errors 0 0 ~ ~ ~ p=1.000 n=12
Symbols 1,394,252 1,394,252 ~ ~ ~ p=1.000 n=12
Types 443,418 443,418 ~ ~ ~ p=1.000 n=12
Memory Used 1,644,285k (± 0.19%) 1,644,608k (± 0.21%) ~ 1,632,450k 1,651,134k p=0.630 n=12
Memory Allocs 97,050,478 (± 0.03%) 97,054,471 (± 0.03%) ~ 96,986,967 97,119,845 p=0.932 n=12
Config Time 0.006s (±11.44%) 0.005s (±16.17%) ~ 0.002s 0.007s p=0.971 n=12
Parse Time 0.236s (± 2.51%) 0.235s (± 2.67%) ~ 0.218s 0.247s p=0.921 n=12
Bind Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Check Time 2.158s (± 0.34%) 2.193s (± 0.55%) +0.036s (+ 1.67%) 2.159s 2.224s p=0.000 n=12
Emit Time 0.328s (± 3.83%) 0.335s (± 6.32%) ~ 0.290s 0.391s p=0.788 n=12
Total Time 29.760s (± 0.46%) 30.237s (± 0.55%) +0.477s (+ 1.60%) 29.761s 30.659s p=0.000 n=12
strada-compiler - native
Errors 0 0 ~ ~ ~ p=1.000 n=12
Symbols 337,531 337,531 ~ ~ ~ p=1.000 n=12
Types 198,830 198,830 ~ ~ ~ p=1.000 n=12
Memory Used 319,525k (± 0.03%) 319,545k (± 0.02%) ~ 319,381k 319,705k p=0.713 n=12
Memory Allocs 4,672,822 (± 0.01%) 4,672,757 (± 0.01%) ~ 4,671,682 4,673,967 p=0.590 n=12
Config Time 0.001s 0.001s ~ ~ ~ p=1.000 n=12
Parse Time 0.112s (± 5.15%) 0.113s (± 4.16%) ~ 0.097s 0.123s p=0.680 n=12
Bind Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Check Time 1.039s (± 0.58%) 1.057s (± 0.52%) +0.019s (+ 1.79%) 1.044s 1.076s p=0.000 n=12
Emit Time 0.131s (±13.99%) 0.142s (±10.03%) ~ 0.104s 0.167s p=0.417 n=12
Total Time 1.341s (± 0.99%) 1.366s (± 0.98%) +0.024s (+ 1.81%) 1.329s 1.398s p=0.016 n=12
ts-pre-modules - native
Errors 87 87 ~ ~ ~ p=1.000 n=12
Symbols 305,179 305,179 ~ ~ ~ p=1.000 n=12
Types 181,876 181,876 ~ ~ ~ p=1.000 n=12
Memory Used 277,177k (± 0.02%) 277,249k (± 0.02%) ~ 277,119k 277,401k p=0.058 n=12
Memory Allocs 1,641,802 (± 0.01%) 1,641,776 (± 0.01%) ~ 1,641,330 1,642,158 p=0.977 n=12
Config Time 0.000s 0.000s (±217.90%) ~ 0.000s 0.001s p=1.000 n=12
Parse Time 0.098s (± 4.32%) 0.101s (± 1.97%) +0.003s (+ 3.06%) 0.094s 0.107s p=0.027 n=12
Bind Time 0.039s (±11.25%) 0.040s (±10.20%) ~ 0.033s 0.054s p=0.432 n=12
Check Time 0.831s (± 0.67%) 0.846s (± 0.38%) +0.015s (+ 1.79%) 0.838s 0.855s p=0.000 n=12
Emit Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Total Time 0.983s (± 0.91%) 1.001s (± 0.42%) +0.019s (+ 1.92%) 0.991s 1.013s p=0.001 n=12
vscode - native
Errors 347 347 ~ ~ ~ p=1.000 n=12
Symbols 8,099,608 8,099,608 ~ ~ ~ p=1.000 n=12
Types 2,787,191 2,787,191 ~ ~ ~ p=1.000 n=12
Memory Used 5,473,265k (± 0.02%) 5,473,514k (± 0.03%) ~ 5,470,222k 5,479,175k p=0.799 n=12
Memory Allocs 42,145,509 (± 0.04%) 42,141,955 (± 0.04%) ~ 42,120,291 42,208,283 p=0.843 n=12
Config Time 0.064s (± 0.51%) 0.064s (± 0.28%) ~ 0.063s 0.064s p=1.000 n=12
Parse Time 1.672s (± 1.61%) 1.598s (± 3.19%) 🟩-0.074s (- 4.42%) 1.469s 1.691s p=0.015 n=12
Bind Time 0.351s (± 2.84%) 0.432s (±19.96%) 🔻+0.081s (+23.13%) 0.354s 0.692s p=0.000 n=12
Check Time 10.073s (± 0.87%) 10.107s (± 1.63%) ~ 9.712s 10.376s p=0.630 n=12
Emit Time 3.226s (± 5.89%) 3.789s (±13.24%) 🔻+0.563s (+17.46%) 3.103s 5.028s p=0.006 n=12
Total Time 15.475s (± 0.75%) 16.084s (± 2.40%) +0.608s (+ 3.93%) 15.409s 17.070s p=0.000 n=12
webpack - native
Errors 538 538 ~ ~ ~ p=1.000 n=12
Symbols 857,681 857,681 ~ ~ ~ p=1.000 n=12
Types 394,496 394,496 ~ ~ ~ p=1.000 n=12
Memory Used 656,000k (± 0.02%) 656,131k (± 0.03%) ~ 655,790k 656,556k p=0.266 n=12
Memory Allocs 4,378,603 (± 0.04%) 4,376,261 (± 0.02%) -2,342 (- 0.05%) 4,374,294 4,379,723 p=0.045 n=12
Config Time 0.007s 0.007s ~ ~ ~ p=1.000 n=12
Parse Time 0.173s (± 1.29%) 0.168s (± 3.73%) ~ 0.147s 0.182s p=0.102 n=12
Bind Time 0.033s (± 2.54%) 0.041s (±19.61%) 🔻+0.008s (+23.12%) 0.033s 0.069s p=0.012 n=12
Check Time 1.143s (± 0.65%) 1.158s (± 0.95%) +0.015s (+ 1.33%) 1.122s 1.173s p=0.005 n=12
Emit Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Total Time 1.375s (± 0.43%) 1.394s (± 0.73%) +0.019s (+ 1.37%) 1.364s 1.420s p=0.002 n=12
xstate-main - native
Errors 0 0 ~ ~ ~ p=1.000 n=12
Symbols 1,022,487 1,022,487 ~ ~ ~ p=1.000 n=12
Types 376,962 376,962 ~ ~ ~ p=1.000 n=12
Memory Used 603,384k (± 0.02%) 603,441k (± 0.01%) ~ 603,289k 603,638k p=0.755 n=12
Memory Allocs 4,754,818 (± 0.04%) 4,755,010 (± 0.04%) ~ 4,750,794 4,759,753 p=0.799 n=12
Config Time 0.002s 0.002s ~ ~ ~ p=1.000 n=12
Parse Time 0.117s (± 3.29%) 0.116s (± 4.46%) ~ 0.106s 0.132s p=0.722 n=12
Bind Time 0.035s (±20.33%) 0.035s (±17.12%) ~ 0.026s 0.056s p=0.394 n=12
Check Time 0.853s (± 0.67%) 0.862s (± 0.88%) ~ 0.845s 0.882s p=0.075 n=12
Emit Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Total Time 1.015s (± 1.02%) 1.026s (± 1.01%) ~ 1.000s 1.049s p=0.109 n=12
System info unknown
Hosts
  • native
Scenarios
  • Compiler-Unions - native
  • angular-1 - native
  • mui-docs - native
  • strada-build-src - native
  • strada-compiler - native
  • ts-pre-modules - native
  • vscode - native
  • webpack - native
  • xstate-main - native
Benchmark Name Iterations
Current pr 12
Baseline baseline 12

lsp

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
Compiler-UnionsLSP - native
Req 1 - updateOpen 15ms (± 3.34%) 15ms (± 2.92%) ~ 14ms 16ms p=0.744 n=12
Req 2 - geterr 682ms (± 0.36%) 690ms (± 0.49%) +7ms (+ 1.09%) 679ms 698ms p=0.001 n=12
Req 3 - references 58ms (± 4.72%) 58ms (± 6.84%) ~ 47ms 63ms p=0.965 n=12
Req 4 - navto 20ms (± 4.17%) 19ms (± 1.60%) ~ 19ms 20ms p=0.052 n=12
Req 5 - completionInfo count 1,363 1,363 ~ ~ ~ p=1.000 n=12
Req 5 - completionInfo 19ms (±10.74%) 18ms (± 6.66%) ~ 16ms 21ms p=0.371 n=12
CompilerLSP - native
Req 1 - updateOpen 13ms (± 6.39%) 13ms (± 3.72%) ~ 12ms 14ms p=0.863 n=12
Req 2 - geterr 295ms (± 0.73%) 301ms (± 0.58%) +6ms (+ 2.09%) 298ms 305ms p=0.000 n=12
Req 3 - references 51ms (± 3.62%) 51ms (± 4.89%) ~ 46ms 56ms p=0.501 n=12
Req 4 - navto 18ms (± 4.47%) 17ms (± 2.95%) ~ 16ms 18ms p=0.309 n=12
Req 5 - completionInfo count 1,525 1,525 ~ ~ ~ p=1.000 n=12
Req 5 - completionInfo 17ms (± 8.93%) 18ms (± 6.14%) ~ 15ms 20ms p=0.512 n=12
System info unknown
Hosts
  • native
Scenarios
  • CompilerLSP - native
  • Compiler-UnionsLSP - native
  • xstate-main-1-LSP - native
Benchmark Name Iterations
Current pr 12
Baseline baseline 12

startup

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
lsp-startup - native
Execution time 4.90ms (±365.09%) 4.72ms (±365.09%) 🟩-0.18ms (- 3.72%) 0.00ms 473.73ms p=0.000 n=1200
tsgo-startup - native
Execution time 4.90ms (±365.10%) 4.72ms (±365.10%) 🟩-0.18ms (- 3.67%) 0.00ms 473.43ms p=0.000 n=1200
System info unknown
Hosts
  • native
Scenarios
  • lsp-startup - native
  • tsgo-startup - native
Benchmark Name Iterations
Current pr 12
Baseline baseline 12

Developer Information:

Download Benchmarks

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 26 changed files in this pull request and generated no new comments.

Files not reviewed (2)
  • tsc/internal/api/encoder/encoder_generated.go: Generated file
  • tsc/internal/ast/kind_stringer_generated.go: Generated file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants