Skip to content

Commit a237f69

Browse files
committed
Swift: show conversions in PrintAst
This also showcases the customizability of the `PrintAst` infrastructure resting on generated code.
1 parent 1f0ca6b commit a237f69

File tree

6 files changed

+500
-328
lines changed

6 files changed

+500
-328
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: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ private newtype TPrintAstNode =
3232
TLocatable(Locatable ast) {
3333
// Only consider resolved nodes (that is not within the hidden conversion AST)
3434
ast = ast.resolve()
35-
}
35+
} or
36+
TConversion(Expr conv) { conv.isConversion() } or
37+
TConversionContainer(Expr e) { e = e.resolve() and e.hasConversions() }
3638

3739
/**
3840
* A node in the output tree.
@@ -66,6 +68,10 @@ class PrintAstNode extends TPrintAstNode {
6668
string getProperty(string key) { none() }
6769
}
6870

71+
private string prettyPrint(Locatable e) {
72+
result = "[" + concat(e.getPrimaryQlClasses(), ", ") + "] " + e
73+
}
74+
6975
/**
7076
* A graph node representing a real Locatable node.
7177
*/
@@ -74,13 +80,64 @@ class PrintLocatable extends PrintAstNode, TLocatable {
7480

7581
PrintLocatable() { this = TLocatable(ast) }
7682

83+
override string toString() { result = prettyPrint(ast) }
84+
7785
final override predicate shouldBePrinted() { shouldPrint(ast) }
7886

7987
override predicate hasChild(PrintAstNode child, int index, string accessor) {
8088
child = TLocatable(getChildAndAccessor(ast, index, accessor))
8189
}
8290

83-
override string toString() { result = "[" + concat(ast.getPrimaryQlClasses(), ", ") + "] " + ast }
84-
8591
final override Location getLocation() { result = ast.getLocation() }
8692
}
93+
94+
/**
95+
* A graph node representing a conversion.
96+
*/
97+
class PrintConversion extends PrintAstNode, TConversion {
98+
Expr conv;
99+
100+
PrintConversion() { this = TConversion(conv) }
101+
102+
override string toString() { result = prettyPrint(conv) }
103+
104+
final override predicate shouldBePrinted() { shouldPrint(conv.resolve()) }
105+
106+
override predicate hasChild(PrintAstNode child, int index, string accessor) { none() }
107+
108+
final override Location getLocation() { result = conv.getLocation() }
109+
}
110+
111+
/**
112+
* A graph node representing a virtual container for conversions.
113+
*/
114+
class PrintConversionContainer extends PrintAstNode, TConversionContainer {
115+
Expr convertee;
116+
117+
PrintConversionContainer() { this = TConversionContainer(convertee) }
118+
119+
override string toString() { result = "" }
120+
121+
final override predicate shouldBePrinted() { shouldPrint(convertee) }
122+
123+
override predicate hasChild(PrintAstNode child, int index, string accessor) {
124+
child = TConversion(convertee.getConversion(index)) and
125+
accessor = "getConversion(" + index + ")"
126+
}
127+
128+
final override Location getLocation() { result = convertee.getFullyConverted().getLocation() }
129+
}
130+
131+
/** A graph node specialization for expressions to show conversions. */
132+
class PrintExpr extends PrintLocatable {
133+
override Expr ast;
134+
135+
override predicate hasChild(PrintAstNode child, int index, string accessor) {
136+
super.hasChild(child, index, accessor)
137+
or
138+
ast.hasConversions() and
139+
index = -1 and
140+
accessor = "conversions" and
141+
child = TConversionContainer(ast)
142+
}
143+
}

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

