Skip to content

Commit 48761b8

Browse files
authored
Merge pull request #10233 from github/redsun82/swift-conversions-in-print-ast
Swift: show conversions in `PrintAst`
2 parents 6d5d78e + 2234070 commit 48761b8

File tree

6 files changed

+556
-10
lines changed

6 files changed

+556
-10
lines changed

swift/ql/lib/codeql/swift/elements/expr/Expr.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ class Expr extends ExprBase {
77

88
Expr getConversion() { result.convertsFrom(this) }
99

10+
Expr getConversion(int n) {
11+
n = 0 and result = this.getConversion()
12+
or
13+
result = this.getConversion(n - 1).getConversion()
14+
}
15+
1016
predicate isConversion() { this.convertsFrom(_) }
1117

1218
predicate hasConversions() { exists(this.getConversion()) }

swift/ql/lib/codeql/swift/printast/PrintAstNode.qll

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,7 @@ private predicate shouldPrint(Locatable e) { any(PrintAstConfiguration config).s
2828
/**
2929
* An AST node that should be printed.
3030
*/
31-
private newtype TPrintAstNode =
32-
TLocatable(Locatable ast) {
33-
// Only consider resolved nodes (that is not within the hidden conversion AST)
34-
ast = ast.resolve()
35-
}
31+
private newtype TPrintAstNode = TLocatable(Locatable ast)
3632

3733
/**
3834
* A node in the output tree.
@@ -47,7 +43,7 @@ class PrintAstNode extends TPrintAstNode {
4743
* Gets the child node at index `index`. Child indices must be unique,
4844
* but need not be contiguous.
4945
*/
50-
abstract predicate hasChild(PrintAstNode child, int index, string accessor);
46+
abstract predicate hasChild(PrintAstNode child, int index, string label);
5147

5248
/**
5349
* Holds if this node should be printed in the output.
@@ -66,6 +62,14 @@ class PrintAstNode extends TPrintAstNode {
6662
string getProperty(string key) { none() }
6763
}
6864

65+
private string prettyPrint(Locatable e) {
66+
result = "[" + concat(e.getPrimaryQlClasses(), ", ") + "] " + e
67+
}
68+
69+
private class Unresolved extends Locatable {
70+
Unresolved() { this != this.resolve() }
71+
}
72+
6973
/**
7074
* A graph node representing a real Locatable node.
7175
*/
@@ -74,13 +78,60 @@ class PrintLocatable extends PrintAstNode, TLocatable {
7478

7579
PrintLocatable() { this = TLocatable(ast) }
7680

81+
override string toString() { result = prettyPrint(ast) }
82+
7783
final override predicate shouldBePrinted() { shouldPrint(ast) }
7884

79-
override predicate hasChild(PrintAstNode child, int index, string accessor) {
80-
child = TLocatable(getChildAndAccessor(ast, index, accessor))
85+
override predicate hasChild(PrintAstNode child, int index, string label) {
86+
exists(Locatable c, int i, string accessor |
87+
c = getChildAndAccessor(ast, i, accessor) and
88+
(
89+
// use even indexes for normal children, leaving odd slots for conversions if any
90+
child = TLocatable(c) and index = 2 * i and label = accessor
91+
or
92+
child = TLocatable(c.getFullyUnresolved().(Unresolved)) and
93+
index = 2 * i + 1 and
94+
(
95+
if c instanceof Expr
96+
then label = accessor + ".getFullyConverted()"
97+
else label = accessor + ".getFullyUnresolved()"
98+
)
99+
)
100+
)
81101
}
82102

83-
override string toString() { result = "[" + concat(ast.getPrimaryQlClasses(), ", ") + "] " + ast }
84-
85103
final override Location getLocation() { result = ast.getLocation() }
86104
}
105+
106+
/**
107+
* A specialization of graph node for "unresolved" children, that is nodes in
108+
* the parallel conversion AST.
109+
*/
110+
class PrintUnresolved extends PrintLocatable {
111+
override Unresolved ast;
112+
113+
override predicate hasChild(PrintAstNode child, int index, string label) {
114+
// only print immediate unresolved children from the "parallel" AST
115+
child = TLocatable(getImmediateChildAndAccessor(ast, index, label).(Unresolved))
116+
}
117+
}
118+
119+
/**
120+
* A specialization of graph node for `VarDecl`, to add typing information.
121+
*/
122+
class PrintVarDecl extends PrintLocatable {
123+
override VarDecl ast;
124+
125+
override string getProperty(string key) { key = "Type" and result = ast.getType().toString() }
126+
}
127+
128+
/**
129+
* A specialization of graph node for `AbstractFunctionDecl`, to add typing information.
130+
*/
131+
class PrintAbstractFunctionDecl extends PrintLocatable {
132+
override AbstractFunctionDecl ast;
133+
134+
override string getProperty(string key) {
135+
key = "InterfaceType" and result = ast.getInterfaceType().toString()
136+
}
137+
}

swift/ql/test/extractor-tests/declarations/all.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,3 +255,11 @@
255255
| declarations.swift:150:44:150:47 | _ |
256256
| declarations.swift:150:50:150:53 | _ |
257257
| declarations.swift:150:56:150:59 | _ |
258+
| declarations.swift:152:1:152:22 | Derived |
259+
| declarations.swift:152:7:152:7 | deinit() |
260+
| declarations.swift:152:7:152:7 | self |
261+
| declarations.swift:152:21:152:21 | init() |
262+
| declarations.swift:152:21:152:21 | self |
263+
| declarations.swift:155:1:155:28 | var ... = ... |
264+
| declarations.swift:155:1:155:28 | { ... } |
265+
| declarations.swift:155:5:155:5 | d |

swift/ql/test/extractor-tests/declarations/declarations.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,8 @@ class GenericClass<A, B: Baz, C: MyProtocol> {
148148
}
149149

150150
func genericFunc<A, B: Baz, C: MyProtocol>(_: A, _: B, _: C) {}
151+
152+
class Derived : Baz {}
153+
154+
// multiple conversions
155+
var d: Baz? = Derived() as Baz

0 commit comments

Comments
 (0)