Swift: allow skipping fields in cppgen

Some fields of base classes pose some problems with diamond hierarchies,
and we don't use them any way as we are emitting them using directly
trap entries instead of structured C++ classes.

This introduces a `cpp_skip` pragma to skip generation of those fields
in structured generated C++ classes, and applies it to `is_unknown` and
`location`.
This commit is contained in:
Paolo Tranquilli
2022-07-11 15:59:21 +02:00
parent 93a4a32527
commit 93d06daf67
3 changed files with 40 additions and 19 deletions

View File

@@ -13,6 +13,7 @@ Each class in the schema gets a corresponding `struct` in `TrapClasses.h`, where
import functools
import pathlib
import typing
from typing import Dict
import inflection
@@ -34,22 +35,25 @@ def _get_type(t: str) -> str:
return t
def _get_field(cls: schema.Class, p: schema.Property) -> cpp.Field:
trap_name = None
if not p.is_single:
trap_name = inflection.camelize(f"{cls.name}_{p.name}")
if not p.is_predicate:
trap_name = inflection.pluralize(trap_name)
args = dict(
field_name=p.name + ("_" if p.name in cpp.cpp_keywords else ""),
type=_get_type(p.type),
is_optional=p.is_optional,
is_repeated=p.is_repeated,
is_predicate=p.is_predicate,
trap_name=trap_name,
)
args.update(cpp.get_field_override(p.name))
return cpp.Field(**args)
def _get_fields(cls: schema.Class) -> typing.Iterable[cpp.Field]:
for p in cls.properties:
if "cpp_skip" in p.pragmas:
continue
trap_name = None
if not p.is_single:
trap_name = inflection.camelize(f"{cls.name}_{p.name}")
if not p.is_predicate:
trap_name = inflection.pluralize(trap_name)
args = dict(
field_name=p.name + ("_" if p.name in cpp.cpp_keywords else ""),
type=_get_type(p.type),
is_optional=p.is_optional,
is_repeated=p.is_repeated,
is_predicate=p.is_predicate,
trap_name=trap_name,
)
args.update(cpp.get_field_override(p.name))
yield cpp.Field(**args)
class Processor:
@@ -65,7 +69,7 @@ class Processor:
return cpp.Class(
name=name,
bases=[self._get_class(b) for b in cls.bases],
fields=[_get_field(cls, p) for p in cls.properties],
fields=list(_get_fields(cls)),
final=not cls.derived,
trap_name=trap_name,
)

View File

@@ -13,14 +13,18 @@ _directories:
stmt: Stmt$
Element:
is_unknown: predicate
is_unknown:
type: predicate
_pragma: cpp_skip # this is emitted using trap entries directly
_pragma: qltest_skip
File:
name: string
Locatable:
location: Location?
location:
type: Location?
_pragma: cpp_skip # this is emitted using trap entries directly
_pragma: qltest_skip
Location:

View File

@@ -165,5 +165,18 @@ def test_classes_with_dirs(generate_grouped):
}
def test_cpp_skip_pragma(generate):
assert generate([
schema.Class(name="A", properties=[
schema.SingleProperty("x", "foo"),
schema.SingleProperty("y", "bar", pragmas=["x", "cpp_skip", "y"]),
])
]) == [
cpp.Class(name="A", final=True, trap_name="As", fields=[
cpp.Field("x", "foo"),
]),
]
if __name__ == '__main__':
sys.exit(pytest.main([__file__] + sys.argv[1:]))