Codegen: implement `set` in qlgen (excluding QL tests)

This commit is contained in:
Paolo Tranquilli 2023-03-29 15:03:00 +02:00
Родитель 00b59f83f2
Коммит d5ee728657
7 изменённых файлов: 69 добавлений и 13 удалений

Просмотреть файл

@ -109,6 +109,7 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, prev_child: str =
prev_child=prev_child if prop.is_child else None,
is_optional=prop.is_optional,
is_predicate=prop.is_predicate,
is_unordered=prop.is_unordered,
description=prop.description
)
if prop.is_single:
@ -123,7 +124,7 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, prev_child: str =
singular=inflection.singularize(inflection.camelize(prop.name)),
plural=inflection.pluralize(inflection.camelize(prop.name)),
tablename=inflection.tableize(f"{cls.name}_{prop.name}"),
tableparams=["this", "index", "result"],
tableparams=["this", "index", "result"] if not prop.is_unordered else ["this", "result"],
doc=_get_doc(cls, prop, plural=False),
doc_plural=_get_doc(cls, prop, plural=True),
)

Просмотреть файл

@ -36,6 +36,7 @@ class Property:
first: bool = False
is_optional: bool = False
is_predicate: bool = False
is_unordered: bool = False
prev_child: Optional[str] = None
qltest_skip: bool = False
description: List[str] = field(default_factory=list)
@ -49,7 +50,11 @@ class Property:
@property
def getter(self):
return f"get{self.singular}" if not self.is_predicate else self.singular
if self.is_predicate:
return self.singular
if self.is_unordered:
return self.indefinite_getter
return f"get{self.singular}"
@property
def indefinite_getter(self):
@ -77,6 +82,10 @@ class Property:
def has_description(self) -> bool:
return bool(self.description)
@property
def is_indexed(self) -> bool:
return self.is_repeated and not self.is_unordered
@dataclass
class Base:

Просмотреть файл

