You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: swift/codegen/templates/ql_parent.mustache
+60-11Lines changed: 60 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -2,33 +2,82 @@
2
2
3
3
import codeql.swift.elements
4
4
5
+
module Impl {
6
+
{{#classes}}
7
+
int getMaximumChildrenIndex{{name}}({{name}} e) {
8
+
{{#root}}e = e and{{/root}}
9
+
result = 0
10
+
{{#bases}}
11
+
+ getMaximumChildrenIndex{{.}}(e)
12
+
{{/bases}}
13
+
{{#properties}}
14
+
{{#is_child}}
15
+
+ 1{{#is_repeated}}+ max(int i | exists(e.getImmediate{{singular}}(i)) | i){{/is_repeated}}
16
+
{{/is_child}}
17
+
{{/properties}}
18
+
}
19
+
20
+
{{/classes}}
5
21
/**
6
22
* Gets any of the "immediate" children of `e`. "Immediate" means not taking into account node resolution: for example
7
23
* if the AST child is the first of a series of conversions that would normally be hidden away, this will select the
8
24
* next conversion down the hidden AST tree instead of the corresponding fully uncoverted node at the bottom.
9
25
* Outside this module this file is mainly intended to be used to test uniqueness of parents.
10
26
*/
11
27
cached
12
-
Element getAnImmediateChild(Element e) {
28
+
Element getImmediateChild(Element e, int index, string partialAccessor) {
13
29
// why does this look more complicated than it should?
14
30
// * none() simplifies generation, as we can append `or ...` without a special case for the first item
15
31
none()
16
32
{{#classes}}
17
-
{{#properties}}
18
-
{{#is_child}}
19
-
or
20
-
result = e.({{name}}).getImmediate{{singular}}({{#is_repeated}}_{{/is_repeated}})
21
-
{{/is_child}}
22
-
{{/properties}}
33
+
{{#has_children}}
34
+
or
35
+
exists(int n{{#properties}}{{#is_child}}, int n{{singular}}{{/is_child}}{{/properties}} |
36
+
n = 0{{#bases}} + getMaximumChildrenIndex{{.}}(e){{/bases}}
37
+
{{#properties}}
38
+
{{#is_child}}
39
+
and n{{singular}} = n{{prev_child}} + 1{{#is_repeated}} + max(int i | i = 0 or exists(e.({{name}}).getImmediate{{singular}}(i)) | i){{/is_repeated}}
40
+
{{/is_child}}
41
+
{{/properties}}
42
+
and (
43
+
none()
44
+
{{#properties}}
45
+
{{#is_child}}
46
+
or
47
+
{{#is_repeated}}
48
+
result = e.({{name}}).getImmediate{{singular}}(index - n{{prev_child}}) and partialAccessor = "{{singular}}(" + (index - n{{prev_child}}).toString() + ")"
49
+
{{/is_repeated}}
50
+
{{^is_repeated}}
51
+
index = n{{prev_child}} and result = e.({{name}}).getImmediate{{singular}}() and partialAccessor = "{{singular}}()"
52
+
{{/is_repeated}}
53
+
{{/is_child}}
54
+
{{/properties}}
55
+
))
56
+
{{/has_children}}
23
57
{{/classes}}
24
58
}
59
+
}
25
60
26
61
/**
27
62
* Gets the "immediate" parent of `e`. "Immediate" means not taking into account node resolution: for example
28
63
* if `e` has conversions, `getImmediateParent(e)` will give the bottom conversion in the hidden AST.
29
64
*/
30
-
Element getImmediateParent(Element e) {
31
-
// `unique` is used here to tell the optimizer that there is in fact only one result
32
-
// this is tested by the `library-tests/parent/no_double_parents.ql` test
33
-
result = unique(Element x | e = getAnImmediateChild(x) | x)
65
+
Element getImmediateParent(Element e) {
66
+
// `unique` is used here to tell the optimizer that there is in fact only one result
67
+
// this is tested by the `library-tests/parent/no_double_parents.ql` test
68
+
result = unique(Element x | e = Impl::getImmediateChild(x, _, _) | x)
69
+
}
70
+
71
+
/**
72
+
* Gets the immediate child indexed at `index`. Indexes are not guaranteed to be contiguous, but are guaranteed to be distinct. `accessor` is bound the the method giving the given child.
73
+
*/
74
+
Element getImmediateChildAndAccessor(Element e, int index, string accessor) {
75
+
exists(string partialAccessor | result = Impl::getImmediateChild(e, index, partialAccessor) and accessor = "getImmediate" + partialAccessor)
76
+
}
77
+
78
+
/**
79
+
* Gets the child indexed at `index`. Indexes are not guaranteed to be contiguous, but are guaranteed to be distinct. `accessor` is bound the the method giving the given child. Node resolution is carried out.
80
+
*/
81
+
Element getChildAndAccessor(Element e, int index, string accessor) {
82
+
exists(string partialAccessor | result = Impl::getImmediateChild(e, index, partialAccessor).resolve() and accessor = "get" + partialAccessor)
0 commit comments