unified/swift: add top-level normalization and fallback scaffold

This commit is contained in:
Asger F
2026-06-18 13:42:20 +02:00
parent 6c74cd31e4
commit 0e9d17b59c
12 changed files with 185 additions and 6 deletions

View File

@@ -1,8 +1,20 @@
use codeql_extractor::extractor::simple;
use yeast::{build::BuildCtx, rule, DesugaringConfig, PhaseKind};
use yeast::{rule, DesugaringConfig, PhaseKind};
fn translation_rules() -> Vec<yeast::Rule> {
vec![
// ---- Top-level ----
// Capture all top-level statements, including unnamed tokens like `nil`.
rule!(
(source_file statement: _* @children)
=>
(top_level
body: (block stmt: {..children})
)
),
// Declarations may be wrapped in local/global wrapper nodes.
rule!((global_declaration _ @inner) => {inner}),
rule!((local_declaration _ @inner) => {inner}),
// ---- Fallbacks ----
rule!(
(_)

View File

@@ -50,6 +50,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let f = { (x: Int) -> Int in x * 2 }"
===
Closure with shorthand parameters
@@ -82,6 +84,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let f = { $0 + $1 }"
===
Trailing closure
@@ -114,6 +118,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "xs.map { $0 * 2 }"
===
Closure with capture list
@@ -163,6 +169,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let f = { [weak self] in self?.doThing() }"
===
Multi-statement closure
@@ -236,3 +244,5 @@ source_file
top_level
body:
block
stmt: unsupported_node "let f = { (x: Int) -> Int in\n let y = x + 1\n return y * 2\n}"

View File

@@ -28,6 +28,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let xs = [1, 2, 3]"
===
Empty array literal with type
@@ -68,6 +70,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let xs: [Int] = []"
===
Dictionary literal
@@ -106,6 +110,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let d = [\"a\": 1, \"b\": 2]"
===
Set literal
@@ -155,6 +161,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let s: Set<Int> = [1, 2, 3]"
===
Tuple literal
@@ -191,6 +199,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let t = (1, \"two\", 3.0)"
===
Subscript access
@@ -232,9 +242,8 @@ source_file
top_level
body:
unsupported_node "// TODO: tree-sitter-swift parses `xs[0]` as a call_expression (same shape"
unsupported_node "// as `xs(0)`), so the mapping currently produces a call_expr. Update the"
unsupported_node "// parser / add a separate subscript_expr node and remap when fixed."
block
stmt: unsupported_node "let first = xs[0]"
===
Dictionary subscript
@@ -276,8 +285,8 @@ source_file
top_level
body:
unsupported_node "// TODO: same parser issue as the array subscript case above —"
unsupported_node "// `d[\"key\"]` is parsed as `call_expression(d, (\"key\"))`."
block
stmt: unsupported_node "let v = d[\"key\"]"
===
Tuple member access
@@ -309,3 +318,5 @@ source_file
top_level
body:
block
stmt: unsupported_node "let n = t.0"

View File

@@ -35,6 +35,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "if x > 0 {\n print(x)\n}"
===
If-else
@@ -90,6 +92,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "if x > 0 {\n print(x)\n} else {\n print(-x)\n}"
===
If-else-if chain
@@ -165,6 +169,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "if x > 0 {\n print(1)\n} else if x < 0 {\n print(2)\n} else {\n print(3)\n}"
===
If-let optional binding
@@ -207,6 +213,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "if let value = optional {\n print(value)\n}"
===
Guard let
@@ -240,6 +248,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "guard let value = optional else { return }"
===
Ternary expression
@@ -277,6 +287,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let y = x > 0 ? 1 : -1"
===
Switch statement
@@ -357,6 +369,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "switch x {\ncase 1:\n print(\"one\")\ncase 2, 3:\n print(\"two or three\")\ndefault:\n print(\"other\")\n}"
===
Switch with binding pattern
@@ -445,3 +459,5 @@ source_file
top_level
body:
block
stmt: unsupported_node "switch shape {\ncase .circle(let r):\n print(r)\ncase .square(let s):\n print(s)\n}"

View File

@@ -17,6 +17,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "1 + 2"
===
Another additive expression is desugared
@@ -37,3 +39,5 @@ source_file
top_level
body:
block
stmt: unsupported_node "foo + bar"

View File

@@ -31,6 +31,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "func greet() {\n print(\"hello\")\n}"
===
Function with parameters and return type
@@ -93,6 +95,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "func add(_ a: Int, _ b: Int) -> Int {\n return a + b\n}"
===
Function with named parameters
@@ -138,6 +142,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "func greet(person name: String) {\n print(name)\n}"
===
Function with default parameter value
@@ -185,6 +191,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "func greet(name: String = \"world\") {\n print(name)\n}"
===
Variadic function
@@ -249,6 +257,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "func sum(_ values: Int...) -> Int {\n return values.reduce(0, +)\n}"
===
Function call
@@ -276,6 +286,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "foo(1, 2)"
===
Function call with labelled arguments
@@ -306,6 +318,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "greet(person: \"Bob\")"
===
Method call
@@ -336,6 +350,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "list.append(1)"
===
Generic function
@@ -387,3 +403,5 @@ source_file
top_level
body:
block
stmt: unsupported_node "func identity<T>(_ x: T) -> T {\n return x\n}"

View File

@@ -13,6 +13,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "42"
===
Negative integer literal
@@ -32,6 +34,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "-7"
===
Floating-point literal
@@ -48,6 +52,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "3.14"
===
Boolean literals
@@ -67,6 +73,10 @@ source_file
top_level
body:
block
stmt:
unsupported_node "true"
unsupported_node "false"
===
Nil literal
@@ -83,6 +93,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "nil"
===
String literal
@@ -101,6 +113,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "\"hello\""
===
String with interpolation
@@ -122,3 +136,5 @@ source_file
top_level
body:
block
stmt: unsupported_node "\"hello \\(name)\""

View File

@@ -37,6 +37,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "for x in [1, 2, 3] {\n print(x)\n}"
===
For-in over range
@@ -76,6 +78,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "for i in 0..<10 {\n print(i)\n}"
===
For-in with where clause
@@ -119,6 +123,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "for x in xs where x > 0 {\n print(x)\n}"
===
While loop
@@ -154,6 +160,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "while x > 0 {\n x -= 1\n}"
===
Repeat-while loop
@@ -189,6 +197,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "repeat {\n x -= 1\n} while x > 0"
===
Break and continue
@@ -252,3 +262,5 @@ source_file
top_level
body:
block
stmt: unsupported_node "for x in xs {\n if x < 0 { continue }\n if x > 100 { break }\n print(x)\n}"

View File

@@ -17,6 +17,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "a + b"
===
Subtraction
@@ -37,6 +39,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "a - b"
===
Multiplication
@@ -57,6 +61,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "a * b"
===
Division
@@ -77,6 +83,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "a / b"
===
Operator precedence: addition and multiplication
@@ -101,6 +109,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "a + b * c"
===
Parenthesised expression
@@ -129,6 +139,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "(a + b) * c"
===
Comparison
@@ -149,6 +161,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "a < b"
===
Equality
@@ -169,6 +183,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "a == b"
===
Logical and
@@ -189,6 +205,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "a && b"
===
Logical or
@@ -209,6 +227,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "a || b"
===
Logical not
@@ -228,6 +248,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "!a"
===
Range operator
@@ -248,3 +270,5 @@ source_file
top_level
body:
block
stmt: unsupported_node "1...10"

View File

@@ -34,6 +34,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let x: Int? = nil"
===
Optional chaining
@@ -74,6 +76,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let n = obj?.foo?.bar"
===
Force unwrap
@@ -103,6 +107,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let n = opt!"
===
Nil-coalescing
@@ -132,6 +138,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let n = opt ?? 0"
===
Throwing function
@@ -167,6 +175,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "func read() throws -> String {\n return \"\"\n}"
===
Do-catch
@@ -216,6 +226,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "do {\n try foo()\n} catch {\n print(error)\n}"
===
Try? expression
@@ -252,6 +264,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let result = try? foo()"
===
Try! expression
@@ -288,3 +302,5 @@ source_file
top_level
body:
block
stmt: unsupported_node "let result = try! foo()"

View File

@@ -18,6 +18,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "class Foo {}"
===
Class with stored properties
@@ -79,6 +81,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "class Point {\n var x: Int\n var y: Int\n}"
===
Class with initializer
@@ -152,6 +156,8 @@ 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}"
===
Class with method
@@ -200,6 +206,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "class Counter {\n var n = 0\n func bump() {\n n += 1\n }\n}"
===
Class inheritance
@@ -228,6 +236,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "class Dog: Animal {}"
===
Struct
@@ -289,6 +299,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "struct Point {\n let x: Int\n let y: Int\n}"
===
Enum with cases
@@ -332,6 +344,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "enum Direction {\n case north\n case south\n case east\n case west\n}"
===
Enum with associated values
@@ -389,6 +403,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "enum Shape {\n case circle(radius: Double)\n case square(side: Double)\n}"
===
Protocol declaration
@@ -414,6 +430,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "protocol Drawable {\n func draw()\n}"
===
Extension
@@ -463,6 +481,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "extension Int {\n func squared() -> Int { return self * self }\n}"
===
Computed property
@@ -555,6 +575,8 @@ 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}"
===
Property with getter and setter
@@ -639,3 +661,5 @@ 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}"

View File

@@ -23,6 +23,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let x = 1"
===
Var binding
@@ -49,6 +51,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "var x = 1"
===
Let with type annotation
@@ -84,6 +88,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let x: Int = 1"
===
Var without initialiser
@@ -118,6 +124,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "var x: Int"
===
Tuple destructuring binding
@@ -154,6 +162,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let (a, b) = pair"
===
Multiple bindings on one line
@@ -185,6 +195,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "let x = 1, y = 2"
===
Assignment
@@ -207,6 +219,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "x = 1"
===
Compound assignment
@@ -229,3 +243,5 @@ source_file
top_level
body:
block
stmt: unsupported_node "x += 1"