Skip to content

Commit feb4e60

Browse files
committed
Swift: make all ql generation language agnostic
1 parent aca18f5 commit feb4e60

File tree

135 files changed

+533
-498
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

135 files changed

+533
-498
lines changed

swift/codegen/generators/qlgen.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
corresponding to raw types)
1515
Moreover in the test directory for each <Class> in <group> it will generate beneath the
1616
extractor-tests/generated/<group>/<Class> directory either
17-
* a `MISSING_SOURCE.txt` explanation file if no `swift` source is present, or
17+
* a `MISSING_SOURCE.txt` explanation file if no source is present, or
1818
* one `<Class>.ql` test query for all single properties and on `<Class>_<property>.ql` test query for each optional or
1919
repeated property
2020
"""
@@ -287,7 +287,7 @@ def _should_skip_qltest(cls: schema.Class, lookup: typing.Dict[str, schema.Class
287287
cls, lookup)
288288

289289

290-
def _get_stub(cls: schema.Class, base_import: str) -> ql.Stub:
290+
def _get_stub(cls: schema.Class, base_import: str, generated_import_prefix: str) -> ql.Stub:
291291
if isinstance(cls.ipa, schema.IpaInfo):
292292
if cls.ipa.from_class is not None:
293293
accessors = [
@@ -307,7 +307,7 @@ def _get_stub(cls: schema.Class, base_import: str) -> ql.Stub:
307307
]
308308
else:
309309
accessors = []
310-
return ql.Stub(name=cls.name, base_import=base_import, ipa_accessors=accessors)
310+
return ql.Stub(name=cls.name, base_import=base_import, import_prefix=generated_import_prefix, ipa_accessors=accessors)
311311

312312

313313
def generate(opts, renderer):
@@ -335,6 +335,7 @@ def generate(opts, renderer):
335335
raise RootElementHasChildren(root)
336336

337337
imports = {}
338+
generated_import_prefix = get_import(out, opts.root_dir)
338339

339340
with renderer.manage(generated=generated, stubs=stubs, registry=opts.generated_registry,
340341
force=opts.force) as renderer:
@@ -349,23 +350,26 @@ def generate(opts, renderer):
349350
for c in classes.values():
350351
qll = out / c.path.with_suffix(".qll")
351352
c.imports = [imports[t] for t in get_classes_used_by(c)]
353+
c.import_prefix = generated_import_prefix
352354
renderer.render(c, qll)
353355

354356
for c in data.classes.values():
355357
path = _get_path(c)
356358
stub_file = stub_out / path
357359
if not renderer.is_customized_stub(stub_file):
358360
base_import = get_import(out / path, opts.root_dir)
359-
renderer.render(_get_stub(c, base_import), stub_file)
361+
renderer.render(_get_stub(c, base_import, generated_import_prefix), stub_file)
360362

361363
# for example path/to/elements -> path/to/elements.qll
362364
renderer.render(ql.ImportList([i for name, i in imports.items() if not classes[name].ql_internal]),
363365
include_file)
364366

367+
elements_module = get_import(include_file, opts.root_dir)
368+
365369
renderer.render(
366370
ql.GetParentImplementation(
367371
classes=list(classes.values()),
368-
additional_imports=[i for name, i in imports.items() if classes[name].ql_internal],
372+
imports=[elements_module] + [i for name, i in imports.items() if classes[name].ql_internal],
369373
),
370374
out / 'ParentChild.qll')
371375

@@ -374,7 +378,7 @@ def generate(opts, renderer):
374378
continue
375379
test_dir = test_out / c.group / c.name
376380
test_dir.mkdir(parents=True, exist_ok=True)
377-
if not any(test_dir.glob("*.swift")):
381+
if all(f.suffix in (".txt", ".ql", ".actual", ".expected") for f in test_dir.glob("*.*")):
378382
log.warning(f"no test source in {test_dir.relative_to(test_out)}")
379383
renderer.render(ql.MissingTestInstructions(),
380384
test_dir / missing_test_source_filename)
@@ -383,11 +387,13 @@ def generate(opts, renderer):
383387
lambda p: p.is_total)
384388
renderer.render(ql.ClassTester(class_name=c.name,
385389
properties=total_props,
390+
elements_module=elements_module,
386391
# in case of collapsed hierarchies we want to see the actual QL class in results
387392
show_ql_class="qltest_collapse_hierarchy" in c.pragmas),
388393
test_dir / f"{c.name}.ql")
389394
for p in partial_props:
390395
renderer.render(ql.PropertyTester(class_name=c.name,
396+
elements_module=elements_module,
391397
property=p), test_dir / f"{c.name}_{p.getter}.ql")
392398

393399
final_ipa_types = []
@@ -403,7 +409,7 @@ def generate(opts, renderer):
403409
stub_file = stub_out / cls.group / f"{cls.name}Constructor.qll"
404410
if not renderer.is_customized_stub(stub_file):
405411
# stub rendering must be postponed as we might not have yet all subtracted ipa types in `ipa_type`
406-
stubs[stub_file] = ql.Synth.ConstructorStub(ipa_type)
412+
stubs[stub_file] = ql.Synth.ConstructorStub(ipa_type, import_prefix=generated_import_prefix)
407413
constructor_import = get_import(stub_file, opts.root_dir)
408414
constructor_imports.append(constructor_import)
409415
if ipa_type.is_ipa:
@@ -413,7 +419,8 @@ def generate(opts, renderer):
413419

414420
for stub_file, data in stubs.items():
415421
renderer.render(data, stub_file)
416-
renderer.render(ql.Synth.Types(root.name, final_ipa_types, non_final_ipa_types), out / "Synth.qll")
422+
renderer.render(ql.Synth.Types(root.name, generated_import_prefix,
423+
final_ipa_types, non_final_ipa_types), out / "Synth.qll")
417424
renderer.render(ql.ImportList(constructor_imports), out / "SynthConstructors.qll")
418425
renderer.render(ql.ImportList(ipa_constructor_imports), out / "PureSynthConstructors.qll")
419426
if opts.ql_format:

swift/codegen/lib/ql.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ class Class:
9797
properties: List[Property] = field(default_factory=list)
9898
dir: pathlib.Path = pathlib.Path()
9999
imports: List[str] = field(default_factory=list)
100+
import_prefix: Optional[str] = None
100101
qltest_skip: bool = False
101102
qltest_collapse_hierarchy: bool = False
102103
qltest_uncollapse_hierarchy: bool = False
@@ -152,6 +153,7 @@ class Stub:
152153

153154
name: str
154155
base_import: str
156+
import_prefix: str
155157
ipa_accessors: List[IpaUnderlyingAccessor] = field(default_factory=list)
156158

157159
@property
@@ -178,7 +180,7 @@ class GetParentImplementation:
178180
template: ClassVar = 'ql_parent'
179181

180182
classes: List[Class] = field(default_factory=list)
181-
additional_imports: List[str] = field(default_factory=list)
183+
imports: List[str] = field(default_factory=list)
182184

183185

184186
@dataclass
@@ -190,19 +192,23 @@ class PropertyForTest:
190192

191193

192194
@dataclass
193-
class ClassTester:
195+
class TesterBase:
196+
class_name: str
197+
elements_module: str
198+
199+
200+
@dataclass
201+
class ClassTester(TesterBase):
194202
template: ClassVar = 'ql_test_class'
195203

196-
class_name: str
197204
properties: List[PropertyForTest] = field(default_factory=list)
198205
show_ql_class: bool = False
199206

200207

201208
@dataclass
202-
class PropertyTester:
209+
class PropertyTester(TesterBase):
203210
template: ClassVar = 'ql_test_property'
204211

205-
class_name: str
206212
property: PropertyForTest
207213

208214

@@ -290,6 +296,7 @@ class Types:
290296
template: ClassVar = "ql_ipa_types"
291297

292298
root: str
299+
import_prefix: str
293300
final_classes: List["Synth.FinalClass"] = field(default_factory=list)
294301
non_final_classes: List["Synth.NonFinalClass"] = field(default_factory=list)
295302

@@ -302,3 +309,4 @@ class ConstructorStub:
302309
template: ClassVar = "ql_ipa_constructor_stub"
303310

304311
cls: "Synth.FinalClass"
312+
import_prefix: str

swift/codegen/templates/ql_class.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// generated by {{generator}}
2-
private import codeql.swift.generated.Synth
3-
private import codeql.swift.generated.Raw
2+
private import {{import_prefix}}.Synth
3+
private import {{import_prefix}}.Raw
44
{{#imports}}
55
import {{.}}
66
{{/imports}}

swift/codegen/templates/ql_ipa_constructor_stub.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// generated by {{generator}}, remove this comment if you wish to edit this file
2-
private import codeql.swift.generated.Raw
2+
private import {{import_prefix}}.Raw
33
{{#cls}}
44
{{#is_db}}
55
{{#has_subtracted_ipa_types}}
6-
private import codeql.swift.generated.PureSynthConstructors
6+
private import {{import_prefix}}.PureSynthConstructors
77
{{/has_subtracted_ipa_types}}
88
{{/is_db}}
99

swift/codegen/templates/ql_ipa_types.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
private import codeql.swift.generated.SynthConstructors
2-
private import codeql.swift.generated.Raw
1+
private import {{import_prefix}}.SynthConstructors
2+
private import {{import_prefix}}.Raw
33

44
cached module Synth {
55
cached newtype T{{root}} =

swift/codegen/templates/ql_parent.mustache

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
// generated by {{generator}}
22

3-
import codeql.swift.elements
4-
{{#additional_imports}}
3+
{{#imports}}
54
import {{.}}
6-
{{/additional_imports}}
5+
{{/imports}}
76

87
private module Impl {
98
{{#classes}}

swift/codegen/templates/ql_stub.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// generated by {{generator}}, remove this comment if you wish to edit this file
22
private import {{base_import}}
33
{{#has_ipa_accessors}}
4-
private import codeql.swift.generated.Raw
5-
private import codeql.swift.generated.Synth
4+
private import {{import_prefix}}.Raw
5+
private import {{import_prefix}}.Synth
66
{{/has_ipa_accessors}}
77

88
{{#ql_internal}}

swift/codegen/templates/ql_test_class.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// generated by {{generator}}
22

3-
import codeql.swift.elements
3+
import {{elements_module}}
44
import TestUtils
55

66
from {{class_name}} x{{#properties}}, {{#type}}{{.}}{{/type}}{{^type}}string{{/type}} {{getter}}{{/properties}}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
// generated by {{generator}}
22

3-
After a swift source file is added in this directory and {{generator}} is run again, test queries
3+
After a source file is added in this directory and {{generator}} is run again, test queries
44
will appear and this file will be deleted

swift/codegen/templates/ql_test_property.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// generated by {{generator}}
22

3-
import codeql.swift.elements
3+
import {{elements_module}}
44
import TestUtils
55

66
{{#property}}

0 commit comments

Comments
 (0)