Skip to content

Commit

Permalink
Codegen: move class synth decorators to pragmas
Browse files Browse the repository at this point in the history
  • Loading branch information
Paolo Tranquilli committed Sep 20, 2024
1 parent 9d6ee09 commit db00cb6
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 35 deletions.
18 changes: 12 additions & 6 deletions misc/codegen/lib/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,6 @@ class Class:
properties: List[Property] = field(default_factory=list)
group: str = ""
pragmas: List[str] | Dict[str, object] = field(default_factory=dict)
synth: Optional[Union[SynthInfo, bool]] = None
"""^^^ filled with `True` for non-final classes with only synthesized final descendants """
doc: List[str] = field(default_factory=list)
hideable: bool = False
test_with: Optional[str] = None
Expand All @@ -114,13 +112,21 @@ def check_types(self, known: typing.Iterable[str]):
_check_type(d, known)
for p in self.properties:
_check_type(p.type, known)
if self.synth is not None:
_check_type(self.synth.from_class, known)
if self.synth.on_arguments is not None:
for t in self.synth.on_arguments.values():
if "synth" in self.pragmas:
synth = self.pragmas["synth"]
_check_type(synth.from_class, known)
if synth.on_arguments is not None:
for t in synth.on_arguments.values():
_check_type(t, known)
_check_type(self.test_with, known)

@property
def synth(self) -> SynthInfo | bool | None:
return self.pragmas.get("synth")

def mark_synth(self):
self.pragmas.setdefault("synth", True)


@dataclass
class Schema:
Expand Down
14 changes: 7 additions & 7 deletions misc/codegen/lib/schemadefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ class _Namespace:
""" simple namespacing mechanism """
name: str

def add(self, pragma: "_PragmaBase"):
def add(self, pragma: "_PragmaBase", key: str | None = None):
self.__dict__[pragma.pragma] = pragma
pragma.pragma = f"{self.name}_{pragma.pragma}"
pragma.pragma = key or f"{self.name}_{pragma.pragma}"


