unified: Port closure rules to swift-syntax

Retarget closures to the swift-syntax AST, output unchanged.
swift-syntax nests the whole closure header under an optional
`closureSignature`, so a single `closureExpr` rule (with optional
attributes, capture list, parameter clause, and return clause) replaces
the tree-sitter `lambda_literal` rule.
The parameter clause is a union of the parenthesised form
(`closureParameterClause`, unwrapped to its `closureParameter` children)
and the shorthand form (`closureShorthandParameter`, a bare name); one
rule each replaces the four `lambda_parameter` variants.
`closureCapture` -> `variable_declaration` (an optional ownership
specifier becomes a modifier; an explicit capture initializer becomes
the bound value).

The trailing-closure call form is already handled by the
`functionCallExpr`
`trailingClosure` variant, so the tree-sitter trailing-closure call rule
is
dropped.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Taus
2026-07-17 21:27:32 +00:00
parent 52cdf59f27
commit 6ad1facee1

View File

@@ -637,16 +637,20 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
rule!((continueStmt label: _? @@lbl) => (continue_expr label: {lbl.map(|l| tree!((identifier #{l})))})),
rule!((throwStmt expression: @val) => (throw_expr value: {val})),
// ---- Closures ----
// Lambda literal with optional type header (parameters + optional return type).
// The return_type capture is optional, so this rule covers both cases.
// A closure (`{ (x: Int) -> Int in … }`) becomes a `function_expr`. The
// whole signature is optional, as are its capture list, parameter
// clause, and return clause, so one rule covers everything from a bare
// `{ … }` to `{ [weak self] (x) -> T in … }`. Shorthand `$0` closures
// have no signature and their `$0` references are ordinary name
// expressions.
rule!(
(lambda_literal
attribute: _* @attrs
captures: (capture_list item: _* @captures)?
type: (lambda_function_type
params: (lambda_function_type_parameters parameter: _* @params)
return_type: _? @ret)?
statement: _* @body)
(closureExpr
signature: (closureSignature
attributes: _* @attrs
capture: (closureCaptureClause items: _* @captures)?
parameterClause: _* @params
returnClause: (returnClause type: @ret)?)?
statements: _* @body)
=>
(function_expr
modifier: {attrs}
@@ -655,51 +659,37 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
return_type: {ret}
body: (block stmt: {body}))
),
// capture_list_item with ownership modifier (e.g. [weak self], [unowned x])
// A closure capture (`[weak self]`, `[x]`, `[y = expr]`). The optional
// ownership specifier (`weak`/`unowned`) becomes a modifier; the
// captured name becomes the bound `name_pattern`; an explicit capture
// initializer (`[y = expr]`) becomes the bound value.
rule!(
(capture_list_item ownership: _? @ownership name: @name value: _? @val)
(closureCapture
specifier: (closureCaptureSpecifier specifier: @@spec)?
name: @@name
initializer: (initializerClause value: @val)?)
=>
(variable_declaration
modifier: {ownership}
modifier: {spec.map(|s| tree!((modifier #{s})))}
pattern: (name_pattern identifier: (identifier #{name}))
value: {val})
),
// Lambda parameter with type and optional external name
// A closure parameter clause (`(x: Int, y)`) unwraps to its parameters.
rule!((closureParameterClause parameters: _* @params) => parameter* { params }),
// A closure parameter (`x: Int`, or just `x`). Unlike a function
// parameter it has no external label; the type is optional.
rule!(
(lambda_parameter external_name: @ext name: @name type: @ty)
(closureParameter firstName: @name type: _? @ty)
=>
(parameter
external_name: (identifier #{ext})
pattern: (name_pattern identifier: (identifier #{name}))
type: {ty})
(parameter pattern: (name_pattern identifier: (identifier #{name})) type: {ty})
),
// A shorthand closure parameter (`x` in `{ x, y in … }`): a bare name
// with no parentheses and no type.
rule!(
(lambda_parameter name: @name type: @ty)
=>
(parameter
pattern: (name_pattern identifier: (identifier #{name}))
type: {ty})
),
rule!(
(lambda_parameter external_name: @ext name: @name)
=>
(parameter
external_name: (identifier #{ext})
pattern: (name_pattern identifier: (identifier #{name})))
),
rule!(
(lambda_parameter name: @name)
(closureShorthandParameter name: @name)
=>
(parameter pattern: (name_pattern identifier: (identifier #{name})))
),
// Call expression with trailing closure (no value_arguments)
rule!(
(call_expression function: @func suffix: (call_suffix lambda: (lambda_literal) @closure))
=>
(call_expr
callee: {func}
argument: (argument value: {closure}))
),
// ---- Control flow ----
// If statement
rule!(