Skip to content

Commit 3f45b73

Browse files
committed
Swift: pattern visitor
This transfers the current state of `PatternVisitor` from the proof-of-concept.
1 parent 19506da commit 3f45b73

File tree

16 files changed

+341
-22
lines changed

16 files changed

+341
-22
lines changed

swift/codegen/schema.yml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -491,46 +491,46 @@ AnyPattern:
491491

492492
BindingPattern:
493493
_extends: Pattern
494-
# sub_pattern: Pattern
494+
sub_pattern: Pattern
495495

496496
BoolPattern:
497497
_extends: Pattern
498-
# value: boolean
498+
value: boolean
499499

500500
EnumElementPattern:
501501
_extends: Pattern
502-
# element: EnumElementDecl
503-
# sub_pattern: Pattern?
502+
element: EnumElementDecl
503+
sub_pattern: Pattern?
504504

505505
ExprPattern:
506506
_extends: Pattern
507-
# sub_expr: Expr
507+
sub_expr: Expr
508508

509509
IsPattern:
510510
_extends: Pattern
511-
# cast_type_repr: TypeRepr?
512-
# sub_pattern: Pattern?
511+
cast_type_repr: TypeRepr?
512+
sub_pattern: Pattern?
513513

514514
NamedPattern:
515515
_extends: Pattern
516-
# name: string
516+
name: string
517517

518518
OptionalSomePattern:
519519
_extends: Pattern
520-
# sub_pattern: Pattern
520+
sub_pattern: Pattern
521521

522522
ParenPattern:
523523
_extends: Pattern
524-
# sub_pattern: Pattern
524+
sub_pattern: Pattern
525525

526526
TuplePattern:
527527
_extends: Pattern
528-
# elements: Pattern*
528+
elements: Pattern*
529529

530530
TypedPattern:
531531
_extends: Pattern
532-
# sub_pattern: Pattern
533-
# type_repr: TypeRepr?
532+
sub_pattern: Pattern
533+
type_repr: TypeRepr?
534534

535535
BraceStmt:
536536
_extends: Stmt

swift/extractor/visitors/PatternVisitor.h

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,91 @@ namespace codeql {
77
class PatternVisitor : public AstVisitorBase<PatternVisitor> {
88
public:
99
using AstVisitorBase<PatternVisitor>::AstVisitorBase;
10-
};
1110

11+
void visitNamedPattern(swift::NamedPattern* pattern) {
12+
auto label = dispatcher_.assignNewLabel(pattern);
13+
// TODO: in some (but not all) cases, this seems to introduce a duplicate entry
14+
// for example the vars listed in a case stmt have a different pointer than then ones in
15+
// patterns.
16+
// assert(pattern->getDecl() && "expect NamedPattern to have Decl");
17+
// dispatcher_.emit(NamedPatternsTrap{label, pattern->getNameStr().str(),
18+
// dispatcher_.fetchLabel(pattern->getDecl())});
19+
dispatcher_.emit(NamedPatternsTrap{label, pattern->getNameStr().str()});
20+
}
21+
22+
void visitTypedPattern(swift::TypedPattern* pattern) {
23+
auto label = dispatcher_.assignNewLabel(pattern);
24+
assert(pattern->getSubPattern() && "expect TypedPattern to have a SubPattern");
25+
dispatcher_.emit(TypedPatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubPattern())});
26+
if (auto typeRepr = pattern->getTypeRepr()) {
27+
dispatcher_.emit(
28+
TypedPatternTypeReprsTrap{label, dispatcher_.fetchLabel(pattern->getTypeRepr())});
29+
}
30+
}
31+
32+
void visitTuplePattern(swift::TuplePattern* pattern) {
33+
auto label = dispatcher_.assignNewLabel(pattern);
34+
dispatcher_.emit(TuplePatternsTrap{label});
35+
auto i = 0u;
36+
for (auto p : pattern->getElements()) {
37+
dispatcher_.emit(
38+
TuplePatternElementsTrap{label, i++, dispatcher_.fetchLabel(p.getPattern())});
39+
}
40+
}
41+
void visitAnyPattern(swift::AnyPattern* pattern) {
42+
dispatcher_.emit(AnyPatternsTrap{dispatcher_.assignNewLabel(pattern)});
43+
}
44+
45+
void visitBindingPattern(swift::BindingPattern* pattern) {
46+
auto label = dispatcher_.assignNewLabel(pattern);
47+
assert(pattern->getSubPattern() && "expect BindingPattern to have a SubPattern");
48+
dispatcher_.emit(BindingPatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubPattern())});
49+
}
50+
51+
void visitEnumElementPattern(swift::EnumElementPattern* pattern) {
52+
auto label = dispatcher_.assignNewLabel(pattern);
53+
dispatcher_.emit(
54+
EnumElementPatternsTrap{label, dispatcher_.fetchLabel(pattern->getElementDecl())});
55+
if (auto subPattern = pattern->getSubPattern()) {
56+
dispatcher_.emit(EnumElementPatternSubPatternsTrap{
57+
label, dispatcher_.fetchLabel(pattern->getSubPattern())});
58+
}
59+
}
60+
61+
void visitOptionalSomePattern(swift::OptionalSomePattern* pattern) {
62+
auto label = dispatcher_.assignNewLabel(pattern);
63+
assert(pattern->getSubPattern() && "expect BindingPattern to have a SubPattern");
64+
dispatcher_.emit(
65+
OptionalSomePatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubPattern())});
66+
}
67+
68+
void visitIsPattern(swift::IsPattern* pattern) {
69+
auto label = dispatcher_.assignNewLabel(pattern);
70+
dispatcher_.emit(IsPatternsTrap{label});
71+
72+
if (auto typeRepr = pattern->getCastTypeRepr()) {
73+
dispatcher_.emit(IsPatternCastTypeReprsTrap{label, dispatcher_.fetchLabel(typeRepr)});
74+
}
75+
if (auto subPattern = pattern->getSubPattern()) {
76+
dispatcher_.emit(IsPatternSubPatternsTrap{label, dispatcher_.fetchLabel(subPattern)});
77+
}
78+
}
79+
80+
void visitExprPattern(swift::ExprPattern* pattern) {
81+
auto label = dispatcher_.assignNewLabel(pattern);
82+
assert(pattern->getSubExpr() && "expect ExprPattern to have SubExpr");
83+
dispatcher_.emit(ExprPatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubExpr())});
84+
}
85+
86+
void visitParenPattern(swift::ParenPattern* pattern) {
87+
auto label = dispatcher_.assignNewLabel(pattern);
88+
assert(pattern->getSubPattern() && "expect ParenPattern to have SubPattern");
89+
dispatcher_.emit(ParenPatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubPattern())});
90+
}
91+
92+
void visitBoolPattern(swift::BoolPattern* pattern) {
93+
auto label = dispatcher_.assignNewLabel(pattern);
94+
dispatcher_.emit(BoolPatternsTrap{label, pattern->getValue()});
95+
}
96+
};
1297
} // namespace codeql

