mirror of
https://github.com/github/codeql.git
synced 2026-06-25 14:47:04 +02:00
unified/swift: add type and declaration-family mappings
This commit is contained in:
@@ -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!(
|
||||
(_)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user