Codegen/Rust: allow renaming in QL

This adds a `ql.name` codegen pragma to change the name of a property on
the QL side. This is useful to give more meaningful names than what we
get from the generated rust AST.
This commit is contained in:
Paolo Tranquilli
2024-11-25 17:01:21 +01:00
parent 8fd581dd7e
commit 261e0a1a53
14 changed files with 61 additions and 56 deletions

View File

@@ -118,17 +118,18 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dic
type_is_hideable="ql_hideable" in lookup[prop.type].pragmas if prop.type in lookup else False,
internal="ql_internal" in prop.pragmas,
)
ql_name = prop.pragmas.get("ql_name", prop.name)
if prop.is_single:
args.update(
singular=inflection.camelize(prop.name),
singular=inflection.camelize(ql_name),
tablename=inflection.tableize(cls.name),
tableparams=["this"] + ["result" if p is prop else "_" for p in cls.properties if p.is_single],
doc=_get_doc(cls, prop),
)
elif prop.is_repeated:
args.update(
singular=inflection.singularize(inflection.camelize(prop.name)),
plural=inflection.pluralize(inflection.camelize(prop.name)),
singular=inflection.singularize(inflection.camelize(ql_name)),
plural=inflection.pluralize(inflection.camelize(ql_name)),
tablename=inflection.tableize(f"{cls.name}_{prop.name}"),
tableparams=["this", "index", "result"] if not prop.is_unordered else ["this", "result"],
doc=_get_doc(cls, prop, plural=False),
@@ -136,14 +137,14 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dic
)
elif prop.is_optional:
args.update(
singular=inflection.camelize(prop.name),
singular=inflection.camelize(ql_name),
tablename=inflection.tableize(f"{cls.name}_{prop.name}"),
tableparams=["this", "result"],
doc=_get_doc(cls, prop),
)
elif prop.is_predicate:
args.update(
singular=inflection.camelize(prop.name, uppercase_first_letter=False),
singular=inflection.camelize(ql_name, uppercase_first_letter=False),
tablename=inflection.underscore(f"{cls.name}_{prop.name}"),
tableparams=["this"],
doc=_get_doc(cls, prop),
@@ -154,6 +155,8 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dic
def get_ql_class(cls: schema.Class, lookup: typing.Dict[str, schema.Class]) -> ql.Class:
if "ql_name" in cls.pragmas:
raise Error("ql_name is not supported yet for classes, only for properties")
prev_child = ""
properties = []
for p in cls.properties:

View File

@@ -72,11 +72,11 @@ def include(source: str):
@_dataclass
class _Namespace:
""" simple namespacing mechanism """
name: str
_name: str
def add(self, pragma: "_PragmaBase", key: str | None = None):
self.__dict__[pragma.pragma] = pragma
pragma.pragma = key or f"{self.name}_{pragma.pragma}"
pragma.pragma = key or f"{self._name}_{pragma.pragma}"
@_dataclass
@@ -87,7 +87,7 @@ class _SynthModifier(_schema.PropertyModifier, _Namespace):
prop.synth = self.synth
def negate(self) -> _schema.PropertyModifier:
return _SynthModifier(self.name, False)
return _SynthModifier(self._name, False)
qltest = _Namespace("qltest")
@@ -239,6 +239,7 @@ qltest.add(_ParametrizedClassPragma("test_with", inherited=True, factory=_schema
ql.add(_ParametrizedClassPragma("default_doc_name", factory=lambda doc: doc))
ql.add(_ClassPragma("hideable", inherited=True))
ql.add(_Pragma("internal"))
ql.add(_ParametrizedPragma("name", factory=lambda name: name))
cpp.add(_Pragma("skip"))
@@ -256,30 +257,24 @@ synth.add(_ParametrizedClassPragma("on_arguments", factory=lambda **kwargs:
_schema.SynthInfo(on_arguments={k: _schema.get_type_name(t) for k, t in kwargs.items()})), key="synth")
@_dataclass(frozen=True)
class _PropertyModifierList(_schema.PropertyModifier):
def __init__(self):
self._mods = []
_mods: tuple[_schema.PropertyModifier, ...]
def __or__(self, other: _schema.PropertyModifier):
self._mods.append(other)
return self
return _PropertyModifierList(self._mods + (other,))
def modify(self, prop: Property):
for m in self._mods:
m.modify(prop)
class _PropertyAnnotation:
def __or__(self, other: _schema.PropertyModifier):
return _PropertyModifierList() | other
_ = _PropertyAnnotation()
_ = _PropertyModifierList(())
drop = object()
def annotate(annotated_cls: type, add_bases: _Iterable[type] | None = None, replace_bases: _Dict[type, type] | None = None, cfg: bool = False) -> _Callable[[type], _PropertyAnnotation]:
def annotate(annotated_cls: type, add_bases: _Iterable[type] | None = None, replace_bases: _Dict[type, type] | None = None, cfg: bool = False) -> _Callable[[type], _PropertyModifierList]:
"""
Add or modify schema annotations after a class has been defined previously.
@@ -287,7 +282,7 @@ def annotate(annotated_cls: type, add_bases: _Iterable[type] | None = None, repl
`replace_bases` can be used to replace bases on the annotated class.
"""
def decorator(cls: type) -> _PropertyAnnotation:
def decorator(cls: type) -> _PropertyModifierList:
if cls.__name__ != "_":
raise _schema.Error("Annotation classes must be named _")
if cls.__doc__ is not None:
@@ -307,7 +302,7 @@ def annotate(annotated_cls: type, add_bases: _Iterable[type] | None = None, repl
del annotated_cls.__annotations__[p]
elif p in annotated_cls.__annotations__:
annotated_cls.__annotations__[p] |= a
elif isinstance(a, (_PropertyAnnotation, _PropertyModifierList)):
elif isinstance(a, (_PropertyModifierList, _PropertyModifierList)):
raise _schema.Error(f"annotated property {p} not present in annotated class "
f"{annotated_cls.__name__}")
else: