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
Codegen: improve implementation of generated parent/child relationship
This improves the implementation of the generated parent/child
relationship by adding a new `all_children` field to `ql.Class` which
lists all children (both direct and inherited) of a class, carefully
avoiding duplicating children in case of diamond inheritance. This:
* simplifies the generated code,
* avoid children ambiguities in case of diamond inheritance.
This only comes with some changes in the order of children in the
generated tests (we were previously sorting bases alphabetically there).
For the rest this should be a non-functional change.
Copy file name to clipboardExpand all lines: misc/codegen/templates/ql_parent.mustache
+33-45Lines changed: 33 additions & 45 deletions
Original file line number
Diff line number
Diff line change
@@ -9,51 +9,39 @@ import {{.}}
9
9
10
10
private module Impl {
11
11
{{#classes}}
12
-
private Element getImmediateChildOf{{name}}({{name}} e, int index, string partialPredicateCall) {
13
-
{{! avoid unused argument warnings on root element, assuming the root element has no children }}
14
-
{{#root}}none(){{/root}}
15
-
{{^root}}
16
-
{{! b is the base offset 0, for ease of generation }}
17
-
{{! b<base> is constructed to be strictly greater than the indexes required for children coming from <base>}}
18
-
{{! n is the base offset for direct children, equal to the last base offset from above }}
19
-
{{! n<child> is constructed to be strictly greater than the indexes for <child> children }}
20
-
exists(int b{{#bases}}, int b{{.}}{{/bases}}, int n{{#properties}}{{#is_child}}, int n{{singular}}{{/is_child}}{{/properties}} |
21
-
b = 0
22
-
{{#bases}}
23
-
and
24
-
b{{.}} = b{{prev}} + 1 + max(int i | i = -1 or exists(getImmediateChildOf{{.}}(e, i, _)) | i)
25
-
{{/bases}}
26
-
and
27
-
n = b{{last_base}}
28
-
{{#properties}}
29
-
{{#is_child}}
30
-
{{! n<child> is defined on top of the previous definition }}
31
-
{{! for single and optional properties it adds 1 (regardless of whether the optional property exists) }}
32
-
{{! for repeated it adds 1 + the maximum index (which works for repeated optional as well) }}
33
-
and
34
-
n{{singular}} = n{{prev_child}} + 1{{#is_repeated}}+ max(int i | i = -1 or exists(e.get{{#type_is_hideable}}Immediate{{/type_is_hideable}}{{singular}}(i)) | i){{/is_repeated}}
35
-
{{/is_child}}
36
-
{{/properties}} and (
37
-
none()
38
-
{{#bases}}
39
-
or
40
-
result = getImmediateChildOf{{.}}(e, index - b{{prev}}, partialPredicateCall)
41
-
{{/bases}}
42
-
{{#properties}}
43
-
{{#is_child}}
44
-
or
45
-
{{#is_repeated}}
46
-
result = e.get{{#type_is_hideable}}Immediate{{/type_is_hideable}}{{singular}}(index - n{{prev_child}}) and partialPredicateCall = "{{singular}}(" + (index - n{{prev_child}}).toString() + ")"
47
-
{{/is_repeated}}
48
-
{{^is_repeated}}
49
-
index = n{{prev_child}} and result = e.get{{#type_is_hideable}}Immediate{{/type_is_hideable}}{{singular}}() and partialPredicateCall = "{{singular}}()"
50
-
{{/is_repeated}}
51
-
{{/is_child}}
52
-
{{/properties}}
53
-
))
54
-
{{/root}}
55
-
}
56
-
12
+
{{#final}}
13
+
private Element getImmediateChildOf{{name}}({{name}} e, int index, string partialPredicateCall) {
14
+
{{^has_children}}none(){{/has_children}}
15
+
{{#has_children}}
16
+
{{! n is the base offset 0, for ease of generation }}
17
+
{{! n<child> is constructed to be strictly greater than the indexes for <child> children }}
18
+
exists(int n{{#all_children}}, int n{{property.singular}}{{/all_children}} |
19
+
n = 0
20
+
{{#all_children}}
21
+
{{#property}}
22
+
{{! n<child> is defined on top of the previous definition }}
23
+
{{! for single and optional properties it adds 1 (regardless of whether the optional property exists) }}
24
+
{{! for repeated it adds 1 + the maximum index (which works for repeated optional as well) }}
25
+
and
26
+
n{{singular}} = n{{prev}} + 1{{#is_repeated}}+ max(int i | i = -1 or exists(e.get{{#type_is_hideable}}Immediate{{/type_is_hideable}}{{singular}}(i)) | i){{/is_repeated}}
27
+
{{/property}}
28
+
{{/all_children}} and (
29
+
none()
30
+
{{#all_children}}
31
+
{{#property}}
32
+
or
33
+
{{#is_repeated}}
34
+
result = e.get{{#type_is_hideable}}Immediate{{/type_is_hideable}}{{singular}}(index - n{{prev}}) and partialPredicateCall = "{{singular}}(" + (index - n{{prev}}).toString() + ")"
35
+
{{/is_repeated}}
36
+
{{^is_repeated}}
37
+
index = n{{prev}} and result = e.get{{#type_is_hideable}}Immediate{{/type_is_hideable}}{{singular}}() and partialPredicateCall = "{{singular}}()"
38
+
{{/is_repeated}}
39
+
{{/property}}
40
+
{{/all_children}}
41
+
))
42
+
{{/has_children}}
43
+
}
44
+
{{/final}}
57
45
{{/classes}}
58
46
cached
59
47
Element getImmediateChild(Element e, int index, string partialAccessor) {
0 commit comments