Skip to content

Commit 77a9cea

Browse files
authored
Merge pull request #11901 from github/redsun82/swift-ql-internal
Swift: introduce `@ql.internal` pragma for classes
2 parents 67bd8cb + 6106edd commit 77a9cea

File tree

8 files changed

+59
-34
lines changed

8 files changed

+59
-34
lines changed

swift/codegen/generators/qlgen.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,8 @@ def generate(opts, renderer):
327327
renderer.render(stub, stub_file)
328328

329329
# for example path/to/elements -> path/to/elements.qll
330-
renderer.render(ql.ImportList(list(imports.values())), include_file)
330+
renderer.render(ql.ImportList([i for name, i in imports.items() if not classes[name].ql_internal]),
331+
include_file)
331332

332333
renderer.render(ql.GetParentImplementation(list(classes.values())), out / 'ParentChild.qll')
333334

swift/codegen/lib/ql.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ class Class:
100100
qltest_skip: bool = False
101101
qltest_collapse_hierarchy: bool = False
102102
qltest_uncollapse_hierarchy: bool = False
103+
ql_internal: bool = False
103104
ipa: bool = False
104105
doc: List[str] = field(default_factory=list)
105106

@@ -130,7 +131,7 @@ def last_base(self) -> str:
130131

131132
@property
132133
def has_doc(self) -> bool:
133-
return bool(self.doc)
134+
return bool(self.doc) or self.ql_internal
134135

135136

136137
@dataclass

swift/codegen/lib/schema/defs.py

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,19 @@ def include(source: str):
3535
"__includes", []).append(source)
3636

3737

38+
class _Namespace:
39+
""" simple namespacing mechanism """
40+
41+
def __init__(self, **kwargs):
42+
self.__dict__.update(kwargs)
43+
44+
45+
qltest = _Namespace()
46+
ql = _Namespace()
47+
cpp = _Namespace()
48+
synth = _Namespace()
49+
50+
3851
@_dataclass
3952
class _Pragma(_schema.PropertyModifier):
4053
""" A class or property pragma.
@@ -43,6 +56,10 @@ class _Pragma(_schema.PropertyModifier):
4356
"""
4457
pragma: str
4558

59+
def __post_init__(self):
60+
namespace, _, name = self.pragma.partition('_')
61+
setattr(globals()[namespace], name, self)
62+
4663
def modify(self, prop: _schema.Property):
4764
prop.pragmas.append(self.pragma)
4865

@@ -86,13 +103,6 @@ def __getitem__(self, item):
86103
return item | self.modifier
87104

88105

89-
class _Namespace:
90-
""" simple namespacing mechanism """
91-
92-
def __init__(self, **kwargs):
93-
self.__dict__.update(kwargs)
94-
95-
96106
_ClassDecorator = _Callable[[type], type]
97107

98108

@@ -119,28 +129,21 @@ def f(cls: type) -> type:
119129

120130
use_for_null = _annotate(null=True)
121131

122-
qltest = _Namespace(
123-
skip=_Pragma("qltest_skip"),
124-
collapse_hierarchy=_Pragma("qltest_collapse_hierarchy"),
125-
uncollapse_hierarchy=_Pragma("qltest_uncollapse_hierarchy"),
126-
)
132+
_Pragma("qltest_skip")
133+
_Pragma("qltest_collapse_hierarchy")
134+
_Pragma("qltest_uncollapse_hierarchy")
127135

128-
ql = _Namespace(
129-
default_doc_name=lambda doc: _annotate(doc_name=doc)
130-
)
136+
ql.default_doc_name = lambda doc: _annotate(doc_name=doc)
137+
_Pragma("ql_internal")
131138

132-
cpp = _Namespace(
133-
skip=_Pragma("cpp_skip"),
134-
)
139+
_Pragma("cpp_skip")
135140

136141

137142
def group(name: str = "") -> _ClassDecorator:
138143
return _annotate(group=name)
139144

140145

141-
synth = _Namespace(
142-
from_class=lambda ref: _annotate(ipa=_schema.IpaInfo(
143-
from_class=_schema.get_type_name(ref))),
144-
on_arguments=lambda **kwargs: _annotate(
145-
ipa=_schema.IpaInfo(on_arguments={k: _schema.get_type_name(t) for k, t in kwargs.items()}))
146-
)
146+
synth.from_class = lambda ref: _annotate(ipa=_schema.IpaInfo(
147+
from_class=_schema.get_type_name(ref)))
148+
synth.on_arguments = lambda **kwargs: _annotate(
149+
ipa=_schema.IpaInfo(on_arguments={k: _schema.get_type_name(t) for k, t in kwargs.items()}))

swift/codegen/templates/ql_class.mustache

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ module Generated {
1111
{{#doc}}
1212
* {{.}}
1313
{{/doc}}
14+
{{#ql_internal}}
15+
* INTERNAL: Do not use.
16+
{{/ql_internal}}
1417
*/
1518
{{/has_doc}}
1619
class {{name}} extends Synth::T{{name}}{{#bases}}, {{.}}{{/bases}} {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
// generated by {{generator}}, remove this comment if you wish to edit this file
22
private import {{base_import}}
33

4+
{{#ql_internal}}
5+
/**
6+
* INTERNAL: Do not use.
7+
*/
8+
{{/ql_internal}}
49
class {{name}} extends Generated::{{name}} {}

swift/codegen/test/test_ql.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,16 @@ def test_class_with_children():
127127
assert cls.has_children is True
128128

129129

130-
def test_class_with_doc():
131-
cls = ql.Class("Class", doc=["foo", "bar"])
132-
assert cls.has_doc is True
133-
134-
135-
def test_class_without_doc():
136-
cls = ql.Class("Class", doc=[])
137-
assert cls.has_doc is False
130+
@pytest.mark.parametrize("doc,ql_internal,expected",
131+
[
132+
(["foo", "bar"], False, True),
133+
(["foo", "bar"], True, True),
134+
([], False, False),
135+
([], True, True),
136+
])
137+
def test_has_doc(doc, ql_internal, expected):
138+
cls = ql.Class("Class", doc=doc, ql_internal=ql_internal)
139+
assert cls.has_doc is expected
138140

139141

140142
def test_property_with_description():

swift/codegen/test/test_qlgen.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,15 @@ def test_hierarchy_imports(generate_import_list):
170170
]) == ql.ImportList([stub_import_prefix + cls for cls in "ABCD"])
171171

172172

173+
def test_internal_not_in_import_list(generate_import_list):
174+
assert generate_import_list([
175+
schema.Class("D", bases=["B", "C"]),
176+
schema.Class("C", bases=["A"], derived={"D"}, pragmas=["ql_internal"]),
177+
schema.Class("B", bases=["A"], derived={"D"}),
178+
schema.Class("A", derived={"B", "C"}, pragmas=["ql_internal"]),
179+
]) == ql.ImportList([stub_import_prefix + cls for cls in "BD"])
180+
181+
173182
def test_hierarchy_children(generate_children_implementations):
174183
assert generate_children_implementations([
175184
schema.Class("A", derived={"B", "C"}),

swift/codegen/test/test_schema.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ class A:
265265
(defs.qltest.collapse_hierarchy, "qltest_collapse_hierarchy"),
266266
(defs.qltest.uncollapse_hierarchy, "qltest_uncollapse_hierarchy"),
267267
(defs.cpp.skip, "cpp_skip"),
268+
(defs.ql.internal, "ql_internal"),
268269
]
269270

270271

0 commit comments

Comments
 (0)