@ -66,9 +66,9 @@ module Generated {
* This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the
* behavior of both the `Immediate` and non-`Immediate` versions.
*/
{{type}} getImmediate{{singular}}({{#is_repeated}}int index{{/is_repeated}}) {
{{type}} get{{#is_unordered}}An{{/is_unordered}}Immediate{{singular}}({{#is_indexed}}int index{{/is_indexed}}) {
{{^ipa}}
result = Synth::convert{{type}}FromRaw(Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_repeated}}index{{/is_repeated}}))
result = Synth::convert{{type}}FromRaw(Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_indexed}}index{{/is_indexed}}))
{{/ipa}}
{{#ipa}}
none()
@ -83,8 +83,8 @@ module Generated {
{{/description}}
{{/has_description}}
*/
final {{type}} {{getter}}({{#is_repeated}}int index{{/is_repeated}}) {
result = getImmediate{{singular}}({{#is_repeated}}index{{/is_repeated}}).resolve()
final {{type}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) {
result = get{{#is_unordered}}An{{/is_unordered}}Immediate{{singular}}({{#is_indexed}}index{{/is_indexed}}).resolve()
}
{{/type_is_class}}
@ -97,9 +97,9 @@ module Generated {
{{/description}}
{{/has_description}}
*/
{{type}} {{getter}}({{#is_repeated}}int index{{/is_repeated}}) {
{{type}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) {
{{^ipa}}
{{^is_predicate}}result = {{/is_predicate}}Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_repeated}}index{{/is_repeated}})
{{^is_predicate}}result = {{/is_predicate}}Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_indexed}}index{{/is_indexed}})
{{/ipa}}
{{#ipa}}
none()
@ -115,7 +115,7 @@ module Generated {
exists({{getter}}({{#is_repeated}}index{{/is_repeated}}))
}
{{/is_optional}}
{{#is_repeated}}
{{#is_indexed}}
/**
* Gets any of the {{doc_plural}}.
@ -132,7 +132,15 @@ module Generated {
result = count(int i | exists({{getter}}(i)))
}
{{/is_optional}}
{{/is_repeated}}
{{/is_indexed}}
{{#is_unordered}}
/**
* Gets the number of {{doc_plural}}.
*/
final int getNumberOf{{plural}}() {
result = count({{getter}}())
}
{{/is_unordered}}
{{/properties}}
}
}

Просмотреть файл

@ -13,7 +13,7 @@ module Raw {
{{/description}}
{{/has_description}}
*/
{{type}} {{getter}}({{#is_repeated}}int index{{/is_repeated}}) {
{{type}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) {
{{tablename}}({{#tableparams}}{{^first}}, {{/first}}{{param}}{{/tableparams}})
}
{{/properties}}

Просмотреть файл

@ -1,6 +1,11 @@
{{^is_predicate}}
{{^is_unoredered}}
Gets the {{#is_repeated}}`index`th {{/is_repeated}}{{doc}}{{#is_repeated}} (0-based){{/is_repeated}}{{#is_optional}}, if it exists{{/is_optional}}.
{{/is_unoredered}}
{{/is_predicate}}
{{#is_predicate}}
Holds if {{doc}}.
{{/is_predicate}}
{{#is_unordered}}
Gets any of the {{doc_plural}}.
{{/is_unordered}}

Просмотреть файл

@ -27,19 +27,26 @@ def test_property_is_a_class(type, expected):
assert [p.param for p in prop.tableparams] == expected_tableparams
@pytest.mark.parametrize("name,expected_getter", [
indefinite_getters = [
("Argument", "getAnArgument"),
("Element", "getAnElement"),
("Integer", "getAnInteger"),
("Operator", "getAnOperator"),
("Unit", "getAUnit"),
("Whatever", "getAWhatever"),
])
]
@pytest.mark.parametrize("name,expected_getter", indefinite_getters)
def test_property_indefinite_article(name, expected_getter):
prop = ql.Property(name, plural="X")
assert prop.indefinite_getter == expected_getter
@pytest.mark.parametrize("name,expected_getter", indefinite_getters)
def test_property_unordered_getter(name, expected_getter):
prop = ql.Property(name, plural="X", is_unordered=True)
assert prop.getter == expected_getter
@pytest.mark.parametrize("plural,expected", [
(None, False),
("", False),
@ -49,6 +56,16 @@ def test_property_is_repeated(plural, expected):
prop = ql.Property("foo", "Foo", "props", ["result"], plural=plural)
assert prop.is_repeated is expected
@pytest.mark.parametrize("plural,unordered,expected", [
(None, False, False),
("", False, False),
("X", False, True),
("X", True, False),
])
def test_property_is_indexed(plural, unordered, expected):
prop = ql.Property("foo", "Foo", "props", ["result"], plural=plural, is_unordered=unordered)
assert prop.is_indexed is expected
@pytest.mark.parametrize("is_optional,is_predicate,plural,expected", [
(False, False, None, True),

Просмотреть файл

@ -337,6 +337,22 @@ def test_repeated_property(generate_classes, is_child, prev_child):
])),
}
def test_repeated_unordered_property(generate_classes):
assert generate_classes([
schema.Class("FakeRoot"),
schema.Class("MyObject", properties=[
schema.RepeatedUnorderedProperty("foo", "bar")]),
]) == {
"FakeRoot.qll": (a_ql_stub(name="FakeRoot", base_import=gen_import_prefix + "FakeRoot"),
a_ql_class(name="FakeRoot", final=True)),
"MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"),
a_ql_class(name="MyObject", final=True, properties=[
ql.Property(singular="Foo", plural="Foos", type="bar", tablename="my_object_foos",
tableparams=["this", "result"], is_unordered=True,
doc="foo of this my object", doc_plural="foos of this my object"),
])),
}
@pytest.mark.parametrize("is_child,prev_child", [(False, None), (True, "")])
def test_repeated_optional_property(generate_classes, is_child, prev_child):