Lines changed: 127 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -101,157 +101,165 @@
101101
| declarations.swift:50:3:52:3 | +-(_:) |
102102
| declarations.swift:50:22:50:22 | self |
103103
| declarations.swift:50:26:50:33 | other |
104-
| declarations.swift:55:8:55:17 | +- |
105-
| declarations.swift:57:1:62:1 | precedencegroup ... |
106-
| declarations.swift:64:7:64:16 | +++ |
107-
| declarations.swift:66:7:66:21 | *** |
108-
| declarations.swift:68:18:74:1 | ZeroWrapper |
109-
| declarations.swift:68:25:68:25 | init() |
110-
| declarations.swift:68:25:68:25 | self |
111-
| declarations.swift:69:3:73:3 | var ... = ... |
112-
| declarations.swift:69:7:69:7 | wrappedValue |
113-
| declarations.swift:70:5:70:5 | self |
114-
| declarations.swift:70:5:72:5 | get |
115-
| declarations.swift:76:1:79:1 | foo() |
116-
| declarations.swift:77:16:77:23 | var ... = ... |
117-
| declarations.swift:77:20:77:20 | _x |
118-
| declarations.swift:77:20:77:20 | get |
119-
| declarations.swift:77:20:77:20 | x |
120-
| declarations.swift:81:1:136:1 | HasPropertyAndObserver |
121-
| declarations.swift:81:8:81:8 | hasBoth |
122-
| declarations.swift:81:8:81:8 | hasDidSet1 |
123-
| declarations.swift:81:8:81:8 | hasDidSet2 |
124-
| declarations.swift:81:8:81:8 | hasWillSet1 |
125-
| declarations.swift:81:8:81:8 | hasWillSet2 |
126-
| declarations.swift:81:8:81:8 | init(normalField:hasWillSet1:hasWillSet2:hasDidSet1:hasDidSet2:hasBoth:) |
127-
| declarations.swift:81:8:81:8 | normalField |
128-
| declarations.swift:81:8:81:8 | self |
129-
| declarations.swift:82:3:87:3 | var ... = ... |
130-
| declarations.swift:82:7:82:7 | (unnamed function decl) |
131-
| declarations.swift:82:7:82:7 | self |
132-
| declarations.swift:82:7:82:7 | settableField |
133-
| declarations.swift:83:5:83:5 | newValue |
134-
| declarations.swift:83:5:83:5 | self |
135-
| declarations.swift:83:5:83:11 | set |
136-
| declarations.swift:84:5:84:5 | self |
137-
| declarations.swift:84:5:86:5 | get |
138-
| declarations.swift:91:3:93:3 | var ... = ... |
139-
| declarations.swift:91:7:91:7 | readOnlyField1 |
140-
| declarations.swift:91:27:91:27 | self |
141-
| declarations.swift:91:27:93:3 | get |
142-
| declarations.swift:96:3:100:3 | var ... = ... |
143-
| declarations.swift:96:7:96:7 | readOnlyField2 |
144-
| declarations.swift:97:5:97:5 | self |
145-
| declarations.swift:97:5:99:5 | get |
146-
| declarations.swift:102:3:102:21 | var ... = ... |
147-
| declarations.swift:102:7:102:7 | (unnamed function decl) |
148-
| declarations.swift:102:7:102:7 | get |
149-
| declarations.swift:102:7:102:7 | normalField |
150-
| declarations.swift:102:7:102:7 | self |
151-
| declarations.swift:102:7:102:7 | self |
152-
| declarations.swift:102:7:102:7 | self |
153-
| declarations.swift:102:7:102:7 | set |
154-
| declarations.swift:102:7:102:7 | value |
155-
| declarations.swift:104:3:104:3 | (unnamed function decl) |
156-
| declarations.swift:104:3:104:3 | self |
157-
| declarations.swift:104:3:109:3 | subscript ... |
158-
| declarations.swift:104:13:104:13 | x |
159-
| declarations.swift:104:13:104:13 | x |
160-
| declarations.swift:104:13:104:16 | x |
161-
| declarations.swift:105:5:105:5 | self |
162-
| declarations.swift:105:5:107:5 | get |
163-
| declarations.swift:108:5:108:5 | newValue |
164-
| declarations.swift:108:5:108:5 | self |
165-
| declarations.swift:108:5:108:11 | set |
166-
| declarations.swift:111:3:113:3 | subscript ... |
167-
| declarations.swift:111:13:111:13 | x |
168-
| declarations.swift:111:13:111:16 | x |
169-
| declarations.swift:111:21:111:21 | y |
170-
| declarations.swift:111:21:111:25 | y |
171-
| declarations.swift:111:37:111:37 | self |
172-
| declarations.swift:111:37:113:3 | get |
173-
| declarations.swift:115:3:117:3 | var ... = ... |
174-
| declarations.swift:115:7:115:7 | (unnamed function decl) |
175-
| declarations.swift:115:7:115:7 | get |
176-
| declarations.swift:115:7:115:7 | hasWillSet1 |
177-
| declarations.swift:115:7:115:7 | self |
178-
| declarations.swift:115:7:115:7 | self |
179-
| declarations.swift:115:7:115:7 | self |
180-
| declarations.swift:115:7:115:7 | set |
181-
| declarations.swift:115:7:115:7 | value |
182-
| declarations.swift:116:5:116:5 | self |
183-
| declarations.swift:116:5:116:25 | willSet |
184-
| declarations.swift:116:13:116:13 | newValue |
104+
| declarations.swift:55:1:55:22 | Derived |
105+
| declarations.swift:55:7:55:7 | deinit() |
106+
| declarations.swift:55:7:55:7 | self |
107+
| declarations.swift:55:21:55:21 | init() |
108+
| declarations.swift:55:21:55:21 | self |
109+
| declarations.swift:57:1:57:28 | var ... = ... |
110+
| declarations.swift:57:1:57:28 | { ... } |
111+
| declarations.swift:57:5:57:5 | d |
112+
| declarations.swift:59:8:59:17 | +- |
113+
| declarations.swift:61:1:66:1 | precedencegroup ... |
114+
| declarations.swift:68:7:68:16 | +++ |
115+
| declarations.swift:70:7:70:21 | *** |
116+
| declarations.swift:72:18:78:1 | ZeroWrapper |
117+
| declarations.swift:72:25:72:25 | init() |
118+
| declarations.swift:72:25:72:25 | self |
119+
| declarations.swift:73:3:77:3 | var ... = ... |
120+
| declarations.swift:73:7:73:7 | wrappedValue |
121+
| declarations.swift:74:5:74:5 | self |
122+
| declarations.swift:74:5:76:5 | get |
123+
| declarations.swift:80:1:83:1 | foo() |
124+
| declarations.swift:81:16:81:23 | var ... = ... |
125+
| declarations.swift:81:20:81:20 | _x |
126+
| declarations.swift:81:20:81:20 | get |
127+
| declarations.swift:81:20:81:20 | x |
128+
| declarations.swift:85:1:140:1 | HasPropertyAndObserver |
129+
| declarations.swift:85:8:85:8 | hasBoth |
130+
| declarations.swift:85:8:85:8 | hasDidSet1 |
131+
| declarations.swift:85:8:85:8 | hasDidSet2 |
132+
| declarations.swift:85:8:85:8 | hasWillSet1 |
133+
| declarations.swift:85:8:85:8 | hasWillSet2 |
134+
| declarations.swift:85:8:85:8 | init(normalField:hasWillSet1:hasWillSet2:hasDidSet1:hasDidSet2:hasBoth:) |
135+
| declarations.swift:85:8:85:8 | normalField |
136+
| declarations.swift:85:8:85:8 | self |
137+
| declarations.swift:86:3:91:3 | var ... = ... |
138+
| declarations.swift:86:7:86:7 | (unnamed function decl) |
139+
| declarations.swift:86:7:86:7 | self |
140+
| declarations.swift:86:7:86:7 | settableField |
141+
| declarations.swift:87:5:87:5 | newValue |
142+
| declarations.swift:87:5:87:5 | self |
143+
| declarations.swift:87:5:87:11 | set |
144+
| declarations.swift:88:5:88:5 | self |
145+
| declarations.swift:88:5:90:5 | get |
146+
| declarations.swift:95:3:97:3 | var ... = ... |
147+
| declarations.swift:95:7:95:7 | readOnlyField1 |
148+
| declarations.swift:95:27:95:27 | self |
149+
| declarations.swift:95:27:97:3 | get |
150+
| declarations.swift:100:3:104:3 | var ... = ... |
151+
| declarations.swift:100:7:100:7 | readOnlyField2 |
152+
| declarations.swift:101:5:101:5 | self |
153+
| declarations.swift:101:5:103:5 | get |
154+
| declarations.swift:106:3:106:21 | var ... = ... |
155+
| declarations.swift:106:7:106:7 | (unnamed function decl) |
156+
| declarations.swift:106:7:106:7 | get |
157+
| declarations.swift:106:7:106:7 | normalField |
158+
| declarations.swift:106:7:106:7 | self |
159+
| declarations.swift:106:7:106:7 | self |
160+
| declarations.swift:106:7:106:7 | self |
161+
| declarations.swift:106:7:106:7 | set |
162+
| declarations.swift:106:7:106:7 | value |
163+
| declarations.swift:108:3:108:3 | (unnamed function decl) |
164+
| declarations.swift:108:3:108:3 | self |
165+
| declarations.swift:108:3:113:3 | subscript ... |
166+
| declarations.swift:108:13:108:13 | x |
167+
| declarations.swift:108:13:108:13 | x |
168+
| declarations.swift:108:13:108:16 | x |
169+
| declarations.swift:109:5:109:5 | self |
170+
| declarations.swift:109:5:111:5 | get |
171+
| declarations.swift:112:5:112:5 | newValue |
172+
| declarations.swift:112:5:112:5 | self |
173+
| declarations.swift:112:5:112:11 | set |
174+
| declarations.swift:115:3:117:3 | subscript ... |
175+
| declarations.swift:115:13:115:13 | x |
176+
| declarations.swift:115:13:115:16 | x |
177+
| declarations.swift:115:21:115:21 | y |
178+
| declarations.swift:115:21:115:25 | y |
179+
| declarations.swift:115:37:115:37 | self |
180+
| declarations.swift:115:37:117:3 | get |
185181
| declarations.swift:119:3:121:3 | var ... = ... |
186182
| declarations.swift:119:7:119:7 | (unnamed function decl) |
187183
| declarations.swift:119:7:119:7 | get |
188-
| declarations.swift:119:7:119:7 | hasWillSet2 |
184+
| declarations.swift:119:7:119:7 | hasWillSet1 |
189185
| declarations.swift:119:7:119:7 | self |
190186
| declarations.swift:119:7:119:7 | self |
191187
| declarations.swift:119:7:119:7 | self |
192188
| declarations.swift:119:7:119:7 | set |
193189
| declarations.swift:119:7:119:7 | value |
194-
| declarations.swift:120:5:120:5 | newValue |
195190
| declarations.swift:120:5:120:5 | self |
196-
| declarations.swift:120:5:120:15 | willSet |
191+
| declarations.swift:120:5:120:25 | willSet |
192+
| declarations.swift:120:13:120:13 | newValue |
197193
| declarations.swift:123:3:125:3 | var ... = ... |
198194
| declarations.swift:123:7:123:7 | (unnamed function decl) |
199195
| declarations.swift:123:7:123:7 | get |
200-
| declarations.swift:123:7:123:7 | hasDidSet1 |
196+
| declarations.swift:123:7:123:7 | hasWillSet2 |
201197
| declarations.swift:123:7:123:7 | self |
202198
| declarations.swift:123:7:123:7 | self |
203199
| declarations.swift:123:7:123:7 | self |
204200
| declarations.swift:123:7:123:7 | set |
205201
| declarations.swift:123:7:123:7 | value |
202+
| declarations.swift:124:5:124:5 | newValue |
206203
| declarations.swift:124:5:124:5 | self |
207-
| declarations.swift:124:5:124:24 | didSet |
208-
| declarations.swift:124:12:124:12 | oldValue |
204+
| declarations.swift:124:5:124:15 | willSet |
209205
| declarations.swift:127:3:129:3 | var ... = ... |
210206
| declarations.swift:127:7:127:7 | (unnamed function decl) |
211207
| declarations.swift:127:7:127:7 | get |
212-
| declarations.swift:127:7:127:7 | hasDidSet2 |
208+
| declarations.swift:127:7:127:7 | hasDidSet1 |
213209
| declarations.swift:127:7:127:7 | self |
214210
| declarations.swift:127:7:127:7 | self |
215211
| declarations.swift:127:7:127:7 | self |
216212
| declarations.swift:127:7:127:7 | set |
217213
| declarations.swift:127:7:127:7 | value |
218214
| declarations.swift:128:5:128:5 | self |
219-
| declarations.swift:128:5:128:14 | didSet |
220-
| declarations.swift:131:3:135:3 | var ... = ... |
215+
| declarations.swift:128:5:128:24 | didSet |
216+
| declarations.swift:128:12:128:12 | oldValue |
217+
| declarations.swift:131:3:133:3 | var ... = ... |
221218
| declarations.swift:131:7:131:7 | (unnamed function decl) |
222219
| declarations.swift:131:7:131:7 | get |
223-
| declarations.swift:131:7:131:7 | hasBoth |
220+
| declarations.swift:131:7:131:7 | hasDidSet2 |
224221
| declarations.swift:131:7:131:7 | self |
225222
| declarations.swift:131:7:131:7 | self |
226223
| declarations.swift:131:7:131:7 | self |
227224
| declarations.swift:131:7:131:7 | set |
228225
| declarations.swift:131:7:131:7 | value |
229-
| declarations.swift:132:5:132:5 | newValue |
230226
| declarations.swift:132:5:132:5 | self |
231-
| declarations.swift:132:5:132:15 | willSet |
232-
| declarations.swift:134:5:134:5 | self |
233-
| declarations.swift:134:5:134:14 | didSet |
234-
| declarations.swift:138:1:142:1 | extension |
235-
| declarations.swift:139:3:141:3 | id() |
236-
| declarations.swift:139:8:139:8 | self |
237-
| declarations.swift:144:1:144:7 | { ... } |
238-
| declarations.swift:146:1:148:1 | GenericClass |
239-
| declarations.swift:146:7:146:7 | deinit() |
240-
| declarations.swift:146:7:146:7 | init() |
241-
| declarations.swift:146:7:146:7 | self |
242-
| declarations.swift:146:7:146:7 | self |
243-
| declarations.swift:146:20:146:20 | A |
244-
| declarations.swift:146:23:146:26 | B |
245-
| declarations.swift:146:31:146:34 | C |
246-
| declarations.swift:147:3:147:41 | genericMethod(_:_:_:) |
247-
| declarations.swift:147:8:147:8 | self |
248-
| declarations.swift:147:22:147:25 | _ |
249-
| declarations.swift:147:28:147:31 | _ |
250-
| declarations.swift:147:34:147:37 | _ |
251-
| declarations.swift:150:1:150:63 | genericFunc(_:_:_:) |
252-
| declarations.swift:150:18:150:18 | A |
253-
| declarations.swift:150:21:150:24 | B |
254-
| declarations.swift:150:29:150:32 | C |
255-
| declarations.swift:150:44:150:47 | _ |
256-
| declarations.swift:150:50:150:53 | _ |
257-
| declarations.swift:150:56:150:59 | _ |
227+
| declarations.swift:132:5:132:14 | didSet |
228+
| declarations.swift:135:3:139:3 | var ... = ... |
229+
| declarations.swift:135:7:135:7 | (unnamed function decl) |
230+
| declarations.swift:135:7:135:7 | get |
231+
| declarations.swift:135:7:135:7 | hasBoth |
232+
| declarations.swift:135:7:135:7 | self |
233+
| declarations.swift:135:7:135:7 | self |
234+
| declarations.swift:135:7:135:7 | self |
235+
| declarations.swift:135:7:135:7 | set |
236+
| declarations.swift:135:7:135:7 | value |
237+
| declarations.swift:136:5:136:5 | newValue |
238+
| declarations.swift:136:5:136:5 | self |
239+
| declarations.swift:136:5:136:15 | willSet |
240+
| declarations.swift:138:5:138:5 | self |
241+
| declarations.swift:138:5:138:14 | didSet |
242+
| declarations.swift:142:1:146:1 | extension |
243+
| declarations.swift:143:3:145:3 | id() |
244+
| declarations.swift:143:8:143:8 | self |
245+
| declarations.swift:148:1:148:7 | { ... } |
246+
| declarations.swift:150:1:152:1 | GenericClass |
247+
| declarations.swift:150:7:150:7 | deinit() |
248+
| declarations.swift:150:7:150:7 | init() |
249+
| declarations.swift:150:7:150:7 | self |
250+
| declarations.swift:150:7:150:7 | self |
251+
| declarations.swift:150:20:150:20 | A |
252+
| declarations.swift:150:23:150:26 | B |
253+
| declarations.swift:150:31:150:34 | C |
254+
| declarations.swift:151:3:151:41 | genericMethod(_:_:_:) |
255+
| declarations.swift:151:8:151:8 | self |
256+
| declarations.swift:151:22:151:25 | _ |
257+
| declarations.swift:151:28:151:31 | _ |
258+
| declarations.swift:151:34:151:37 | _ |
259+
| declarations.swift:154:1:154:63 | genericFunc(_:_:_:) |
260+
| declarations.swift:154:18:154:18 | A |
261+
| declarations.swift:154:21:154:24 | B |
262+
| declarations.swift:154:29:154:32 | C |
263+
| declarations.swift:154:44:154:47 | _ |
264+
| declarations.swift:154:50:154:53 | _ |
265+
| declarations.swift:154:56:154:59 | _ |

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ class Baz {
5252
}
5353
}
5454

55+
class Derived : Baz {}
56+
57+
var d: Baz? = Derived() as Baz
58+
5559
prefix operator +-
5660

5761
precedencegroup NewPrecedence {

0 commit comments

Comments
 (0)