unified/swift: add type and declaration-family mappings

This commit is contained in:
Asger F
2026-06-18 13:42:33 +02:00
parent f362707493
commit 1e167dfa6b
7 changed files with 594 additions and 27 deletions

View File

@@ -665,6 +665,274 @@ fn translation_rules() -> Vec<yeast::Rule> {
imported_expr: {name}
modifier: {..mods})
),
// ---- Types and classes ----
// Self expression → name_expr
rule!((self_expression) => (name_expr identifier: (identifier "self"))),
// Super expression → super_expr
rule!((super_expression) => (super_expr)),
// Modifiers — unwrap to individual modifier children
rule!((modifiers _* @mods) => {..mods}),
rule!((attribute) @m => (modifier #{m})),
rule!((visibility_modifier) @m => (modifier #{m})),
rule!((function_modifier) @m => (modifier #{m})),
rule!((member_modifier) @m => (modifier #{m})),
rule!((mutation_modifier) @m => (modifier #{m})),
rule!((ownership_modifier) @m => (modifier #{m})),
rule!((property_modifier) @m => (modifier #{m})),
rule!((parameter_modifier) @m => (modifier #{m})),
rule!((inheritance_modifier) @m => (modifier #{m})),
rule!((property_behavior_modifier) @m => (modifier #{m})),
// Type annotations — unwrap
rule!((type_annotation type: @inner) => {inner}),
// user_type is split into simple_user_type parts.
// Keep a conservative textual fallback to avoid dropping type information.
rule!((user_type) @ty => (named_type_expr name: (identifier #{ty}))),
// Tuple type → tuple_type_expr
rule!((tuple_type element: _* @elems) => (tuple_type_expr element: {..elems})),
rule!((tuple_type_item name: @name type: @ty) => (tuple_type_element name: (identifier #{name}) type: {ty})),
rule!((tuple_type_item type: @ty) => (tuple_type_element type: {ty})),
// Array type `[T]` → generic_type_expr with Array base
rule!((array_type element: @e) => (generic_type_expr
base: (named_type_expr name: (identifier "Array"))
type_argument: {e})),
// Dictionary type `[K: V]` → generic_type_expr with Dictionary base
rule!((dictionary_type key: @k value: @v) => (generic_type_expr
base: (named_type_expr name: (identifier "Dictionary"))
type_argument: {k}
type_argument: {v})),
// Optional type `T?` → generic_type_expr with Optional base
rule!((optional_type wrapped: @w) => (generic_type_expr
base: (named_type_expr name: (identifier "Optional"))
type_argument: {w})),
// Function type `(Params) -> Ret` → function_type_expr.
rule!((function_type parameter: _* @ps return_type: @ret) => (function_type_expr parameter: {..ps} return_type: {ret})),
rule!((function_type_parameter name: @name type: @ty) => (parameter external_name: (identifier #{name}) type: {ty})),
rule!((function_type_parameter type: @ty) => (parameter type: {ty})),
// Selector expression: `#selector(inner)` -- not yet supported
rule!(
(selector_expression _ @inner)
=>
(unsupported_node)
),
// Key path expressions are currently unsupported.
rule!((key_path_expression) => (unsupported_node)),
// Inheritance specifier → base_type
rule!((inheritance_specifier inherits_from: @ty) => (base_type type: {ty})),
// Class declaration with body containing members
rule!(
(class_declaration
declaration_kind: @kind
name: @name
body: (class_body member: _* @members)
(inheritance_specifier)* @bases
(modifiers)* @mods)
=>
(class_like_declaration
modifier: (modifier #{kind})
modifier: {..mods}
name: (identifier #{name})
base_type: {..bases}
member: {..members})
),
// Enum class declaration: same as a regular class but with an enum body.
rule!(
(class_declaration
declaration_kind: @kind
name: @name
body: (enum_class_body member: _* @members)
(inheritance_specifier)* @bases
(modifiers)* @mods)
=>
(class_like_declaration
modifier: (modifier #{kind})
modifier: {..mods}
name: (identifier #{name})
base_type: {..bases}
member: {..members})
),
// Class declaration with empty body
rule!(
(class_declaration
declaration_kind: @kind
name: @name
body: _
(inheritance_specifier)* @bases
(modifiers)* @mods)
=>
(class_like_declaration
modifier: (modifier #{kind})
modifier: {..mods}
name: (identifier #{name})
base_type: {..bases})
),
// Protocol declaration
rule!(
(protocol_declaration
name: @name
body: (protocol_body member: _* @members)
(inheritance_specifier)* @bases
(modifiers)* @mods)
=>
(class_like_declaration
modifier: (modifier "protocol")
modifier: {..mods}
name: (identifier #{name})
base_type: {..bases}
member: {..members})
),
// Protocol function — return type and body statements both optional.
rule!(
(protocol_function_declaration
name: @name
(parameter)* @params
return_type: _? @ret
body: (block statement: _* @body_stmts)?
(modifiers)* @mods)
=>
(function_declaration
modifier: {..mods}
name: (identifier #{name})
parameter: {..params}
return_type: {..ret}
body: (block stmt: {..body_stmts}))
),
// Init declaration → constructor_declaration. Body statements optional;
// body itself is also optional (protocol requirement).
rule!(
(init_declaration
(parameter)* @params
body: (block statement: _* @body_stmts)?
(modifiers)* @mods)
=>
(constructor_declaration
modifier: {..mods}
parameter: {..params}
body: (block stmt: {..body_stmts}))
),
// Deinit declaration → destructor_declaration. Body statements optional.
rule!(
(deinit_declaration
body: (block statement: _* @body_stmts)
(modifiers)* @mods)
=>
(destructor_declaration
modifier: {..mods}
body: (block stmt: {..body_stmts}))
),
// Typealias declaration
rule!(
(typealias_declaration name: @name value: @val (modifiers)* @mods)
=>
(type_alias_declaration
modifier: {..mods}
name: (identifier #{name})
r#type: {val})
),
// Subscript declaration (not yet supported -- grammar needs to distinguish plain calls from subscript calls)
rule!(
(subscript_declaration (parameter)* @params (modifiers)* @mods)
=>
(unsupported_node)
),
// Associated type declaration (with optional bound)
rule!(
(associatedtype_declaration name: @name inherits_from: _? @bound (modifiers)* @mods)
=>
(associated_type_declaration
modifier: {..mods}
name: (identifier #{name})
bound: {..bound})
),
// Protocol property declaration: translate each accessor requirement to an
// accessor_declaration without a body, carrying the property name and type.
// Subsequent accessors get chained_declaration (same flattening as computed properties).
rule!(
(protocol_property_declaration
name: @pattern
requirements: (protocol_property_requirements accessor: _+ @accessors)
type: _? @ty
(modifiers)* @mods)
=>
{..{
let name_text = __yeast_ctx.ast.source_text(pattern.into());
let mod_ids: Vec<usize> = mods.iter().map(|&m| m.into()).collect();
let ty_ids: Vec<usize> = ty.iter().map(|&t| t.into()).collect();
let acc_ids: Vec<usize> = accessors.iter().map(|&a| a.into()).collect();
for (i, &acc_id) in acc_ids.iter().enumerate() {
if i > 0 {
let chained = __yeast_ctx.literal("modifier", "chained_declaration");
__yeast_ctx.prepend_field(acc_id, "modifier", chained);
}
for &mod_id in mod_ids.iter().rev() {
__yeast_ctx.prepend_field(acc_id, "modifier", mod_id);
}
for &ty_id in ty_ids.iter().rev() {
__yeast_ctx.prepend_field(acc_id, "type", ty_id);
}
let ident = __yeast_ctx.literal("identifier", &name_text);
__yeast_ctx.prepend_field(acc_id, "name", ident);
}
acc_ids
}}
),
// getter_specifier / setter_specifier → bodyless accessor_declaration
rule!((getter_specifier) => (accessor_declaration accessor_kind: (accessor_kind "get"))),
rule!((setter_specifier) => (accessor_declaration accessor_kind: (accessor_kind "set"))),
// protocol_property_requirements wrapper — should be consumed by above; fallback
rule!((protocol_property_requirements accessor: _* @accs) => {..accs}),
// Computed getter → accessor_declaration (body optional).
rule!(
(computed_getter body: (block statement: _* @body)?)
=>
(accessor_declaration
accessor_kind: (accessor_kind "get")
body: (block stmt: {..body}))
),
// Computed setter with explicit parameter name.
rule!(
(computed_setter parameter: @param body: (block statement: _* @body))
=>
(accessor_declaration
accessor_kind: (accessor_kind "set")
parameter: (parameter pattern: (name_pattern identifier: (identifier #{param})))
body: (block stmt: {..body}))
),
// Computed setter without explicit parameter name; body optional.
rule!(
(computed_setter body: (block statement: _* @body)?)
=>
(accessor_declaration
accessor_kind: (accessor_kind "set")
body: (block stmt: {..body}))
),
// Computed modify → accessor_declaration
rule!(
(computed_modify body: (block statement: _* @body))
=>
(accessor_declaration
accessor_kind: (accessor_kind "modify")
body: (block stmt: {..body}))
),
// willset/didset block — spread to children
rule!((willset_didset_block _* @clauses) => {..clauses}),
// willset clause → accessor_declaration (body optional).
rule!(
(willset_clause body: (block statement: _* @body)?)
=>
(accessor_declaration
accessor_kind: (accessor_kind "willSet")
body: (block stmt: {..body}))
),
// didset clause → accessor_declaration (body optional).
rule!(
(didset_clause body: (block statement: _* @body)?)
=>
(accessor_declaration
accessor_kind: (accessor_kind "didSet")
body: (block stmt: {..body}))
),
// Preprocessor conditionals — unsupported
rule!((diagnostic) => (unsupported_node)),
// ---- Fallbacks ----
rule!(
(_)

View File

@@ -73,8 +73,12 @@ top_level
pattern:
name_pattern
identifier: identifier "x"
type: unsupported_node "Int"
return_type: unsupported_node "Int"
type:
named_type_expr
name: identifier "Int"
return_type:
named_type_expr
name: identifier "Int"
===
Closure with shorthand parameters
@@ -245,11 +249,13 @@ top_level
call_expr
callee:
member_access_expr
base: unsupported_node "self"
base:
name_expr
identifier: identifier "self"
member: identifier "doThing"
capture_declaration:
variable_declaration
modifier: unsupported_node "weak" <-- ERROR: The field variable_declaration.modifier should contain modifier, but got unsupported_node
modifier: modifier "weak"
pattern:
name_pattern
identifier: identifier "self"
@@ -363,5 +369,9 @@ top_level
pattern:
name_pattern
identifier: identifier "x"
type: unsupported_node "Int"
return_type: unsupported_node "Int"
type:
named_type_expr
name: identifier "Int"
return_type:
named_type_expr
name: identifier "Int"

View File

@@ -88,7 +88,14 @@ top_level
pattern:
name_pattern
identifier: identifier "xs"
type: unsupported_node ": [Int]"
type:
generic_type_expr
base:
named_type_expr
name: identifier "Array"
type_argument:
named_type_expr
name: identifier "Int"
value: array_literal "[]"
===
@@ -192,7 +199,9 @@ top_level
pattern:
name_pattern
identifier: identifier "s"
type: unsupported_node ": Set<Int>"
type:
named_type_expr
name: identifier "Set<Int>"
value:
array_literal
element:

View File

@@ -135,7 +135,9 @@ top_level
pattern:
name_pattern
identifier: identifier "b"
return_type: unsupported_node "Int"
return_type:
named_type_expr
name: identifier "Int"
===
Function with named parameters
@@ -365,7 +367,9 @@ top_level
pattern:
name_pattern
identifier: identifier "values"
return_type: unsupported_node "Int"
return_type:
named_type_expr
name: identifier "Int"
===
Function call
@@ -554,7 +558,9 @@ top_level
pattern:
name_pattern
identifier: identifier "x"
return_type: unsupported_node "T"
return_type:
named_type_expr
name: identifier "T"
===
Leading-dot expression value

View File

@@ -41,7 +41,14 @@ top_level
pattern:
name_pattern
identifier: identifier "x"
type: unsupported_node ": Int?"
type:
generic_type_expr
base:
named_type_expr
name: identifier "Optional"
type_argument:
named_type_expr
name: identifier "Int"
value: builtin_expr "nil"
===
@@ -228,7 +235,9 @@ top_level
return_expr
value: string_literal "\"\""
name: identifier "read"
return_type: unsupported_node "String"
return_type:
named_type_expr
name: identifier "String"
===
Do-catch

View File

@@ -19,7 +19,10 @@ source_file
top_level
body:
block
stmt: unsupported_node "class Foo {}"
stmt:
class_like_declaration
modifier: modifier "class"
name: identifier "Foo"
===
Class with stored properties
@@ -82,7 +85,27 @@ source_file
top_level
body:
block
stmt: unsupported_node "class Point {\n var x: Int\n var y: Int\n}"
stmt:
class_like_declaration
member:
variable_declaration
modifier: modifier "var"
pattern:
name_pattern
identifier: identifier "x"
type:
named_type_expr
name: identifier "Int"
variable_declaration
modifier: modifier "var"
pattern:
name_pattern
identifier: identifier "y"
type:
named_type_expr
name: identifier "Int"
modifier: modifier "class"
name: identifier "Point"
===
Class with initializer
@@ -157,7 +180,33 @@ source_file
top_level
body:
block
stmt: unsupported_node "class Point {\n var x: Int\n init(x: Int) {\n self.x = x\n }\n}"
stmt:
class_like_declaration
member:
variable_declaration
modifier: modifier "var"
pattern:
name_pattern
identifier: identifier "x"
type:
named_type_expr
name: identifier "Int"
constructor_declaration
body:
block
stmt:
assign_expr
target:
member_access_expr
base:
name_expr
identifier: identifier "self"
member: identifier "x"
value:
name_expr
identifier: identifier "x"
modifier: modifier "class"
name: identifier "Point"
===
Class with method
@@ -207,7 +256,28 @@ source_file
top_level
body:
block
stmt: unsupported_node "class Counter {\n var n = 0\n func bump() {\n n += 1\n }\n}"
stmt:
class_like_declaration
member:
variable_declaration
modifier: modifier "var"
pattern:
name_pattern
identifier: identifier "n"
value: int_literal "0"
function_declaration
body:
block
stmt:
compound_assign_expr
operator: infix_operator "+="
target:
name_expr
identifier: identifier "n"
value: int_literal "1"
name: identifier "bump"
modifier: modifier "class"
name: identifier "Counter"
===
Class inheritance
@@ -237,7 +307,10 @@ source_file
top_level
body:
block
stmt: unsupported_node "class Dog: Animal {}"
stmt:
class_like_declaration
modifier: modifier "class"
name: identifier "Dog"
===
Struct
@@ -300,7 +373,27 @@ source_file
top_level
body:
block
stmt: unsupported_node "struct Point {\n let x: Int\n let y: Int\n}"
stmt:
class_like_declaration
member:
variable_declaration
modifier: modifier "let"
pattern:
name_pattern
identifier: identifier "x"
type:
named_type_expr
name: identifier "Int"
variable_declaration
modifier: modifier "let"
pattern:
name_pattern
identifier: identifier "y"
type:
named_type_expr
name: identifier "Int"
modifier: modifier "struct"
name: identifier "Point"
===
Enum with cases
@@ -345,7 +438,31 @@ source_file
top_level
body:
block
stmt: unsupported_node "enum Direction {\n case north\n case south\n case east\n case west\n}"
stmt:
class_like_declaration
member:
variable_declaration
modifier: modifier "enum_case"
pattern:
name_pattern
identifier: identifier "north"
variable_declaration
modifier: modifier "enum_case"
pattern:
name_pattern
identifier: identifier "south"
variable_declaration
modifier: modifier "enum_case"
pattern:
name_pattern
identifier: identifier "east"
variable_declaration
modifier: modifier "enum_case"
pattern:
name_pattern
identifier: identifier "west"
modifier: modifier "enum"
name: identifier "Direction"
===
Enum with associated values
@@ -404,7 +521,39 @@ source_file
top_level
body:
block
stmt: unsupported_node "enum Shape {\n case circle(radius: Double)\n case square(side: Double)\n}"
stmt:
class_like_declaration
member:
class_like_declaration
member:
constructor_declaration
body: block "circle(radius: Double)"
parameter:
parameter
pattern:
name_pattern
identifier: identifier "radius"
type:
named_type_expr
name: identifier "Double"
modifier: modifier "enum_case"
name: identifier "circle"
class_like_declaration
member:
constructor_declaration
body: block "square(side: Double)"
parameter:
parameter
pattern:
name_pattern
identifier: identifier "side"
type:
named_type_expr
name: identifier "Double"
modifier: modifier "enum_case"
name: identifier "square"
modifier: modifier "enum"
name: identifier "Shape"
===
Protocol declaration
@@ -431,7 +580,14 @@ source_file
top_level
body:
block
stmt: unsupported_node "protocol Drawable {\n func draw()\n}"
stmt:
class_like_declaration
member:
function_declaration
body: block "func draw()"
name: identifier "draw"
modifier: modifier "protocol"
name: identifier "Drawable"
===
Extension
@@ -482,7 +638,29 @@ source_file
top_level
body:
block
stmt: unsupported_node "extension Int {\n func squared() -> Int { return self * self }\n}"
stmt:
class_like_declaration
member:
function_declaration
body:
block
stmt:
return_expr
value:
binary_expr
operator: infix_operator "*"
left:
name_expr
identifier: identifier "self"
right:
name_expr
identifier: identifier "self"
name: identifier "squared"
return_type:
named_type_expr
name: identifier "Int"
modifier: modifier "extension"
name: identifier "Int"
===
Computed property
@@ -576,7 +754,47 @@ source_file
top_level
body:
block
stmt: unsupported_node "class Rect {\n var w: Double\n var h: Double\n var area: Double {\n return w * h\n }\n}"
stmt:
class_like_declaration
member:
variable_declaration
modifier: modifier "var"
pattern:
name_pattern
identifier: identifier "w"
type:
named_type_expr
name: identifier "Double"
variable_declaration
modifier: modifier "var"
pattern:
name_pattern
identifier: identifier "h"
type:
named_type_expr
name: identifier "Double"
accessor_declaration
body:
block
stmt:
return_expr
value:
binary_expr
operator: infix_operator "*"
left:
name_expr
identifier: identifier "w"
right:
name_expr
identifier: identifier "h"
modifier: modifier "var"
name: identifier "area"
type:
named_type_expr
name: identifier "Double"
accessor_kind: accessor_kind "get"
modifier: modifier "class"
name: identifier "Rect"
===
Property with getter and setter
@@ -662,4 +880,47 @@ source_file
top_level
body:
block
stmt: unsupported_node "class Box {\n private var _v = 0\n var v: Int {\n get { return _v }\n set { _v = newValue }\n }\n}"
stmt:
class_like_declaration
member:
variable_declaration
modifier: modifier "var"
pattern:
name_pattern
identifier: identifier "_v"
value: int_literal "0"
accessor_declaration
body:
block
stmt:
return_expr
value:
name_expr
identifier: identifier "_v"
modifier: modifier "var"
name: identifier "v"
type:
named_type_expr
name: identifier "Int"
accessor_kind: accessor_kind "get"
accessor_declaration
body:
block
stmt:
assign_expr
target:
name_expr
identifier: identifier "_v"
value:
name_expr
identifier: identifier "newValue"
modifier:
modifier "var"
modifier "chained_declaration"
name: identifier "v"
type:
named_type_expr
name: identifier "Int"
accessor_kind: accessor_kind "set"
modifier: modifier "class"
name: identifier "Box"

View File

@@ -107,7 +107,9 @@ top_level
pattern:
name_pattern
identifier: identifier "x"
type: unsupported_node ": Int"
type:
named_type_expr
name: identifier "Int"
value: int_literal "1"
===
@@ -150,7 +152,9 @@ top_level
pattern:
name_pattern
identifier: identifier "x"
type: unsupported_node ": Int"
type:
named_type_expr
name: identifier "Int"
===
Tuple destructuring binding