Skip to content

Commit 1f05b41

Browse files
committed
Rust: Add codegen for generating a toStringImpl that delegates to getAPrimaryQlClass
1 parent 7a367c9 commit 1f05b41

276 files changed

Lines changed: 944 additions & 517 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

misc/codegen/generators/qlgen.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,9 @@ def get_ql_class(self, cls: schema.Class) -> ql.Class:
237237
hideable="ql_hideable" in cls.pragmas,
238238
internal="ql_internal" in cls.pragmas,
239239
cfg=cls.cfg,
240+
to_string_impl_from_primary_class=bool(
241+
cls.pragmas.get("ql_to_string_impl_from_primary_class")
242+
),
240243
)
241244
return self._class_cache[cache_key]
242245

misc/codegen/lib/ql.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ class Class:
117117
doc: List[str] = field(default_factory=list)
118118
hideable: bool = False
119119
cfg: bool = False
120+
to_string_impl_from_primary_class: bool = False
120121

121122
def __post_init__(self):
122123
def get_bases(bases):

misc/codegen/lib/schemadefs.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,12 @@ def __getitem__(self, item):
263263

264264
ql.add(_Parametrized(_ClassPragma("default_doc_name"), factory=lambda doc: doc))
265265
ql.add(_ClassPragma("hideable", inherited=True))
266+
ql.add(
267+
_Parametrized(
268+
_ClassPragma("to_string_impl_from_primary_class", inherited=True),
269+
factory=lambda enabled: enabled,
270+
)
271+
)
266272
ql.add(_Pragma("internal"))
267273
ql.add(_Parametrized(_Pragma("name"), factory=lambda name: name))
268274
ql.add(_Parametrized(_PropertyPragma("db_table_name"), factory=lambda name: name))

misc/codegen/templates/ql_class.mustache

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ module Generated {
7777
{{/root}}
7878
{{#final}}
7979
override string getAPrimaryQlClass() { result = "{{name}}" }
80+
{{#to_string_impl_from_primary_class}}
81+
82+
override string toStringImpl() { result = this.getAPrimaryQlClass() }
83+
{{/to_string_impl_from_primary_class}}
8084
{{/final}}
8185
{{#properties}}
8286

misc/codegen/test/test_qlgen.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,47 @@ def test_one_empty_class(generate_classes):
196196
}
197197

198198

199+
def test_to_string_impl_from_primary_class(generate_classes):
200+
assert generate_classes(
201+
[
202+
schema.Class(
203+
"A",
204+
derived={"B"},
205+
pragmas={"ql_to_string_impl_from_primary_class": True},
206+
),
207+
schema.Class(
208+
"B",
209+
bases=["A"],
210+
pragmas={"ql_to_string_impl_from_primary_class": True},
211+
),
212+
]
213+
) == {
214+
"A.qll": (
215+
a_ql_class_public(name="A"),
216+
a_ql_stub(name="A"),
217+
a_ql_class(
218+
name="A",
219+
imports=[stub_import_prefix + "A"],
220+
to_string_impl_from_primary_class=True,
221+
),
222+
),
223+
"B.qll": (
224+
a_ql_class_public(name="B", imports=[stub_import_prefix + "A"]),
225+
a_ql_stub(name="B"),
226+
a_ql_class(
227+
name="B",
228+
final=True,
229+
bases=["A"],
230+
bases_impl=["AImpl::A"],
231+
imports=[
232+
stub_import_prefix_internal + "AImpl::Impl as AImpl",
233+
],
234+
to_string_impl_from_primary_class=True,
235+
),
236+
),
237+
}
238+
239+
199240
def test_one_empty_internal_class(generate_classes):
200241
assert generate_classes([schema.Class("A", pragmas=["ql_internal"])]) == {
201242
"A.qll": (

misc/codegen/test/test_schemaloader.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,29 @@ class A:
382382
}
383383

384384

385+
def test_inherited_to_string_impl_from_primary_class_pragma():
386+
@load
387+
class data:
388+
@defs.ql.to_string_impl_from_primary_class(True)
389+
class A:
390+
pass
391+
392+
class B(A):
393+
pass
394+
395+
@defs.ql.to_string_impl_from_primary_class(False)
396+
class C(B):
397+
pass
398+
399+
class D(C):
400+
pass
401+
402+
assert data.classes["A"].pragmas["ql_to_string_impl_from_primary_class"] is True
403+
assert data.classes["B"].pragmas["ql_to_string_impl_from_primary_class"] is True
404+
assert data.classes["C"].pragmas["ql_to_string_impl_from_primary_class"] is False
405+
assert data.classes["D"].pragmas["ql_to_string_impl_from_primary_class"] is False
406+
407+
385408
def test_synth_from_class():
386409
@load
387410
class data:

rust/ql/.generated.list

Lines changed: 259 additions & 174 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/ql/.gitattributes

Lines changed: 85 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/ql/lib/codeql/rust/elements/internal/AbiImpl.qll

Lines changed: 2 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/ql/lib/codeql/rust/elements/internal/ArgListImpl.qll

Lines changed: 2 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)