Skip to content

Conversation

@kyleconroy
Copy link
Collaborator

Replace the template-based code generation in the Go codegen with
programmatic generation using direct AST-like buffer writes.

Changes:

  • Add internal/poet package with helpers for Go code generation
  • Add internal/codegen/golang/generator.go with CodeGenerator
  • Update gen.go to use CodeGenerator instead of templates
  • Remove template.go and embedded templates

The new approach:

  • Generates identical output to the previous templates
  • More maintainable and easier to debug
  • Type-safe code generation without string interpolation
  • Better IDE support and code navigation

All existing tests pass with no changes to expected output.

Replace the template-based code generation in the Go codegen with
programmatic generation using direct AST-like buffer writes.

Changes:
- Add internal/poet package with helpers for Go code generation
- Add internal/codegen/golang/generator.go with CodeGenerator
- Update gen.go to use CodeGenerator instead of templates
- Remove template.go and embedded templates

The new approach:
- Generates identical output to the previous templates
- More maintainable and easier to debug
- Type-safe code generation without string interpolation
- Better IDE support and code navigation

All existing tests pass with no changes to expected output.
@dosubot dosubot bot added size:XXL This PR changes 1000+ lines, ignoring generated files. 🔧 golang labels Jan 5, 2026
claude added 17 commits January 5, 2026 15:05
Redesign the poet package to use custom AST structures specifically
designed for Go code generation instead of wrapping go/ast types.

Key changes:
- New ast.go: Custom types (File, Import, Decl, TypeDef, Func, Struct,
  Field, Interface, etc.) with proper support for comments
- New render.go: Rendering logic that converts custom AST to formatted
  Go source code with proper comment placement
- ImportGroups: Support for separating stdlib and third-party imports
  with blank lines between groups
- TrailingComment: Support for trailing comments on struct fields
  (e.g., "Valid is true if X is not NULL")

Removed old poet package files (expr.go, func.go, poet.go, stmt.go,
types.go) that wrapped go/ast which made comment placement difficult.

The generator.go now builds poet.File structures and calls poet.Render()
to produce formatted Go code that exactly matches the previous output.
…mplates

Add AST support for structured function bodies:
- Return: return statement with multiple values
- For: traditional for loop and range-based iteration
- If: if/else statements with optional init clause

Enhance Param type:
- Add Pointer boolean field to indicate pointer types instead of
  requiring "*" prefix in the Type string

Delete unused templates:
- Remove internal/codegen/golang/templates/ directory containing
  .tmpl files that are no longer used after switching to poet-based
  code generation
Add Switch statement AST node:
- Switch: switch statement with optional init and expression
- Case: case clause with values (empty for default)

Breaking change to Func struct:
- Remove Body field to force use of Stmts
- Update all usages in generator.go to use Stmts with RawStmt

This enforces consistent use of the structured statement API
instead of allowing raw body strings as an escape hatch.
Replace RawStmt usage with structured statement types where applicable:
- poet.Return for return statements
- poet.Switch for switch statements
- poet.If for if statements

Also:
- Use Pointer field on Param instead of "*" prefix in Type
- Format multi-value switch cases on separate lines
- Keep line lengths under 90 chars for readability

This makes the code generation more structured and type-safe while
maintaining identical output.
Add new statement AST nodes:
- Defer: defer statements (defer expr)
- Assign: assignment statements (left op right)
- CallStmt: function call statements

Update generator.go to use structured statements:
- Convert RawStmt assignments to poet.Assign
- Eliminates manual tab management for these statements

The rendering handles indentation automatically, making the code
more maintainable and less error-prone.
…tements

Add VarDecl statement type to poet package for variable declarations
inside function bodies (e.g., "var items []Type").

Convert all standard SQL driver query functions to use structured
poet statements instead of strings.Builder:
- addQueryOneStd: uses Assign, VarDecl, If, Return
- addQueryManyStd: uses Assign, VarDecl, Defer, For, If, Return
- addQueryExecRowsStd: uses Assign, If, Return
- addQueryExecLastIDStd: uses Assign, If, Return
- addQueryExecResultStd: uses Assign, If, Return

Slice queries (sqlc.slice) fall back to RawStmt due to their
complex dynamic SQL generation requirements.

Added wrapErrorReturn helper for consistent error wrapping logic.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Add new expression types that implement the Expr interface:
- CallExpr: function/method calls
- StructLit: struct literals with Multiline option
- SliceLit: slice literals
- TypeCast: type conversions
- FuncLit: anonymous function literals
- Selector: field/method selection (a.b.c)
- Index: array/slice indexing

Add new statement types:
- GoStmt: goroutine launch (go f())
- Continue: continue statement with optional label
- Break: break statement with optional label

Update generator.go to use StructLit for:
- New function (compact single-line format)
- WithTx method (multi-line format)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Update SliceLit to support multi-line formatting similar to StructLit.
This ensures AllEnumTypeValues() functions generate properly formatted
slice literals with each value on its own line.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Replace manual string building with poet AST types for:
- Prepare function: VarDecl, Assign, If with Return
- Close function: VarDecl, nested If statements, Assign, Return

The slice query fallback still uses RawStmt due to complex
dynamic SQL handling requirements.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Convert the HasSqlcSlices() fallback paths in addQueryOneStd and
addQueryManyStd to use poet AST types instead of string building.

Only the initial query exec call (writeQueryExecStdCall) remains as
RawStmt due to complex dynamic SQL handling. All other statements
now use structured poet types:
- poet.If for error handling
- poet.Defer for rows.Close()
- poet.VarDecl and poet.Assign for variable declarations
- poet.For for iteration
- poet.Return for return statements

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add guidance to always run go fmt before committing changes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Convert the HasSqlcSlices() fallback paths in addQueryExecStd and
addQueryExecRowsStd to use poet AST types instead of string building.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Replace string building with structured poet AST types for:
- addQueryOnePGX, addQueryManyPGX, addQueryExecPGX
- addQueryExecRowsPGX, addQueryExecResultPGX
- addCopyFromCodeMySQL
- batch functions (batchexec, batchmany, batchone)

This eliminates manual string building with fmt.Fprintf and
WriteString calls in favor of structured poet.If, poet.For,
poet.Assign, poet.Defer, and other statement types.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Add Indent field to FuncLit to support configurable body indentation
- Update RenderFuncLit to use the Indent field (defaults to "\t")
- Convert batchmany innerFunc from manual string building to poet.FuncLit

This eliminates the last remaining manual string building with tabs in
the batch functions, using structured poet AST throughout.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Split long poet.Method declarations across multiple lines for better
readability.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Add buildQuerySliceExecStmts function that returns []poet.Stmt
- Add public RenderStmt function to poet package
- Use poet.If with Else, poet.For with Range, poet.Assign, poet.VarDecl
- Eliminate manual string building with tabs

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files. 🔧 golang

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants