Skip to content

JavaScript: Add CaptureKind to template captures#7067

Draft
knutwannheden wants to merge 7 commits intomainfrom
stormy-fox
Draft

JavaScript: Add CaptureKind to template captures#7067
knutwannheden wants to merge 7 commits intomainfrom
stormy-fox

Conversation

@knutwannheden
Copy link
Copy Markdown
Contributor

@knutwannheden knutwannheden commented Mar 20, 2026

Summary

  • Add CaptureKind enum (Expression, Identifier, TypeReference, Statement) to the JS templating engine, mirroring the C# CaptureKind added in C#: Add CaptureKind to template captures for position-aware scaffolding #7059
  • Add kind-specific factory functions (expr(), ident(), typeRef(), stmt()) as alternatives to the generic capture(), available both as direct imports and namespace-qualified on capture (e.g. capture.expr())
  • Migrate all existing templating tests to use the kind-specific factories, documenting the semantic intent of each capture
  • Kind-specific factories delegate to capture() internally, so there is a single code path for name resolution and option handling

API

// Direct imports (concise)
import { expr, ident, typeRef, stmt } from './capture';
const e = expr('x');
const n = ident('method');
const t = typeRef('ret');
const s = stmt('body');

// Namespace-qualified (no collisions)
import { capture } from './capture';
capture.expr('x')
capture.ident('method')

// Backwards compatible
capture('x')  // defaults to Expression kind
capture({ name: 'x', kind: CaptureKind.Identifier })

Note

The CaptureKind metadata is stored on captures but not yet consumed by the engine — scaffold-aware placeholder generation will follow once we have concrete recipes that need different scaffold wrapping.

Test plan

  • 18 new tests for capture kinds (enum values, factory functions, backwards compat, namespace access, any() integration, pattern usage)
  • All 258 existing templating tests pass with migrated factory calls
  • TypeScript typecheck passes with no new errors

Add a CaptureKind enum (Expression, Identifier, TypeReference, Statement)
and kind-specific factory functions (expr, ident, typeRef, stmt) as an
alternative to the generic capture() function. Factory functions are also
available as namespace-qualified methods on capture (e.g. capture.expr()).

The existing capture() function defaults to CaptureKind.Expression for
backwards compatibility. The kind is stored but not yet consumed by the
engine — scaffold-aware placeholder generation will follow.
Replace generic capture() calls with expr(), ident(), and stmt() across
all templating tests to document the semantic intent of each capture:
- expr() for expression captures (operands, arguments, conditions)
- ident() for identifier captures (function names, property names)
- stmt() for statement captures (variadic statement bodies)

Only basic.test.ts retains capture() since it tests the base function.
- Clarify namespace block is type-only declarations for TS augmentation
- Eliminate duplicated logic in createKindCapture by delegating to capture()
- Rename expr0 to parsed for consistency with other test files
@knutwannheden knutwannheden changed the title JS: Add CaptureKind to template captures JavaScript: Add CaptureKind to template captures Mar 20, 2026
Remove CaptureKind from public exports and the kind option from
CaptureOptions. The factory functions (expr, ident, typeRef, stmt)
are the intended API for setting capture kinds; there is no need
to expose the enum to callers.
Move the `type` option from CaptureOptions to a new ExprCaptureOptions
interface only accepted by expr(). The template engine now skips preamble
generation for non-expression captures (ident, typeRef, stmt), since type
attribution declarations only make sense for expression placeholders.
Add non-variadic and variadic overload signatures to expr(), ident(),
typeRef(), and stmt() matching the existing capture() overloads. This
fixes TypeScript type inference for typed captures with constraints
(e.g. expr<J.Literal>({constraint: ...})) and variadic captures with
array operations (e.g. args[0], args.slice(1)).
npm run typecheck misses test file type errors because vitest types
are not resolved by tsc alone. Note to prefer npm test as the final
verification before pushing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

1 participant