Skip to content

Commit 3597efb

Browse files
committed
Swift: rename to getImmediateParent and use hidden AST
1 parent a894ba6 commit 3597efb

File tree

10 files changed

+303
-248
lines changed

10 files changed

+303
-248
lines changed

swift/codegen/generators/qlgen.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ def generate(opts, renderer):
120120
renderer.render(all_imports, include_file)
121121

122122
print(include_file)
123-
renderer.render(ql.Children(classes=classes, imports=[get_import(include_file, opts.swift_dir)]),
124-
out / 'Children.qll')
123+
renderer.render(ql.GetParentImplementation(classes=classes, imports=[get_import(include_file, opts.swift_dir)]),
124+
out / 'GetImmediateParent.qll')
125125

126126
renderer.cleanup(existing)
127127
if opts.ql_format:

swift/codegen/lib/ql.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ class ImportList:
9595

9696

9797
@dataclass
98-
class Children:
99-
template: ClassVar = 'ql_children'
98+
class GetParentImplementation:
99+
template: ClassVar = 'ql_parent'
100100

101-
imports: List[str] = field(default_factory=list)
102101
classes: List[Class] = field(default_factory=list)
102+
imports: List[str] = field(default_factory=list)

swift/codegen/templates/ql_children.mustache

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// generated by {{generator}}
2+
3+
{{#imports}}
4+
import {{.}}
5+
{{/imports}}
6+
7+
// we are defining this class mainly to leverage existing generation machinery
8+
// when we generate getters in classes we use the db predicate with `this`. In order to reuse that we need a class here
9+
// as well
10+
private class ElementWithChildAccessor extends Element {
11+
// why does this look more complicated than it should?
12+
// * the none() simplifies generation, as we can append `or ...` without a special case for the first item
13+
// * the `exists` and the `x` variables are there to reuse the same generation done in classes (where the variables
14+
// are used to hide nodes via resolution)
15+
Element getAnImmediateChild() {
16+
none()
17+
{{#classes}}
18+
{{#properties}}
19+
{{#is_child}}
20+
or
21+
exists({{type}} {{local_var}}{{#is_repeated}}, int index{{/is_repeated}} | {{tablename}}({{#tableparams}}{{^first}}, {{/first}}{{param}}{{/tableparams}}) and result = {{local_var}})
22+
{{/is_child}}
23+
{{/properties}}
24+
{{/classes}}
25+
}
26+
}
27+
28+
/**
29+
* Gets any of the "immediate" children of `e`. "Immediate" means not taking into account node resolution: for example
30+
* if the AST child is the first of a series of conversions that would normally be hidden away, this will select the
31+
* next conversion down the hidden AST tree instead of the corresponding fully uncoverted node at the bottom.
32+
* This predicate is mainly intended to be used to test uniqueness of parents.
33+
*/
34+
cached
35+
Element getAnImmediateChild(Element e) {
36+
result = e.(ElementWithChildAccessor).getAnImmediateChild()
37+
}
38+
39+
/**
40+
* Gets the "immediate" parent of `e`. "Immediate" means not taking into account node resolution: for example
41+
* if `e` has conversions, `getImmediateParent(e)` will give the bottom conversion in the hidden AST.
42+
*/
43+
Element getImmediateParent(Element e) {
44+
result = unique(Element x | e = getAnImmediateChild(x) | x)
45+
}

swift/codegen/test/test_qlgen.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def run_mock():
1717
stub_path = lambda: paths.swift_dir / "ql/lib/stub/path"
1818
ql_output_path = lambda: paths.swift_dir / "ql/lib/other/path"
1919
import_file = lambda: stub_path().with_suffix(".qll")
20-
children_file = lambda: ql_output_path() / "Children.qll"
20+
children_file = lambda: ql_output_path() / "GetImmediateParent.qll"
2121
stub_import = "stub.path"
2222
stub_import_prefix = f"{stub_import}."
2323
gen_import_prefix = "other.path."
@@ -69,7 +69,7 @@ def generate_classes(opts, renderer):
6969
def test_empty(opts, input, renderer):
7070
assert generate(opts, renderer) == {
7171
import_file(): ql.ImportList(),
72-
children_file(): ql.Children(imports=[stub_import]),
72+
children_file(): ql.GetParentImplementation(imports=[stub_import]),
7373
}
7474

7575

@@ -120,7 +120,7 @@ def test_hierarchy_children(opts, input, renderer):
120120
schema.Class("B", bases={"A"}, derived={"D"}),
121121
schema.Class("A", derived={"B", "C"}),
122122
]
123-
assert generate_children_implementations(opts, renderer) == ql.Children(
123+
assert generate_children_implementations(opts, renderer) == ql.GetParentImplementation(
124124
classes=[ql.Class(name="A"),
125125
ql.Class(name="B", bases=["A"], imports=[stub_import_prefix + "A"]),
126126
ql.Class(name="C", bases=["A"], imports=[stub_import_prefix + "A"]),
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1+
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
12
private import codeql.swift.generated.AstNode
2-
private import codeql.swift.generated.Children
33

4-
class AstNode extends AstNodeBase {
5-
AstNode getParent() { result = unique(AstNode x | this = getAChild(x) | x) }
6-
}
4+
class AstNode extends AstNodeBase { }

swift/ql/lib/codeql/swift/generated/Children.qll

Lines changed: 0 additions & 212 deletions
This file was deleted.

0 commit comments

Comments
 (0)