Skip to content

Codegen Go and TypeScript SyntaxKinds, ASTs, factories, visitors, type guards, encoders, decoders#3367

Merged
andrewbranch merged 71 commits intomicrosoft:mainfrom
andrewbranch:ast-codegen
Apr 10, 2026
Merged

Codegen Go and TypeScript SyntaxKinds, ASTs, factories, visitors, type guards, encoders, decoders#3367
andrewbranch merged 71 commits intomicrosoft:mainfrom
andrewbranch:ast-codegen

Conversation

@andrewbranch
Copy link
Copy Markdown
Member

@andrewbranch andrewbranch commented Apr 8, 2026

Thanks to @virtulis for some additional tests; supersedes #3195.

I will try to list the more interesting changes here, but I recommend just looking at the changed files that are not thousands of lines of generated code diff to see where usage actually changed; it's fairly small.

Actual AST changes made:

  • Renamed SyntaxKind.JSDocTag to SyntaxKind.JSDocUnknownTag
  • Deleted SyntaxKind.CommaListExpression (unused in Corsa)
  • In Corsa, reordered VariableDeclarationList factory params to align with Strada
  • Some scalar properties were previously left out of factory update functions for unclear reasons; they are universally included now.

Cosmetic AST changes made to Corsa:

  • As casts always match their struct name, e.g. AsTypeParameter()AsTypeParameterDeclaration()
  • Embedding hierarchy expanded to match branded interfaces in Strada, e.g. PrefixUnaryExpression goes from embedding ExpressionBase directly to a chain of UpdateExpressionBaseUnaryExpressionBaseExpressionBase, because these give the corresponding TypeScript interface _updateExpressionBrand, _unaryExpressionBrand, and so on.
  • Every node automatically gets a named type alias for Node and those aliases are consistently used in struct field types and factory/visitor parameters.

Making changes

  • edit _scripts/ast.json
  • run hereby generate:ast

virtulis added 30 commits March 22, 2026 01:06
# Conflicts:
#	internal/api/encoder/decoder.go
# Conflicts:
#	_packages/api/src/node/encoder.ts
#	internal/api/encoder/encoder.go
# Conflicts:
#	_packages/api/test/async/api.test.ts
#	_packages/api/test/sync/api.test.ts
#	_packages/ast/src/is.ts
@andrewbranch andrewbranch requested a review from Copilot April 9, 2026 05:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR moves AST infrastructure toward a schema-driven codegen pipeline, generating Go/TypeScript AST types and protocol helpers while removing older per-package generators.

Changes:

  • Introduces schema + generators to emit Go AST/kind definitions and TS AST scaffolding.
  • Switches @typescript/ast consumers from nodes.ts/hand generators to ast.ts + generated factory/visitor artifacts.
  • Refactors encoder/RemoteNode infrastructure to rely on generated protocol tables and node accessors; updates CI and tests accordingly.

Reviewed changes

