Skip to content

Commit 26f0d3a

Browse files
committed
Swift: Add helper predicates on AST classes
1 parent 1e9fcfb commit 26f0d3a

22 files changed

+219
-38
lines changed

swift/ql/lib/codeql/swift/elements/Element.qll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
private import codeql.swift.generated.Element
22

33
class Element extends ElementBase {
4+
private predicate resolvesTo(Element e) { e.getResolveStep() = this }
5+
46
override string toString() { result = getPrimaryQlClasses() }
7+
8+
Element getFullyUnresolved() {
9+
not this.resolvesTo(_) and result = this
10+
or
11+
exists(Element e |
12+
this.resolvesTo(e) and
13+
result = e.getFullyUnresolved()
14+
)
15+
}
516
}
617

718
class UnknownElement extends Element {
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
21
private import codeql.swift.generated.expr.ApplyExpr
2+
private import codeql.swift.elements.decl.FuncDecl
3+
private import codeql.swift.elements.expr.DeclRefExpr
34

4-
class ApplyExpr extends ApplyExprBase { }
5+
class ApplyExpr extends ApplyExprBase {
6+
FuncDecl getStaticTarget() { result = this.getFunction().(DeclRefExpr).getDecl() }
7+
}
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
21
private import codeql.swift.generated.expr.AutoClosureExpr
2+
private import codeql.swift.elements.stmt.ReturnStmt
33

4-
class AutoClosureExpr extends AutoClosureExprBase { }
4+
class AutoClosureExpr extends AutoClosureExprBase {
5+
/** Gets the implicit return statement generated by this autoclosure expression. */
6+
ReturnStmt getReturn() { result = unique( | | this.getBody().getAnElement()) }
7+
}
Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
21
private import codeql.swift.generated.expr.BinaryExpr
2+
private import codeql.swift.elements.expr.Expr
33

4-
class BinaryExpr extends BinaryExprBase { }
4+
class BinaryExpr extends BinaryExprBase {
5+
Expr getLeftOperand() { result = getArgument(0).getExpr() }
6+
7+
Expr getRightOperand() { result = getArgument(1).getExpr() }
8+
9+
Expr getAnOperand() { result = [this.getLeftOperand(), this.getRightOperand()] }
10+
}
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
21
private import codeql.swift.generated.expr.ExplicitCastExpr
32

4-
class ExplicitCastExpr extends ExplicitCastExprBase { }
3+
class ExplicitCastExpr extends ExplicitCastExprBase {
4+
override predicate convertsFrom(Expr e) { explicit_cast_exprs(this, e) }
5+
}
Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
1-
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
21
private import codeql.swift.generated.expr.Expr
32

4-
class Expr extends ExprBase { }
3+
class Expr extends ExprBase {
4+
final override Expr getResolveStep() { convertsFrom(result) }
5+
6+
predicate convertsFrom(Expr e) { none() } // overridden by subclasses
7+
8+
Expr getConversion() { result.convertsFrom(this) }
9+
10+
predicate isConversion() { convertsFrom(_) }
11+
12+
predicate hasConversions() { exists(getConversion()) }
13+
14+
Expr getFullyConverted() { result = this.getFullyUnresolved() }
15+
16+
Expr getUnconverted() { result = this.resolve() }
17+
}
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
21
private import codeql.swift.generated.expr.IdentityExpr
32

4-
class IdentityExpr extends IdentityExprBase { }
3+
class IdentityExpr extends IdentityExprBase {
4+
override predicate convertsFrom(Expr e) { identity_exprs(this, e) }
5+
}
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
21
private import codeql.swift.generated.expr.IfExpr
32

4-
class IfExpr extends IfExprBase { }
3+
class IfExpr extends IfExprBase {
4+
Expr getBranch(boolean b) {
5+
b = true and
6+
result = this.getThenExpr()
7+
or
8+
b = false and
9+
result = this.getElseExpr()
10+
}
11+
}
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
21
private import codeql.swift.generated.expr.ImplicitConversionExpr
32

4-
class ImplicitConversionExpr extends ImplicitConversionExprBase { }
3+
class ImplicitConversionExpr extends ImplicitConversionExprBase {
4+
override predicate convertsFrom(Expr e) { implicit_conversion_exprs(this, e) }
5+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
private import codeql.swift.elements.expr.Expr
2+
private import codeql.swift.elements.expr.BinaryExpr
3+
private import codeql.swift.elements.expr.PrefixUnaryExpr
4+
private import codeql.swift.elements.expr.DotSyntaxCallExpr
5+
private import codeql.swift.elements.expr.DeclRefExpr
6+
private import codeql.swift.elements.decl.ConcreteFuncDecl
7+
8+
private predicate unaryHasName(PrefixUnaryExpr e, string name) {
9+
e.getFunction()
10+
.(DotSyntaxCallExpr)
11+
.getFunction()
12+
.(DeclRefExpr)
13+
.getDecl()
14+
.(ConcreteFuncDecl)
15+
.getName() = name
16+
}
17+
18+
private predicate binaryHasName(BinaryExpr e, string name) {
19+
e.getFunction()
20+
.(DotSyntaxCallExpr)
21+
.getFunction()
22+
.(DeclRefExpr)
23+
.getDecl()
24+
.(ConcreteFuncDecl)
25+
.getName() = name
26+
}
27+
28+
class LogicalAndExpr extends BinaryExpr {
29+
LogicalAndExpr() { binaryHasName(this, "&&") }
30+
}
31+
32+
class LogicalOrExpr extends BinaryExpr {
33+
LogicalOrExpr() { binaryHasName(this, "||") }
34+
}
35+
36+
class BinaryLogicalOperation extends BinaryExpr {
37+
BinaryLogicalOperation() {
38+
this instanceof LogicalAndExpr or
39+
this instanceof LogicalOrExpr
40+
}
41+
}
42+
43+
class NotExpr extends PrefixUnaryExpr {
44+
NotExpr() { unaryHasName(this, "!") }
45+
}
46+
47+
class UnaryLogicalOperation extends PrefixUnaryExpr {
48+
UnaryLogicalOperation() { this instanceof NotExpr }
49+
}
50+
51+
class LogicalOperation extends Expr {
52+
LogicalOperation() {
53+
this instanceof BinaryLogicalOperation or
54+
this instanceof UnaryLogicalOperation
55+
}
56+
57+
Expr getAnOperand() {
58+
result = this.(BinaryLogicalOperation).getAnOperand()
59+
or
60+
result = this.(UnaryLogicalOperation).getOperand()
61+
}
62+
}

0 commit comments

Comments
 (0)