Skip to content

Commit 93d06da

Browse files
committed
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`.
1 parent 93a4a32 commit 93d06da

File tree

3 files changed

+40
-19
lines changed

3 files changed

+40
-19
lines changed

swift/codegen/generators/cppgen.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import functools
1515
import pathlib
16+
import typing
1617
from typing import Dict
1718

1819
import inflection
@@ -34,22 +35,25 @@ def _get_type(t: str) -> str:
3435
return t
3536

3637

37-
def _get_field(cls: schema.Class, p: schema.Property) -> cpp.Field:
38-
trap_name = None
39-
if not p.is_single:
40-
trap_name = inflection.camelize(f"{cls.name}_{p.name}")
41-
if not p.is_predicate:
42-
trap_name = inflection.pluralize(trap_name)
43-
args = dict(
44-
field_name=p.name + ("_" if p.name in cpp.cpp_keywords else ""),
45-
type=_get_type(p.type),
46-
is_optional=p.is_optional,
47-
is_repeated=p.is_repeated,
48-
is_predicate=p.is_predicate,
49-
trap_name=trap_name,
50-
)
51-
args.update(cpp.get_field_override(p.name))
52-
return cpp.Field(**args)
38+
def _get_fields(cls: schema.Class) -> typing.Iterable[cpp.Field]:
39+
for p in cls.properties:
40+
if "cpp_skip" in p.pragmas:
41+
continue
42+
trap_name = None
43+
if not p.is_single:
44+
trap_name = inflection.camelize(f"{cls.name}_{p.name}")
45+
if not p.is_predicate:
46+
trap_name = inflection.pluralize(trap_name)
47+
args = dict(
48+
field_name=p.name + ("_" if p.name in cpp.cpp_keywords else ""),
49+
type=_get_type(p.type),
50+
is_optional=p.is_optional,
51+
is_repeated=p.is_repeated,
52+
is_predicate=p.is_predicate,
53+
trap_name=trap_name,
54+
)
55+
args.update(cpp.get_field_override(p.name))
56+
yield cpp.Field(**args)
5357

5458

5559
class Processor:
@@ -65,7 +69,7 @@ def _get_class(self, name: str) -> cpp.Class:
6569
return cpp.Class(
6670
name=name,
6771
bases=[self._get_class(b) for b in cls.bases],
68-
fields=[_get_field(cls, p) for p in cls.properties],
72+
fields=list(_get_fields(cls)),
6973
final=not cls.derived,
7074
trap_name=trap_name,
7175
)

swift/codegen/schema.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,18 @@ _directories:
1313
stmt: Stmt$
1414

1515
Element:
16-
is_unknown: predicate
16+
is_unknown:
17+
type: predicate
18+
_pragma: cpp_skip # this is emitted using trap entries directly
1719
_pragma: qltest_skip
1820

1921
File:
2022
name: string
2123

2224
Locatable:
23-
location: Location?
25+
location:
26+
type: Location?
27+
_pragma: cpp_skip # this is emitted using trap entries directly
2428
_pragma: qltest_skip
2529

2630
Location:

swift/codegen/test/test_cppgen.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,5 +165,18 @@ def test_classes_with_dirs(generate_grouped):
165165
}
166166

167167

168+
def test_cpp_skip_pragma(generate):
169+
assert generate([
170+
schema.Class(name="A", properties=[
171+
schema.SingleProperty("x", "foo"),
172+
schema.SingleProperty("y", "bar", pragmas=["x", "cpp_skip", "y"]),
173+
])
174+
]) == [
175+
cpp.Class(name="A", final=True, trap_name="As", fields=[
176+
cpp.Field("x", "foo"),
177+
]),
178+
]
179+
180+
168181
if __name__ == '__main__':
169182
sys.exit(pytest.main([__file__] + sys.argv[1:]))

0 commit comments

Comments
 (0)