Copilot reviewed 57 out of 134 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
_scripts/generate-go-ast.ts New generator for Go AST structs, factories, visitors, kind guards, and kind enum output.
_scripts/ast.schema.json Adds JSON schema for AST definition inputs used by generators.
_packages/ast/src/scanner.ts Updates scanner typings/imports and defines a JSDoc token-kind union tied to SyntaxKind.
_packages/ast/src/index.ts Re-exports new ast.ts surface and drops nodes.ts export.
_packages/ast/src/enums/tokenFlags.ts Updates generated-file header to new Hereby generator format.
_packages/ast/src/enums/tokenFlags.enum.ts Updates generated-file header to new Hereby generator format.
_packages/ast/src/enums/syntaxKind.ts Updates generated SyntaxKind output and header to reference kind_generated.go.
_packages/ast/src/enums/syntaxKind.enum.ts Updates generated SyntaxKind enum output and header to reference kind_generated.go.
_packages/ast/src/enums/outerExpressionKinds.ts New generated JS enum output for OuterExpressionKinds.
_packages/ast/src/enums/outerExpressionKinds.enum.ts New generated TS enum output for OuterExpressionKinds.
_packages/ast/src/enums/nodeFlags.ts Updates generated-file header to new Hereby generator format.
_packages/ast/src/enums/nodeFlags.enum.ts Updates generated-file header to new Hereby generator format.
_packages/ast/src/enums/modifierFlags.ts Updates generated-file header to new Hereby generator format.
_packages/ast/src/enums/modifierFlags.enum.ts Updates generated-file header to new Hereby generator format.
_packages/ast/src/clone.ts Switches to generated factory imports and updates literal cloning to carry tokenFlags.
_packages/ast/src/astnav.ts Switches to ast.ts + generated factory types; fixes JSDoc kind guard naming and token factory typing.
_packages/ast/src/ast.ts New hand-written AST facade layering generated AST types + core shared interfaces.
_packages/ast/scripts/generateVisitor.ts Removes legacy visitor generator script (now superseded by schema-driven generation).
_packages/ast/scripts/generateFactory.ts Removes legacy factory generator script (now superseded by schema-driven generation).
_packages/ast/package.json Updates exports/scripts to use generated factory and new generate:ast script.
_packages/api/test/sync/ast.test.ts Updates tests for new AST type names and updated factory signatures/flags.
_packages/api/test/sync/api.test.ts Adds roundtrip/clone coverage and factors out tsserver path helper.
_packages/api/test/encoder.test.ts Adjusts encoder tests to updated factory signatures and RemoteNode typing.
_packages/api/test/async/api.test.ts Mirrors sync test additions/updates for async API and clone/roundtrip checks.
_packages/api/src/node/protocol.ts Removes hand-maintained childProperties table and re-exports generated protocol tables.
_packages/api/src/node/protocol.generated.ts Adds generated childProperties + singleChildNodePropertyNames tables.
_packages/api/src/node/node.ts Splits heavy RemoteNode code into generated + infrastructure modules and re-exports public surface.
_packages/api/src/node/node.infrastructure.ts New shared infrastructure helpers/constants for RemoteNode decoding.
_packages/api/src/node/node.generated.ts Adds generated RemoteNode/RemoteNodeList implementation and generated property getters.
_packages/api/src/node/encoder.ts Refactors encoder to use generated node-data helpers and new child-presence semantics.
_packages/api/src/node/encoder.generated.ts Adds generated helpers for node-data typing + common-data bit packing.
_packages/api/src/enums/typePredicateKind.ts Updates generated-file header to new Hereby generator format.
_packages/api/src/enums/typePredicateKind.enum.ts Updates generated-file header to new Hereby generator format.
_packages/api/src/enums/typeFlags.ts Updates generated-file header to new Hereby generator format.
_packages/api/src/enums/typeFlags.enum.ts Updates generated-file header to new Hereby generator format.
_packages/api/src/enums/symbolFlags.ts Updates generated-file header to new Hereby generator format.
_packages/api/src/enums/symbolFlags.enum.ts Updates generated-file header to new Hereby generator format.
_packages/api/src/enums/signatureKind.ts Updates generated-file header to new Hereby generator format.
_packages/api/src/enums/signatureKind.enum.ts Updates generated-file header to new Hereby generator format.
_packages/api/src/enums/signatureFlags.ts Updates generated-file header to new Hereby generator format.
_packages/api/src/enums/signatureFlags.enum.ts Updates generated-file header to new Hereby generator format.
_packages/api/src/enums/objectFlags.ts Updates generated-file header to new Hereby generator format.
_packages/api/src/enums/objectFlags.enum.ts Updates generated-file header to new Hereby generator format.
_packages/api/src/enums/elementFlags.ts Updates generated-file header to new Hereby generator format.
_packages/api/src/enums/elementFlags.enum.ts Updates generated-file header to new Hereby generator format.
_packages/api/src/enums/diagnosticCategory.ts Updates generated-file header to new Hereby generator format.
_packages/api/src/enums/diagnosticCategory.enum.ts Updates generated-file header to new Hereby generator format.
_packages/api/package.json Adds encoder generation step and updates generator scripts to new pipeline.
Herebyfile.mjs Adds generate:ast task, updates SyntaxKind enum source, and standardizes TS enum headers.
.github/workflows/ci.yml Updates CI generation steps to run generate:ast instead of older package scripts.

@andrewbranch andrewbranch marked this pull request as ready for review April 9, 2026 23:02

export function modifierToFlag(kind: SyntaxKind): ModifierFlags {
switch (kind) {
case SyntaxKind.StaticKeyword:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Curious if this could be generated, given it seems 1:1

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Surely. ModifierFlags are currently generated from the Go source the way other enums (besides SyntaxKind, now) are, so there would be a bit more setup to do this correctly, but it would be nice.

@@ -0,0 +1,5515 @@
{
"$schema": "./ast.schema.json",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

In a way I wish we'd use a more compact language like KDL, or a JS file with a little DSL, but, JSON is ubiquitous, so

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I was also tempted to use KDL, but I figured anything besides JSON would be controversial, having schema support is nice, importing with no processing is nice, and any other choice would be controversial, but it would be free to switch down the road if we want.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah, the JSON schema thing is helpful.

Evil voice: it would work for yaml too

Comment on lines +568 to +574
// PropertySignatureDeclaration
// MethodSignatureDeclaration
// IndexSignatureDeclaration
// CallSignatureDeclaration
// ConstructSignatureDeclaration
//
// PropertySignature:
// PropertySignatureDeclaration:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

were these things from the spec? or is this rename okay?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

There was a replace-all that got much more than intended (same thing that caused the accidental checker.Type method change) which I tried to undo everything undesriable, but I thought these were talking about node kinds, so I left them. Now that you mention it, I think it was copied from the spec, but I don't know how relevant that is now. I'm ambivalent about this; do you want me to undo it?

Copy link
Copy Markdown
Member

@jakebailey jakebailey Apr 10, 2026

Choose a reason for hiding this comment

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

Probably doesn't matter that much, outside them matching Strada's comments

Copy link
Copy Markdown
Member

@jakebailey jakebailey left a comment

Choose a reason for hiding this comment

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

LGTM, but if you want to do the other additions I won't complain 😄

Will probably conflict with whatever @ahejlsberg is doing with reparsing, but hopefully not too hard to fix up.

@andrewbranch andrewbranch added this pull request to the merge queue Apr 10, 2026
@andrewbranch
Copy link
Copy Markdown
Member Author

There are things that I'd like to improve and additional things I'd like to generate, but need to get some more time-sensitive stuff out of the way first.

Merged via the queue into microsoft:main with commit 1933459 Apr 10, 2026
21 checks passed
@andrewbranch andrewbranch deleted the ast-codegen branch April 10, 2026 16:10
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.

5 participants