Skip to content

Commit c7c80a7

Browse files
committed
unified: Ensure 'static' modifier is preserved for accessors
Modifiers like 'static' did not get preserved when extracting accessors, making most of the tests fail for static getters/setters. All those tests now pass.
1 parent 5dec1dc commit c7c80a7

4 files changed

Lines changed: 69 additions & 21 deletions

File tree

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

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ struct SwiftContext {
1818
/// parameter type, when available.
1919
property_type: Option<yeast::OutputId>,
2020
/// Translated outer modifiers to attach to each child of a flattening
21-
/// outer rule — e.g. the `let`/`var` binding modifier on each
22-
/// `patternBinding` of a `variableDecl`, or the binding modifier on each
23-
/// accessor of a property.
21+
/// outer rule — e.g. the `let`/`var` binding modifier, attributes and
22+
/// modifiers (`static`, `public`, …) on each `patternBinding` of a
23+
/// `variableDecl`, or on each accessor of a property.
2424
outer_modifiers: Vec<yeast::OutputId>,
2525
/// True when the current child of a flattening outer rule is not
2626
/// the first one — its inner rule should emit a
@@ -325,6 +325,8 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
325325
// block.
326326
rule!(
327327
(variableDecl
328+
attributes: _* @attrs
329+
modifiers: _* @mods
328330
bindingSpecifier: @@spec
329331
bindings: (patternBinding
330332
pattern: (identifierPattern identifier: @@name)
@@ -333,6 +335,8 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
333335
=>
334336
(accessor_declaration
335337
modifier: (modifier #{spec})
338+
modifier: {attrs}
339+
modifier: {mods}
336340
name_node: (identifier #{name})
337341
return_type: {ty}
338342
accessor_kind: {ctx.literal_at_start_of("accessor_kind", "get", body)}
@@ -355,6 +359,8 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
355359
// test). Must precede the plain `variableDecl` rules.
356360
rule!(
357361
(variableDecl
362+
attributes: _* @attrs
363+
modifiers: _* @mods
358364
bindingSpecifier: @@spec
359365
bindings: (patternBinding
360366
pattern: (identifierPattern identifier: @@name)
@@ -363,7 +369,12 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
363369
accessorBlock: (accessorBlock accessors: (accessorDecl)+ @@accessors)))
364370
=>
365371
member* {
366-
ctx.outer_modifiers = vec![tree!((modifier #{spec}))];
372+
// The binding (`let`/`var`) leads, then attributes then modifiers,
373+
// matching the plain `variableDecl` rule.
374+
ctx.outer_modifiers = std::iter::once(tree!((modifier #{spec})))
375+
.chain(attrs)
376+
.chain(mods)
377+
.collect();
367378
ctx.property_name_node = Some(tree!((identifier #{name})));
368379
ctx.property_type = Some(ty);
369380
let mut result = Vec::new();
@@ -390,12 +401,12 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
390401
}
391402
),
392403
// Each `accessorDecl` becomes an `accessor_declaration`, reading the
393-
// property name/type and the binding/chained modifiers from `ctx`. The
404+
// property name/type and the modifiers from `ctx`. The
394405
// accessor kind comes straight from the specifier keyword
395406
// (`get`/`set`/`willSet`/`didSet`). The body is optional: a body-bearing
396407
// accessor (a computed getter/setter, or a `willSet`/`didSet` observer)
397-
// carries the binding modifier and a translated body, whereas a bodyless
398-
// one (a protocol requirement) carries neither. The property context is
408+
// has a translated body, whereas a bodyless one (a protocol requirement)
409+
// has none. The property context is
399410
// read out *before* translating the body, which resets `ctx` so the
400411
// accessor's context does not leak into the body subtree.
401412
//
@@ -430,11 +441,7 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
430441
}
431442
(None, None) => None,
432443
};
433-
let binding = if body.is_some() {
434-
ctx.outer_modifiers.clone()
435-
} else {
436-
Vec::new()
437-
};
444+
let modifiers = ctx.outer_modifiers.clone();
438445
let chained = chained_modifier(&mut ctx);
439446
let name = ctx
440447
.property_name_node
@@ -452,7 +459,7 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
452459
None => None,
453460
};
454461
tree!((accessor_declaration
455-
modifier: {binding}
462+
modifier: {modifiers}
456463
modifier: {chained}
457464
name_node: {name}
458465
return_type: {return_ty}

‎unified/extractor/tests/corpus/swift/types/protocol-with-read-only-and-read-write-property-requirements.output‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,19 @@ top_level source="⟨body⟩"
111111
name_node: identifier "P" source="P"
112112
member:
113113
accessor_declaration source="⟨accessor_kind⟩"
114+
modifier: modifier "var" source="var" (external)
114115
name_node: identifier "foo" source="foo" (external)
115116
accessor_kind: accessor_kind "get" source="get"
116117
return_type: identifier "Int" source="Int" (external)
117118
accessor_declaration source="⟨accessor_kind⟩"
119+
modifier: modifier "var" source="var" (external)
118120
name_node: identifier "bar" source="bar" (external)
119121
accessor_kind: accessor_kind "get" source="get"
120122
return_type: identifier "String" source="String" (external)
121123
accessor_declaration source="⟨accessor_kind⟩⟨parameter⟩"
122-
modifier: modifier "chained_declaration" source=""
124+
modifier:
125+
modifier "var" source="var" (external)
126+
modifier "chained_declaration" source=""
123127
name_node: identifier "bar" source="bar" (external)
124128
accessor_kind: accessor_kind "set" source="set"
125129
parameter:
@@ -128,6 +132,7 @@ top_level source="⟨body⟩"
128132
type: identifier "String" source="String" (external)
129133
pattern: identifier "newValue" source="set"
130134
accessor_declaration source="⟨accessor_kind⟩"
135+
modifier: modifier "var" source="var" (external)
131136
name_node: identifier "count" source="count" (external)
132137
accessor_kind: accessor_kind "get" source="get"
133138
return_type: identifier "Int" source="Int" (external)

‎unified/ql/test/library-tests/dataflow/accessors_static.swift‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ func t1() {
77
class C {
88
static var x: String { source("t1.1") }
99
}
10-
sink(C.x) // $ MISSING: hasValueFlow=t1.1
10+
sink(C.x) // $ hasValueFlow=t1.1
1111
}
1212

1313
func t2() {
@@ -18,7 +18,7 @@ func t2() {
1818
get { source("t2.1") }
1919
}
2020
}
21-
sink(C.x) // $ MISSING: hasValueFlow=t2.1
21+
sink(C.x) // $ hasValueFlow=t2.1
2222
}
2323

2424
func t3() {
@@ -28,14 +28,14 @@ func t3() {
2828
set {}
2929
}
3030
}
31-
sink(C.x) // $ MISSING: hasValueFlow=t3.1
31+
sink(C.x) // $ hasValueFlow=t3.1
3232
}
3333

3434
func t4() {
3535
class C {
3636
static var x: String {
3737
get {}
38-
set { sink(newValue) } // $ MISSING: hasValueFlow=t4.1
38+
set { sink(newValue) } // $ hasValueFlow=t4.1
3939
}
4040
}
4141
C.x = source("t4.1")
@@ -45,7 +45,7 @@ func t5() {
4545
class C {
4646
static var x: String {
4747
get { source("t5.1") }
48-
set { sink(newValue) } // $ MISSING: hasValueFlow=t5.1
48+
set { sink(newValue) } // $ hasValueFlow=t5.1
4949
}
5050
}
5151
C.x = C.x
@@ -56,11 +56,11 @@ func t6() {
5656
static var x: String { source("t6.1") }
5757

5858
func method() {
59-
sink(Self.x) // $ MISSING: hasValueFlow=t6.1
59+
sink(Self.x) // $ hasValueFlow=t6.1
6060
}
6161

6262
static func staticMethod() {
63-
sink(Self.x) // $ MISSING: hasValueFlow=t6.1
63+
sink(Self.x) // $ hasValueFlow=t6.1
6464
sink(x) // $ hasValueFlow=t6.1
6565
}
6666
}

‎unified/ql/test/library-tests/dataflow/test.expected‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@ edges
1111
| accessors_local.swift:39:9:39:11 | newValue | accessors_local.swift:39:20:39:27 | newValue | provenance | |
1212
| accessors_local.swift:41:5:41:5 | x | accessors_local.swift:39:9:39:11 | newValue | provenance | |
1313
| accessors_local.swift:41:9:41:9 | x | accessors_local.swift:41:5:41:5 | x | provenance | |
14+
| accessors_static.swift:8:32:8:45 | source(...) | accessors_static.swift:10:10:10:12 | ... .x | provenance | |
15+
| accessors_static.swift:18:19:18:32 | source(...) | accessors_static.swift:21:10:21:12 | ... .x | provenance | |
16+
| accessors_static.swift:27:19:27:32 | source(...) | accessors_static.swift:31:10:31:12 | ... .x | provenance | |
17+
| accessors_static.swift:38:13:38:15 | newValue | accessors_static.swift:38:24:38:31 | newValue | provenance | |
18+
| accessors_static.swift:41:5:41:7 | ... .x | accessors_static.swift:38:13:38:15 | newValue | provenance | |
19+
| accessors_static.swift:41:11:41:24 | source(...) | accessors_static.swift:41:5:41:7 | ... .x | provenance | |
20+
| accessors_static.swift:47:19:47:32 | source(...) | accessors_static.swift:51:11:51:13 | ... .x | provenance | |
21+
| accessors_static.swift:48:13:48:15 | newValue | accessors_static.swift:48:24:48:31 | newValue | provenance | |
22+
| accessors_static.swift:51:5:51:7 | ... .x | accessors_static.swift:48:13:48:15 | newValue | provenance | |
23+
| accessors_static.swift:51:11:51:13 | ... .x | accessors_static.swift:51:5:51:7 | ... .x | provenance | |
24+
| accessors_static.swift:56:32:56:45 | source(...) | accessors_static.swift:59:18:59:23 | ... .x | provenance | |
25+
| accessors_static.swift:56:32:56:45 | source(...) | accessors_static.swift:63:18:63:23 | ... .x | provenance | |
1426
| accessors_static.swift:56:32:56:45 | source(...) | accessors_static.swift:64:18:64:18 | x | provenance | |
1527
| calls.swift:7:19:7:19 | x | calls.swift:8:14:8:14 | x | provenance | |
1628
| calls.swift:10:12:10:25 | source(...) | calls.swift:7:19:7:19 | x | provenance | |
@@ -488,7 +500,24 @@ nodes
488500
| accessors_local.swift:39:20:39:27 | newValue | semmle.label | newValue |
489501
| accessors_local.swift:41:5:41:5 | x | semmle.label | x |
490502
| accessors_local.swift:41:9:41:9 | x | semmle.label | x |
503+
| accessors_static.swift:8:32:8:45 | source(...) | semmle.label | source(...) |
504+
| accessors_static.swift:10:10:10:12 | ... .x | semmle.label | ... .x |
505+
| accessors_static.swift:18:19:18:32 | source(...) | semmle.label | source(...) |
506+
| accessors_static.swift:21:10:21:12 | ... .x | semmle.label | ... .x |
507+
| accessors_static.swift:27:19:27:32 | source(...) | semmle.label | source(...) |
508+
| accessors_static.swift:31:10:31:12 | ... .x | semmle.label | ... .x |
509+
| accessors_static.swift:38:13:38:15 | newValue | semmle.label | newValue |
510+
| accessors_static.swift:38:24:38:31 | newValue | semmle.label | newValue |
511+
| accessors_static.swift:41:5:41:7 | ... .x | semmle.label | ... .x |
512+
| accessors_static.swift:41:11:41:24 | source(...) | semmle.label | source(...) |
513+
| accessors_static.swift:47:19:47:32 | source(...) | semmle.label | source(...) |
514+
| accessors_static.swift:48:13:48:15 | newValue | semmle.label | newValue |
515+
| accessors_static.swift:48:24:48:31 | newValue | semmle.label | newValue |
516+
| accessors_static.swift:51:5:51:7 | ... .x | semmle.label | ... .x |
517+
| accessors_static.swift:51:11:51:13 | ... .x | semmle.label | ... .x |
491518
| accessors_static.swift:56:32:56:45 | source(...) | semmle.label | source(...) |
519+
| accessors_static.swift:59:18:59:23 | ... .x | semmle.label | ... .x |
520+
| accessors_static.swift:63:18:63:23 | ... .x | semmle.label | ... .x |
492521
| accessors_static.swift:64:18:64:18 | x | semmle.label | x |
493522
| calls.swift:7:19:7:19 | x | semmle.label | x |
494523
| calls.swift:8:14:8:14 | x | semmle.label | x |
@@ -1073,6 +1102,13 @@ testFailures
10731102
| accessors_local.swift:25:10:25:10 | x | accessors_local.swift:22:15:22:28 | source(...) | accessors_local.swift:25:10:25:10 | x | $@ | accessors_local.swift:22:15:22:28 | source(...) | source(...) |
10741103
| accessors_local.swift:31:20:31:27 | newValue | accessors_local.swift:33:9:33:22 | source(...) | accessors_local.swift:31:20:31:27 | newValue | $@ | accessors_local.swift:33:9:33:22 | source(...) | source(...) |
10751104
| accessors_local.swift:39:20:39:27 | newValue | accessors_local.swift:38:15:38:28 | source(...) | accessors_local.swift:39:20:39:27 | newValue | $@ | accessors_local.swift:38:15:38:28 | source(...) | source(...) |
1105+
| accessors_static.swift:10:10:10:12 | ... .x | accessors_static.swift:8:32:8:45 | source(...) | accessors_static.swift:10:10:10:12 | ... .x | $@ | accessors_static.swift:8:32:8:45 | source(...) | source(...) |
1106+
| accessors_static.swift:21:10:21:12 | ... .x | accessors_static.swift:18:19:18:32 | source(...) | accessors_static.swift:21:10:21:12 | ... .x | $@ | accessors_static.swift:18:19:18:32 | source(...) | source(...) |
1107+
| accessors_static.swift:31:10:31:12 | ... .x | accessors_static.swift:27:19:27:32 | source(...) | accessors_static.swift:31:10:31:12 | ... .x | $@ | accessors_static.swift:27:19:27:32 | source(...) | source(...) |
1108+
| accessors_static.swift:38:24:38:31 | newValue | accessors_static.swift:41:11:41:24 | source(...) | accessors_static.swift:38:24:38:31 | newValue | $@ | accessors_static.swift:41:11:41:24 | source(...) | source(...) |
1109+
| accessors_static.swift:48:24:48:31 | newValue | accessors_static.swift:47:19:47:32 | source(...) | accessors_static.swift:48:24:48:31 | newValue | $@ | accessors_static.swift:47:19:47:32 | source(...) | source(...) |
1110+
| accessors_static.swift:59:18:59:23 | ... .x | accessors_static.swift:56:32:56:45 | source(...) | accessors_static.swift:59:18:59:23 | ... .x | $@ | accessors_static.swift:56:32:56:45 | source(...) | source(...) |
1111+
| accessors_static.swift:63:18:63:23 | ... .x | accessors_static.swift:56:32:56:45 | source(...) | accessors_static.swift:63:18:63:23 | ... .x | $@ | accessors_static.swift:56:32:56:45 | source(...) | source(...) |
10761112
| accessors_static.swift:64:18:64:18 | x | accessors_static.swift:56:32:56:45 | source(...) | accessors_static.swift:64:18:64:18 | x | $@ | accessors_static.swift:56:32:56:45 | source(...) | source(...) |
10771113
| calls.swift:8:14:8:14 | x | calls.swift:10:12:10:25 | source(...) | calls.swift:8:14:8:14 | x | $@ | calls.swift:10:12:10:25 | source(...) | source(...) |
10781114
| calls.swift:17:10:17:17 | target(...) | calls.swift:15:16:15:29 | source(...) | calls.swift:17:10:17:17 | target(...) | $@ | calls.swift:15:16:15:29 | source(...) | source(...) |

0 commit comments

Comments
 (0)