1414 corresponding to raw types)
1515Moreover in the test directory for each <Class> in <group> it will generate beneath the
1616extractor-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
313313def 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 :
0 commit comments