@_dataclass
Expand Down Expand Up @@ -142,7 +142,7 @@ class _ParametrizedClassPragma(_PragmaBase):
"""
_pragma_class: _ClassVar[type] = _ClassPragma

function: _Callable[[...], object] = None
function: _Callable[..., object] = None

def __post_init__(self):
self.__signature__ = _inspect.signature(self.function).replace(return_annotation=self._pragma_class)
Expand Down Expand Up @@ -248,10 +248,10 @@ def group(name: str = "") -> _ClassDecorator:
return _annotate(group=name)


synth.from_class = lambda ref: _annotate(synth=_schema.SynthInfo(
from_class=_schema.get_type_name(ref)))
synth.on_arguments = lambda **kwargs: _annotate(
synth=_schema.SynthInfo(on_arguments={k: _schema.get_type_name(t) for k, t in kwargs.items()}))
synth.add(_ParametrizedClassPragma("from_class", lambda ref: _schema.SynthInfo(
from_class=_schema.get_type_name(ref))), key="synth")
synth.add(_ParametrizedClassPragma("on_arguments", lambda **kwargs:
_schema.SynthInfo(on_arguments={k: _schema.get_type_name(t) for k, t in kwargs.items()})), key="synth")


class _PropertyModifierList(_schema.PropertyModifier):
Expand Down
5 changes: 2 additions & 3 deletions misc/codegen/loaders/schemaloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ def _get_class(cls: type) -> schema.Class:
test_with=_get_name(getattr(cls, "_test_with", None)),
# in the following we don't use `getattr` to avoid inheriting
pragmas=cls.__dict__.get("_pragmas", {}),
synth=cls.__dict__.get("_synth", None),
properties=[
a | _PropertyNamer(n)
for n, a in cls.__dict__.get("__annotations__", {}).items()
Expand Down Expand Up @@ -100,8 +99,8 @@ def fill_is_synth(name: str):
fill_is_synth(root)

for name, cls in classes.items():
if cls.synth is None and is_synth[name]:
cls.synth = True
if is_synth[name]:
cls.mark_synth()


def _fill_hideable_information(classes: typing.Dict[str, schema.Class]):
Expand Down
6 changes: 3 additions & 3 deletions misc/codegen/test/test_cppgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,15 +185,15 @@ def test_synth_classes_ignored(generate):
assert generate([
schema.Class(
name="W",
synth=schema.SynthInfo(),
pragmas={"synth": schema.SynthInfo()},
),
schema.Class(
name="X",
synth=schema.SynthInfo(from_class="A"),
pragmas={"synth": schema.SynthInfo(from_class="A")},
),
schema.Class(
name="Y",
synth=schema.SynthInfo(on_arguments={"a": "A", "b": "int"}),
pragmas={"synth": schema.SynthInfo(on_arguments={"a": "A", "b": "int"})},
),
schema.Class(
name="Z",
Expand Down
8 changes: 4 additions & 4 deletions misc/codegen/test/test_dbschemegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -536,9 +536,9 @@ def test_null_class(generate):

def test_synth_classes_ignored(generate):
assert generate([
schema.Class(name="A", synth=schema.SynthInfo()),
schema.Class(name="B", synth=schema.SynthInfo(from_class="A")),
schema.Class(name="C", synth=schema.SynthInfo(on_arguments={"x": "A"})),
schema.Class(name="A", pragmas={"synth": schema.SynthInfo()}),
schema.Class(name="B", pragmas={"synth": schema.SynthInfo(from_class="A")}),
schema.Class(name="C", pragmas={"synth": schema.SynthInfo(on_arguments={"x": "A"})}),
]) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
Expand All @@ -549,7 +549,7 @@ def test_synth_classes_ignored(generate):
def test_synth_derived_classes_ignored(generate):
assert generate([
schema.Class(name="A", derived={"B", "C"}),
schema.Class(name="B", bases=["A"], synth=schema.SynthInfo()),
schema.Class(name="B", bases=["A"], pragmas={"synth": schema.SynthInfo()}),
schema.Class(name="C", bases=["A"]),
]) == dbscheme.Scheme(
src=schema_file.name,
Expand Down
4 changes: 2 additions & 2 deletions misc/codegen/test/test_qlgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,7 @@ def test_property_on_class_with_default_doc_name(generate_classes):

def test_stub_on_class_with_synth_from_class(generate_classes):
assert generate_classes([
schema.Class("MyObject", synth=schema.SynthInfo(from_class="A"),
schema.Class("MyObject", pragmas={"synth": schema.SynthInfo(from_class="A")},
properties=[schema.SingleProperty("foo", "bar")]),
]) == {
"MyObject.qll": (a_ql_class_public(name="MyObject"), a_ql_stub(name="MyObject", synth_accessors=[
Expand All @@ -952,7 +952,7 @@ def test_stub_on_class_with_synth_from_class(generate_classes):

def test_stub_on_class_with_synth_on_arguments(generate_classes):
assert generate_classes([
schema.Class("MyObject", synth=schema.SynthInfo(on_arguments={"base": "A", "index": "int", "label": "string"}),
schema.Class("MyObject", pragmas={"synth": schema.SynthInfo(on_arguments={"base": "A", "index": "int", "label": "string"})},
properties=[schema.SingleProperty("foo", "bar")]),
]) == {
"MyObject.qll": (a_ql_class_public(name="MyObject"), a_ql_stub(name="MyObject", synth_accessors=[
Expand Down
20 changes: 10 additions & 10 deletions misc/codegen/test/test_schemaloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,8 @@ class B(A):
pass

assert data.classes == {
'A': schema.Class('A', derived={'B'}, synth=True),
'B': schema.Class('B', bases=['A'], synth=schema.SynthInfo(from_class="A")),
'A': schema.Class('A', derived={'B'}, pragmas={"synth": True}),
'B': schema.Class('B', bases=['A'], pragmas={"synth": schema.SynthInfo(from_class="A")}),
}


Expand All @@ -371,7 +371,7 @@ class B(A):
pass

assert data.classes == {
'A': schema.Class('A', derived={'B'}, synth=schema.SynthInfo(from_class="B")),
'A': schema.Class('A', derived={'B'}, pragmas={"synth": schema.SynthInfo(from_class="B")}),
'B': schema.Class('B', bases=['A']),
}

Expand All @@ -396,8 +396,8 @@ class B(A):
pass

assert data.classes == {
'A': schema.Class('A', derived={'B'}, synth=True),
'B': schema.Class('B', bases=['A'], synth=schema.SynthInfo(on_arguments={'a': 'A', 'i': 'int'})),
'A': schema.Class('A', derived={'B'}, pragmas={"synth": True}),
'B': schema.Class('B', bases=['A'], pragmas={"synth": schema.SynthInfo(on_arguments={'a': 'A', 'i': 'int'})}),
}


Expand All @@ -415,7 +415,7 @@ class B(A):
pass

assert data.classes == {
'A': schema.Class('A', derived={'B'}, synth=schema.SynthInfo(on_arguments={'b': 'B', 'i': 'int'})),
'A': schema.Class('A', derived={'B'}, pragmas={"synth": schema.SynthInfo(on_arguments={'b': 'B', 'i': 'int'})}),
'B': schema.Class('B', bases=['A']),
}

Expand Down Expand Up @@ -454,10 +454,10 @@ class C(Root):

assert data.classes == {
'Root': schema.Class('Root', derived={'Base', 'C'}),
'Base': schema.Class('Base', bases=['Root'], derived={'Intermediate', 'B'}, synth=True),
'Intermediate': schema.Class('Intermediate', bases=['Base'], derived={'A'}, synth=True),
'A': schema.Class('A', bases=['Intermediate'], synth=schema.SynthInfo(on_arguments={'a': 'Base', 'i': 'int'})),
'B': schema.Class('B', bases=['Base'], synth=schema.SynthInfo(from_class='Base')),
'Base': schema.Class('Base', bases=['Root'], derived={'Intermediate', 'B'}, pragmas={"synth": True}),
'Intermediate': schema.Class('Intermediate', bases=['Base'], derived={'A'}, pragmas={"synth": True}),
'A': schema.Class('A', bases=['Intermediate'], pragmas={"synth": schema.SynthInfo(on_arguments={'a': 'Base', 'i': 'int'})}),
'B': schema.Class('B', bases=['Base'], pragmas={"synth": schema.SynthInfo(from_class='Base')}),
'C': schema.Class('C', bases=['Root']),
}

Expand Down

0 comments on commit db00cb6

Please sign in to comment.