swift/ql/lib/codeql/swift/generated/pattern/BindingPattern.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,11 @@ import codeql.swift.elements.pattern.Pattern
33

44
class BindingPatternBase extends @binding_pattern, Pattern {
55
override string getAPrimaryQlClass() { result = "BindingPattern" }
6+
7+
Pattern getSubPattern() {
8+
exists(Pattern x |
9+
binding_patterns(this, x) and
10+
result = x.resolve()
11+
)
12+
}
613
}

swift/ql/lib/codeql/swift/generated/pattern/BoolPattern.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ import codeql.swift.elements.pattern.Pattern
33

44
class BoolPatternBase extends @bool_pattern, Pattern {
55
override string getAPrimaryQlClass() { result = "BoolPattern" }
6+
7+
boolean getValue() { bool_patterns(this, result) }
68
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
// generated by codegen/codegen.py
2+
import codeql.swift.elements.decl.EnumElementDecl
23
import codeql.swift.elements.pattern.Pattern
34

45
class EnumElementPatternBase extends @enum_element_pattern, Pattern {
56
override string getAPrimaryQlClass() { result = "EnumElementPattern" }
7+
8+
EnumElementDecl getElement() {
9+
exists(EnumElementDecl x |
10+
enum_element_patterns(this, x) and
11+
result = x.resolve()
12+
)
13+
}
14+
15+
Pattern getSubPattern() {
16+
exists(Pattern x |
17+
enum_element_pattern_sub_patterns(this, x) and
18+
result = x.resolve()
19+
)
20+
}
21+
22+
predicate hasSubPattern() { exists(getSubPattern()) }
623
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
// generated by codegen/codegen.py
2+
import codeql.swift.elements.expr.Expr
23
import codeql.swift.elements.pattern.Pattern
34

45
class ExprPatternBase extends @expr_pattern, Pattern {
56
override string getAPrimaryQlClass() { result = "ExprPattern" }
7+
8+
Expr getSubExpr() {
9+
exists(Expr x |
10+
expr_patterns(this, x) and
11+
result = x.resolve()
12+
)
13+
}
614
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
11
// generated by codegen/codegen.py
22
import codeql.swift.elements.pattern.Pattern
3+
import codeql.swift.elements.typerepr.TypeRepr
34

45
class IsPatternBase extends @is_pattern, Pattern {
56
override string getAPrimaryQlClass() { result = "IsPattern" }
7+
8+
TypeRepr getCastTypeRepr() {
9+
exists(TypeRepr x |
10+
is_pattern_cast_type_reprs(this, x) and
11+
result = x.resolve()
12+
)
13+
}
14+
15+
predicate hasCastTypeRepr() { exists(getCastTypeRepr()) }
16+
17+
Pattern getSubPattern() {
18+
exists(Pattern x |
19+
is_pattern_sub_patterns(this, x) and
20+
result = x.resolve()
21+
)
22+
}
23+
24+
predicate hasSubPattern() { exists(getSubPattern()) }
625
}

swift/ql/lib/codeql/swift/generated/pattern/NamedPattern.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ import codeql.swift.elements.pattern.Pattern
33

44
class NamedPatternBase extends @named_pattern, Pattern {
55
override string getAPrimaryQlClass() { result = "NamedPattern" }
6+
7+
string getName() { named_patterns(this, result) }
68
}

swift/ql/lib/codeql/swift/generated/pattern/OptionalSomePattern.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,11 @@ import codeql.swift.elements.pattern.Pattern
33

44
class OptionalSomePatternBase extends @optional_some_pattern, Pattern {
55
override string getAPrimaryQlClass() { result = "OptionalSomePattern" }
6+
7+
Pattern getSubPattern() {
8+
exists(Pattern x |
9+
optional_some_patterns(this, x) and
10+
result = x.resolve()
11+
)
12+
}
613
}

swift/ql/lib/codeql/swift/generated/pattern/ParenPattern.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,11 @@ import codeql.swift.elements.pattern.Pattern
33

44
class ParenPatternBase extends @paren_pattern, Pattern {
55
override string getAPrimaryQlClass() { result = "ParenPattern" }
6+
7+
Pattern getSubPattern() {
8+
exists(Pattern x |
9+
paren_patterns(this, x) and
10+
result = x.resolve()
11+
)
12+
}
613
}

0 commit comments

Comments
 (0)