@@ -104,8 +104,17 @@ def _get_doc(cls: schema.Class, prop: schema.Property, plural=None):
104104 return f"{ prop_name } of this { class_name } "
105105
106106
107- def get_ql_property (cls : schema .Class , prop : schema .Property , lookup : typing .Dict [str , schema .Class ],
107+ def _type_is_hideable (t : str , lookup : typing .Dict [str , schema .ClassBase ]) -> bool :
108+ if t in lookup :
109+ match lookup [t ]:
110+ case schema .Class () as cls :
111+ return "ql_hideable" in cls .pragmas
112+ return False
113+
114+
115+ def get_ql_property (cls : schema .Class , prop : schema .Property , lookup : typing .Dict [str , schema .ClassBase ],
108116 prev_child : str = "" ) -> ql .Property :
117+
109118 args = dict (
110119 type = prop .type if not prop .is_predicate else "predicate" ,
111120 qltest_skip = "qltest_skip" in prop .pragmas ,
@@ -115,7 +124,8 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dic
115124 is_unordered = prop .is_unordered ,
116125 description = prop .description ,
117126 synth = bool (cls .synth ) or prop .synth ,
118- type_is_hideable = "ql_hideable" in lookup [prop .type ].pragmas if prop .type in lookup else False ,
127+ type_is_hideable = _type_is_hideable (prop .type , lookup ),
128+ type_is_codegen_class = prop .type in lookup and not lookup [prop .type ].imported ,
119129 internal = "ql_internal" in prop .pragmas ,
120130 )
121131 ql_name = prop .pragmas .get ("ql_name" , prop .name )
@@ -154,7 +164,7 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dic
154164 return ql .Property (** args )
155165
156166
157- def get_ql_class (cls : schema .Class , lookup : typing .Dict [str , schema .Class ]) -> ql .Class :
167+ def get_ql_class (cls : schema .Class , lookup : typing .Dict [str , schema .ClassBase ]) -> ql .Class :
158168 if "ql_name" in cls .pragmas :
159169 raise Error ("ql_name is not supported yet for classes, only for properties" )
160170 prev_child = ""
@@ -391,14 +401,15 @@ def generate(opts, renderer):
391401
392402 data = schemaloader .load_file (input )
393403
394- classes = {name : get_ql_class (cls , data .classes ) for name , cls in data .classes .items ()}
404+ classes = {name : get_ql_class (cls , data .classes ) for name , cls in data .classes .items () if not cls . imported }
395405 if not classes :
396406 raise NoClasses
397407 root = next (iter (classes .values ()))
398408 if root .has_children :
399409 raise RootElementHasChildren (root )
400410
401- imports = {}
411+ pre_imports = {n : cls .module for n , cls in data .classes .items () if cls .imported }
412+ imports = dict (pre_imports )
402413 imports_impl = {}
403414 classes_used_by = {}
404415 cfg_classes = []
@@ -410,7 +421,7 @@ def generate(opts, renderer):
410421 force = opts .force ) as renderer :
411422
412423 db_classes = [cls for name , cls in classes .items () if not data .classes [name ].synth ]
413- renderer .render (ql .DbClasses (db_classes ), out / "Raw.qll" )
424+ renderer .render (ql .DbClasses (classes = db_classes , imports = sorted ( set ( pre_imports . values ())) ), out / "Raw.qll" )
414425
415426 classes_by_dir_and_name = sorted (classes .values (), key = lambda cls : (cls .dir , cls .name ))
416427 for c in classes_by_dir_and_name :
@@ -439,6 +450,8 @@ def generate(opts, renderer):
439450 renderer .render (cfg_classes_val , cfg_qll )
440451
441452 for c in data .classes .values ():
453+ if c .imported :
454+ continue
442455 path = _get_path (c )
443456 path_impl = _get_path_impl (c )
444457 stub_file = stub_out / path_impl
@@ -457,20 +470,23 @@ def generate(opts, renderer):
457470 renderer .render (class_public , class_public_file )
458471
459472 # for example path/to/elements -> path/to/elements.qll
460- renderer .render (ql .ImportList ([i for name , i in imports .items () if not classes [name ].internal ]),
473+ renderer .render (ql .ImportList ([i for name , i in imports .items () if name not in classes or not classes [name ].internal ]),
461474 include_file )
462475
463476 elements_module = get_import (include_file , opts .root_dir )
464477
465478 renderer .render (
466479 ql .GetParentImplementation (
467480 classes = list (classes .values ()),
468- imports = [elements_module ] + [i for name , i in imports .items () if classes [name ].internal ],
481+ imports = [elements_module ] + [i for name ,
482+ i in imports .items () if name in classes and classes [name ].internal ],
469483 ),
470484 out / 'ParentChild.qll' )
471485
472486 if test_out :
473487 for c in data .classes .values ():
488+ if c .imported :
489+ continue
474490 if should_skip_qltest (c , data .classes ):
475491 continue
476492 test_with_name = c .pragmas .get ("qltest_test_with" )
@@ -500,7 +516,8 @@ def generate(opts, renderer):
500516 constructor_imports = []
501517 synth_constructor_imports = []
502518 stubs = {}
503- for cls in sorted (data .classes .values (), key = lambda cls : (cls .group , cls .name )):
519+ for cls in sorted ((cls for cls in data .classes .values () if not cls .imported ),
520+ key = lambda cls : (cls .group , cls .name )):
504521 synth_type = get_ql_synth_class (cls )
505522 if synth_type .is_final :
506523 final_synth_types .append (synth_type )
0 commit comments