From d2ebe00492bb9f8ad69f79e0cbe05833eecc87cf Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 20 Sep 2024 12:36:56 +0200 Subject: [PATCH] Codegen: move group to parametrized pragmas --- misc/codegen/lib/schema.py | 5 ++++- misc/codegen/lib/schemadefs.py | 4 +--- misc/codegen/loaders/schemaloader.py | 5 ++--- misc/codegen/test/test_cppgen.py | 8 ++++---- misc/codegen/test/test_dbschemegen.py | 22 +++++++++++----------- misc/codegen/test/test_qlgen.py | 6 +++--- misc/codegen/test/test_schemaloader.py | 6 +++--- 7 files changed, 28 insertions(+), 28 deletions(-) diff --git a/misc/codegen/lib/schema.py b/misc/codegen/lib/schema.py index 8a3bf4511fb..21a4cdcfc06 100644 --- a/misc/codegen/lib/schema.py +++ b/misc/codegen/lib/schema.py @@ -91,7 +91,6 @@ class Class: bases: List[str] = field(default_factory=list) derived: Set[str] = field(default_factory=set) properties: List[Property] = field(default_factory=list) - group: str = "" pragmas: List[str] | Dict[str, object] = field(default_factory=dict) doc: List[str] = field(default_factory=list) @@ -125,6 +124,10 @@ class Class: def mark_synth(self): self.pragmas.setdefault("synth", True) + @property + def group(self) -> str: + return typing.cast(str, self.pragmas.get("group", "")) + @dataclass class Schema: diff --git a/misc/codegen/lib/schemadefs.py b/misc/codegen/lib/schemadefs.py index 241a22031a9..9edb8e759e2 100644 --- a/misc/codegen/lib/schemadefs.py +++ b/misc/codegen/lib/schemadefs.py @@ -250,9 +250,7 @@ rust.add(_Pragma("skip_doc_test")) rust.add(_ParametrizedClassPragma("doc_test_signature", factory=lambda signature: signature)) - -def group(name: str = "") -> _ClassDecorator: - return _annotate(group=name) +group = _ParametrizedClassPragma("group", inherited=True, factory=lambda group: group) synth.add(_ParametrizedClassPragma("from_class", factory=lambda ref: _schema.SynthInfo( diff --git a/misc/codegen/loaders/schemaloader.py b/misc/codegen/loaders/schemaloader.py index 12cd903032e..5b224203783 100644 --- a/misc/codegen/loaders/schemaloader.py +++ b/misc/codegen/loaders/schemaloader.py @@ -37,7 +37,8 @@ def _get_class(cls: type) -> schema.Class: if cls.__name__ != to_underscore_and_back: raise schema.Error(f"Class name must be upper camel-case, without capitalized acronyms, found {cls.__name__} " f"instead of {to_underscore_and_back}") - if len({b._group for b in cls.__bases__ if hasattr(b, "_group")}) > 1: + if len({g for g in (getattr(b, f"{schema.inheritable_pragma_prefix}group", None) + for b in cls.__bases__) if g}) > 1: raise schema.Error(f"Bases with mixed groups for {cls.__name__}") if any(getattr(b, "_null", False) for b in cls.__bases__): raise schema.Error(f"Null class cannot be derived") @@ -50,8 +51,6 @@ def _get_class(cls: type) -> schema.Class: return schema.Class(name=cls.__name__, bases=[b.__name__ for b in cls.__bases__ if b is not object], derived={d.__name__ for d in cls.__subclasses__()}, - # getattr to inherit from bases - group=getattr(cls, "_group", ""), pragmas=pragmas, # in the following we don't use `getattr` to avoid inheriting properties=[ diff --git a/misc/codegen/test/test_cppgen.py b/misc/codegen/test/test_cppgen.py index c8e05fa1d12..fea9be2037f 100644 --- a/misc/codegen/test/test_cppgen.py +++ b/misc/codegen/test/test_cppgen.py @@ -156,10 +156,10 @@ def test_classes_with_dirs(generate_grouped): cbase = cpp.Class(name="CBase") assert generate_grouped([ schema.Class(name="A"), - schema.Class(name="B", group="foo"), - schema.Class(name="CBase", derived={"C"}, group="bar"), - schema.Class(name="C", bases=["CBase"], group="bar"), - schema.Class(name="D", group="foo/bar/baz"), + schema.Class(name="B", pragmas={"group": "foo"}), + schema.Class(name="CBase", derived={"C"}, pragmas={"group": "bar"}), + schema.Class(name="C", bases=["CBase"], pragmas={"group": "bar"}), + schema.Class(name="D", pragmas={"group": "foo/bar/baz"}), ]) == { ".": [cpp.Class(name="A", trap_name="As", final=True)], "foo": [cpp.Class(name="B", trap_name="Bs", final=True)], diff --git a/misc/codegen/test/test_dbschemegen.py b/misc/codegen/test/test_dbschemegen.py index 50ad70ed2b8..96a6b0d0f7f 100644 --- a/misc/codegen/test/test_dbschemegen.py +++ b/misc/codegen/test/test_dbschemegen.py @@ -56,7 +56,7 @@ def test_includes(input, opts, generate): def test_empty_final_class(generate, dir_param): assert generate([ - schema.Class("Object", group=dir_param.input), + schema.Class("Object", pragmas={"group": dir_param.input}), ]) == dbscheme.Scheme( src=schema_file.name, includes=[], @@ -74,7 +74,7 @@ def test_empty_final_class(generate, dir_param): def test_final_class_with_single_scalar_field(generate, dir_param): assert generate([ - schema.Class("Object", group=dir_param.input, properties=[ + schema.Class("Object", pragmas={"group": dir_param.input}, properties=[ schema.SingleProperty("foo", "bar"), ]), ]) == dbscheme.Scheme( @@ -94,7 +94,7 @@ def test_final_class_with_single_scalar_field(generate, dir_param): def test_final_class_with_single_class_field(generate, dir_param): assert generate([ - schema.Class("Object", group=dir_param.input, properties=[ + schema.Class("Object", pragmas={"group": dir_param.input}, properties=[ schema.SingleProperty("foo", "Bar"), ]), ]) == dbscheme.Scheme( @@ -114,7 +114,7 @@ def test_final_class_with_single_class_field(generate, dir_param): def test_final_class_with_optional_field(generate, dir_param): assert generate([ - schema.Class("Object", group=dir_param.input, properties=[ + schema.Class("Object", pragmas={"group": dir_param.input}, properties=[ schema.OptionalProperty("foo", "bar"), ]), ]) == dbscheme.Scheme( @@ -142,7 +142,7 @@ def test_final_class_with_optional_field(generate, dir_param): @pytest.mark.parametrize("property_cls", [schema.RepeatedProperty, schema.RepeatedOptionalProperty]) def test_final_class_with_repeated_field(generate, property_cls, dir_param): assert generate([ - schema.Class("Object", group=dir_param.input, properties=[ + schema.Class("Object", pragmas={"group": dir_param.input}, properties=[ property_cls("foo", "bar"), ]), ]) == dbscheme.Scheme( @@ -170,7 +170,7 @@ def test_final_class_with_repeated_field(generate, property_cls, dir_param): def test_final_class_with_repeated_unordered_field(generate, dir_param): assert generate([ - schema.Class("Object", group=dir_param.input, properties=[ + schema.Class("Object", pragmas={"group": dir_param.input}, properties=[ schema.RepeatedUnorderedProperty("foo", "bar"), ]), ]) == dbscheme.Scheme( @@ -196,7 +196,7 @@ def test_final_class_with_repeated_unordered_field(generate, dir_param): def test_final_class_with_predicate_field(generate, dir_param): assert generate([ - schema.Class("Object", group=dir_param.input, properties=[ + schema.Class("Object", pragmas={"group": dir_param.input}, properties=[ schema.PredicateProperty("foo"), ]), ]) == dbscheme.Scheme( @@ -222,7 +222,7 @@ def test_final_class_with_predicate_field(generate, dir_param): def test_final_class_with_more_fields(generate, dir_param): assert generate([ - schema.Class("Object", group=dir_param.input, properties=[ + schema.Class("Object", pragmas={"group": dir_param.input}, properties=[ schema.SingleProperty("one", "x"), schema.SingleProperty("two", "y"), schema.OptionalProperty("three", "z"), @@ -309,7 +309,7 @@ def test_class_with_derived_and_single_property(generate, dir_param): schema.Class( name="Base", derived={"Left", "Right"}, - group=dir_param.input, + pragmas={"group": dir_param.input}, properties=[ schema.SingleProperty("single", "Prop"), ]), @@ -349,7 +349,7 @@ def test_class_with_derived_and_optional_property(generate, dir_param): schema.Class( name="Base", derived={"Left", "Right"}, - group=dir_param.input, + pragmas={"group": dir_param.input}, properties=[ schema.OptionalProperty("opt", "Prop"), ]), @@ -388,7 +388,7 @@ def test_class_with_derived_and_repeated_property(generate, dir_param): assert generate([ schema.Class( name="Base", - group=dir_param.input, + pragmas={"group": dir_param.input}, derived={"Left", "Right"}, properties=[ schema.RepeatedProperty("rep", "Prop"), diff --git a/misc/codegen/test/test_qlgen.py b/misc/codegen/test/test_qlgen.py index d955f51b137..684d3d6a1a1 100644 --- a/misc/codegen/test/test_qlgen.py +++ b/misc/codegen/test/test_qlgen.py @@ -467,7 +467,7 @@ def test_class_with_doc(generate_classes): def test_class_dir(generate_classes): dir = "another/rel/path" assert generate_classes([ - schema.Class("A", derived={"B"}, group=dir), + schema.Class("A", derived={"B"}, pragmas={"group": dir}), schema.Class("B", bases=["A"]), ]) == { f"{dir}/A.qll": ( @@ -489,7 +489,7 @@ def test_root_element_cannot_have_children(generate_classes): def test_class_dir_imports(generate_import_list): dir = "another/rel/path" assert generate_import_list([ - schema.Class("A", derived={"B"}, group=dir), + schema.Class("A", derived={"B"}, pragmas={"group": dir}), schema.Class("B", bases=["A"]), ]) == ql.ImportList([ stub_import_prefix + "B", @@ -583,7 +583,7 @@ def test_test_source_present(opts, generate_tests): def test_test_source_present_with_dir(opts, generate_tests): write(opts.ql_test_output / "foo" / "A" / "test.swift") assert generate_tests([ - schema.Class("A", group="foo"), + schema.Class("A", pragmas={"group": "foo"}), ]) == { "foo/A/A.ql": a_ql_class_tester(class_name="A"), } diff --git a/misc/codegen/test/test_schemaloader.py b/misc/codegen/test/test_schemaloader.py index 994fadacf0b..4d1aa06ecd0 100644 --- a/misc/codegen/test/test_schemaloader.py +++ b/misc/codegen/test/test_schemaloader.py @@ -101,7 +101,7 @@ def test_group(): pass assert data.classes == { - 'A': schema.Class('A', group="xxx"), + 'A': schema.Class('A', pragmas={"group": "xxx"}), } @@ -124,8 +124,8 @@ def test_group_is_inherited(): assert data.classes == { 'A': schema.Class('A', derived={'B', 'C'}), 'B': schema.Class('B', bases=['A'], derived={'D'}), - 'C': schema.Class('C', bases=['A'], derived={'D'}, group='xxx'), - 'D': schema.Class('D', bases=['B', 'C'], group='xxx'), + 'C': schema.Class('C', bases=['A'], derived={'D'}, pragmas={"group": "xxx"}), + 'D': schema.Class('D', bases=['B', 'C'], pragmas={"group": "xxx"}), }