Skip to content

Commit c878e73

Browse files
committed
Unified: Add locations for blocks
Blocks are slightly awkward, since we destructure them (as codeBlock) in the query, and then reconstruct them (as `block`) in the rule body, meaning the location of the block is (by default) assigned to the wrong place by the heuristic. To get around this, I added a helper function that updates the location appropriately, including handling cases where we only optionally match a block. (Also, in some cases we can fix this by just not destructuring `codeBlock`s in the first place -- there's already a rule that maps `codeBlock` to `block`.)
1 parent c21bba7 commit c878e73

8 files changed

Lines changed: 51 additions & 17 deletions

File tree

‎unified/extractor/src/languages/swift/swift.rs‎

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,20 @@ impl SwiftContext {
6060
}
6161
}
6262

63+
fn block_with_anchor(
64+
ctx: &mut yeast::build::BuildCtx<'_, SwiftContext>,
65+
statements: Vec<yeast::Id>,
66+
anchor: Option<yeast::Id>,
67+
) -> yeast::Id {
68+
match anchor {
69+
Some(anchor) => {
70+
let source_range = ctx.source_range_of(anchor);
71+
ctx.with_node_source_range(source_range, |ctx| tree!(ctx, (block stmt: {statements})))
72+
}
73+
None => tree!(ctx, (block stmt: {statements})),
74+
}
75+
}
76+
6377
/// Build a freshly-created `chained_declaration` modifier node if
6478
/// `ctx.is_chained`, else `None`. Used by inner declaration rules to
6579
/// emit the chained tag for non-first children of a flattening outer
@@ -301,14 +315,14 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
301315
bindings: (patternBinding
302316
pattern: (identifierPattern identifier: @@name)
303317
typeAnnotation: (typeAnnotation type: @ty)
304-
accessorBlock: (accessorBlock accessors: (codeBlockItem)+ @body)))
318+
accessorBlock: (accessorBlock accessors: (codeBlockItem)+ @body) @@accessor_block))
305319
=>
306320
(accessor_declaration
307321
modifier: (modifier #{spec})
308322
name_node: (identifier #{name})
309323
type: {ty}
310-
accessor_kind: (accessor_kind "get")
311-
body: (block stmt: {body}))
324+
accessor_kind: {ctx.literal_at_start_of("accessor_kind", "get", accessor_block)}
325+
body: {block_with_anchor(&mut ctx, body, Some(accessor_block))})
312326
),
313327
// A property with an explicit accessor block. swift-syntax makes both
314328
// shapes plain `accessorDecl`s, so they are told apart by the presence
@@ -564,15 +578,15 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
564578
signature: (functionSignature
565579
parameterClause: (functionParameterClause parameters: _* @params)
566580
returnClause: (returnClause type: @ret)?)
567-
body: (codeBlock statements: _* @body))
581+
body: (codeBlock) @body)
568582
=>
569583
(function_declaration
570584
modifier: {mods}
571585
name_node: (identifier #{name})
572586
type_parameter: {type_params}
573587
parameter: {params}
574588
return_type: {ret}
575-
body: (block stmt: {body}))
589+
body: {body})
576590
),
577591
rule!(
578592
(functionDecl
@@ -747,14 +761,14 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
747761
capture: (closureCaptureClause items: _* @captures)?
748762
parameterClause: _* @params
749763
returnClause: (returnClause type: @ret)?)?
750-
statements: _* @body)
764+
statements: _* @body) @@closure
751765
=>
752766
(function_expr
753767
modifier: {attrs}
754768
capture_declaration: {captures}
755769
parameter: {params}
756770
return_type: {ret}
757-
body: (block stmt: {body}))
771+
body: {block_with_anchor(&mut ctx, body, Some(closure))})
758772
),
759773
// A closure capture (`[weak self]`, `[x]`, `[y = expr]`). The optional
760774
// ownership specifier (`weak`/`unowned`) becomes a modifier; the
@@ -1277,22 +1291,33 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
12771291
modifiers: _* @mods
12781292
signature: (functionSignature
12791293
parameterClause: (functionParameterClause parameters: _* @params))
1280-
body: (codeBlock statements: _* @body_stmts)?)
1294+
body: (codeBlock) @body)
12811295
=>
12821296
(constructor_declaration
12831297
modifier: {mods}
12841298
parameter: {params}
1285-
body: (block stmt: {body_stmts}))
1299+
body: {body})
1300+
),
1301+
rule!(
1302+
(initializerDecl
1303+
modifiers: _* @mods
1304+
signature: (functionSignature
1305+
parameterClause: (functionParameterClause parameters: _* @params)))
1306+
=>
1307+
(constructor_declaration
1308+
modifier: {mods}
1309+
parameter: {params}
1310+
body: (block))
12861311
),
12871312
// Deinit declaration → destructor_declaration. Body statements optional.
12881313
rule!(
12891314
(deinitializerDecl
12901315
modifiers: _* @mods
1291-
body: (codeBlock statements: _* @body_stmts))
1316+
body: (codeBlock) @body)
12921317
=>
12931318
(destructor_declaration
12941319
modifier: {mods}
1295-
body: (block stmt: {body_stmts}))
1320+
body: {body})
12961321
),
12971322
// Typealias declaration
12981323
rule!(

‎unified/extractor/tests/corpus/swift/expressions/unsafe-expression.output‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,5 @@ top_level
4747
stmt:
4848
function_declaration
4949
name_node: identifier "doWork"
50-
body: block
50+
body: block "{}"
5151
unsupported_node "unsafe doWork()"

‎unified/extractor/tests/corpus/swift/types/class-function.output‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,4 @@ top_level
5454
function_declaration
5555
modifier: modifier "class"
5656
name_node: identifier "make"
57-
body: block
57+
body: block "{}"

‎unified/extractor/tests/corpus/swift/types/constructor-with-parameters.output‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,4 @@ top_level
7777
external_name_node: identifier "height"
7878
type: identifier "Int"
7979
pattern: identifier "h"
80-
body: block
80+
body: block "{}"

‎unified/extractor/tests/corpus/swift/types/function-type-with-convention-attribute.output‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,4 @@ top_level
6868
type: unsupported_node "@convention(c) () -> Void"
6969
value:
7070
function_expr
71-
body: block
71+
body: block "{}"

‎unified/extractor/tests/corpus/swift/types/function-type-with-sendable-attribute.output‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,4 @@ top_level
6161
type: unsupported_node "@Sendable () -> Void"
6262
value:
6363
function_expr
64-
body: block
64+
body: block "{}"

‎unified/extractor/tests/corpus/swift/types/static-function.output‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,4 @@ top_level
5454
function_declaration
5555
modifier: modifier "static"
5656
name_node: identifier "make"
57-
body: block
57+
body: block "{}"

‎unified/extractor/tests/location_tests.rs‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@ fn generic_type_children_have_local_ranges() {
7171
assert_has_span(&ast, source, "identifier", Some("Foo"), "Foo");
7272
}
7373

74+
#[test]
75+
fn declaration_and_operator_tokens_keep_precise_ranges() {
76+
let source = "func f() { return x }";
77+
let ast = desugar(source);
78+
79+
assert_has_span(&ast, source, "block", None, "{ return x }");
80+
assert_has_span(&ast, source, "return_expr", None, "return x");
81+
}
82+
7483
#[test]
7584
fn synthetic_type_and_modifier_nodes_use_empty_scope_start_ranges() {
7685
let source = "let array: [T]\nlet optional: T?\nenum E { case a, b }";

0 commit comments

Comments
 (0)