Skip to content

Commit 7bcc5db

Browse files
committed
Swift: parametrize namespace and other things in codegen
This is so that we can use this in the PoC branch.
1 parent c87fb4d commit 7bcc5db

File tree

10 files changed

+76
-39
lines changed

10 files changed

+76
-39
lines changed

swift/codegen/cppgen.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import functools
2-
import inflection
32
from typing import Dict
43

4+
import inflection
55
from toposort import toposort_flatten
66

77
from swift.codegen.lib import cpp, generator, schema
@@ -20,7 +20,7 @@ def _get_type(t: str) -> str:
2020
def _get_field(cls: schema.Class, p: schema.Property) -> cpp.Field:
2121
trap_name = None
2222
if not p.is_single:
23-
trap_name = inflection.pluralize(inflection.camelize(f"{cls.name}_{p.name}")) + "Trap"
23+
trap_name = inflection.pluralize(inflection.camelize(f"{cls.name}_{p.name}"))
2424
args = dict(
2525
name=p.name + ("_" if p.name in cpp.cpp_keywords else ""),
2626
type=_get_type(p.type),
@@ -41,7 +41,7 @@ def _get_class(self, name: str) -> cpp.Class:
4141
cls = self._classmap[name]
4242
trap_name = None
4343
if not cls.derived or any(p.is_single for p in cls.properties):
44-
trap_name = inflection.pluralize(cls.name) + "Trap"
44+
trap_name = inflection.pluralize(cls.name)
4545
return cpp.Class(
4646
name=name,
4747
bases=[self._get_class(b) for b in cls.bases],
@@ -58,7 +58,8 @@ def get_classes(self):
5858
def generate(opts, renderer):
5959
processor = Processor({cls.name: cls for cls in schema.load(opts.schema).classes})
6060
out = opts.cpp_output
61-
renderer.render(cpp.ClassList(processor.get_classes()), out / "TrapClasses.h")
61+
renderer.render(cpp.ClassList(processor.get_classes(), opts.cpp_namespace, opts.trap_suffix,
62+
opts.cpp_include_dir), out / "TrapClasses.h")
6263

6364

6465
tags = ("cpp", "schema")

swift/codegen/lib/cpp.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,18 @@ def has_bases(self):
105105
class TrapList:
106106
template: ClassVar = 'trap_traps'
107107

108-
traps: List[Trap] = field(default_factory=list)
108+
traps: List[Trap]
109+
namespace: str
110+
trap_suffix: str
111+
include_dir: str
109112

110113

111114
@dataclass
112115
class TagList:
113116
template: ClassVar = 'trap_tags'
114117

115-
tags: List[Tag] = field(default_factory=list)
118+
tags: List[Tag]
119+
namespace: str
116120

117121

118122
@dataclass
@@ -148,3 +152,6 @@ class ClassList:
148152
template: ClassVar = "cpp_classes"
149153

150154
classes: List[Class]
155+
namespace: str
156+
trap_suffix: str
157+
include_dir: str

swift/codegen/lib/options.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ def _init_options():
1616
Option("--ql-stub-output", tags=["ql"], type=_abspath, default=paths.swift_dir / "ql/lib/codeql/swift/elements")
1717
Option("--codeql-binary", tags=["ql"], default="codeql")
1818
Option("--cpp-output", tags=["cpp"], type=_abspath, required=True)
19+
Option("--cpp-namespace", tags=["cpp"], default="codeql")
20+
Option("--trap-suffix", tags=["cpp"], default="Trap")
21+
Option("--cpp-include-dir", tags=["cpp"], required=True)
1922

2023

2124
def _abspath(x):

swift/codegen/templates/cpp_classes.mustache

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
#include <optional>
77
#include <vector>
88

9-
#include "swift/extractor/trap/TrapLabel.h"
10-
#include "swift/extractor/trap/TrapEntries.h"
9+
#include "{{include_dir}}/TrapLabel.h"
10+
#include "{{include_dir}}/TrapEntries.h"
1111

12-
namespace codeql {
12+
namespace {{namespace}} {
1313
{{#classes}}
1414

1515
struct {{name}}{{#final}} : Binding<{{name}}Tag>{{#bases}}, {{ref.name}}{{/bases}}{{/final}}{{^final}}{{#has_bases}}: {{#bases}}{{^first}}, {{/first}}{{ref.name}}{{/bases}}{{/has_bases}}{{/final}} {
@@ -30,21 +30,21 @@ struct {{name}}{{#final}} : Binding<{{name}}Tag>{{#bases}}, {{ref.name}}{{/bases
3030
{{ref.name}}::emit(id, out);
3131
{{/bases}}
3232
{{#trap_name}}
33-
out << {{.}}{id{{#single_fields}}, {{name}}{{/single_fields}}} << '\n';
33+
out << {{.}}{{trap_suffix}}{id{{#single_fields}}, {{name}}{{/single_fields}}} << '\n';
3434
{{/trap_name}}
3535
{{#fields}}
3636
{{#is_optional}}
3737
{{^is_repeated}}
38-
if ({{name}}) out << {{trap_name}}{id, *{{name}}} << '\n';
38+
if ({{name}}) out << {{trap_name}}{{trap_suffix}}{id, *{{name}}} << '\n';
3939
{{/is_repeated}}
4040
{{/is_optional}}
4141
{{#is_repeated}}
4242
for (auto i = 0u; i < {{name}}.size(); ++i) {
4343
{{^is_optional}}
44-
out << {{trap_name}}{id, i, {{name}}[i]};
44+
out << {{trap_name}}{{trap_suffix}}{id, i, {{name}}[i]};
4545
{{/is_optional}}
4646
{{#is_optional}}
47-
if ({{name}}[i]) out << {{trap_name}}{id, i, *{{name}}[i]};
47+
if ({{name}}[i]) out << {{trap_name}}{{trap_suffix}}{id, i, *{{name}}[i]};
4848
{{/is_optional}}
4949
}
5050
{{/is_repeated}}

swift/codegen/templates/trap_tags.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// clang-format off
33
#pragma once
44

5-
namespace codeql {
5+
namespace {{namespace}} {
66
{{#tags}}
77

88
// {{id}}

swift/codegen/templates/trap_traps.mustache

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
#include <iostream>
66
#include <string>
77

8-
#include "swift/extractor/trap/TrapLabel.h"
9-
#include "swift/extractor/trap/TrapTags.h"
8+
#include "{{include_dir}}/TrapLabel.h"
9+
#include "{{include_dir}}/TrapTags.h"
1010

11-
namespace codeql {
11+
namespace {{namespace}} {
1212
{{#traps}}
1313

1414
// {{table_name}}
15-
struct {{name}}Trap {
15+
struct {{name}}{{trap_suffix}} {
1616
static constexpr bool is_binding = {{#id}}true{{/id}}{{^id}}false{{/id}};
1717
{{#id}}
1818
{{type}} getBoundLabel() const { return {{cpp_name}}; }

swift/codegen/test/test_cppgen.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,19 @@
1010
@pytest.fixture
1111
def generate(opts, renderer, input):
1212
opts.cpp_output = output_dir
13+
opts.cpp_namespace = "test_namespace"
14+
opts.trap_suffix = "TestTrapSuffix"
15+
opts.cpp_include_dir = "my/include/dir"
1316

1417
def ret(classes):
1518
input.classes = classes
1619
generated = run_generation(cppgen.generate, opts, renderer)
1720
assert set(generated) == {output_dir / "TrapClasses.h"}
1821
generated = generated[output_dir / "TrapClasses.h"]
1922
assert isinstance(generated, cpp.ClassList)
23+
assert generated.namespace == opts.cpp_namespace
24+
assert generated.trap_suffix == opts.trap_suffix
25+
assert generated.include_dir == opts.cpp_include_dir
2026
return generated.classes
2127

2228
return ret
@@ -30,7 +36,7 @@ def test_empty_class(generate):
3036
assert generate([
3137
schema.Class(name="MyClass"),
3238
]) == [
33-
cpp.Class(name="MyClass", final=True, trap_name="MyClassesTrap")
39+
cpp.Class(name="MyClass", final=True, trap_name="MyClasses")
3440
]
3541

3642

@@ -41,7 +47,7 @@ def test_two_class_hierarchy(generate):
4147
schema.Class(name="B", bases={"A"}),
4248
]) == [
4349
base,
44-
cpp.Class(name="B", bases=[base], final=True, trap_name="BsTrap"),
50+
cpp.Class(name="B", bases=[base], final=True, trap_name="Bs"),
4551
]
4652

4753

@@ -50,8 +56,8 @@ def test_complex_hierarchy_topologically_ordered(generate):
5056
b = cpp.Class(name="B")
5157
c = cpp.Class(name="C", bases=[a])
5258
d = cpp.Class(name="D", bases=[a])
53-
e = cpp.Class(name="E", bases=[b, c, d], final=True, trap_name="EsTrap")
54-
f = cpp.Class(name="F", bases=[c], final=True, trap_name="FsTrap")
59+
e = cpp.Class(name="E", bases=[b, c, d], final=True, trap_name="Es")
60+
f = cpp.Class(name="F", bases=[c], final=True, trap_name="Fs")
5561
assert generate([
5662
schema.Class(name="F", bases={"C"}),
5763
schema.Class(name="B", derived={"E"}),
@@ -70,9 +76,9 @@ def test_complex_hierarchy_topologically_ordered(generate):
7076
])
7177
@pytest.mark.parametrize("property_cls,optional,repeated,trap_name", [
7278
(schema.SingleProperty, False, False, None),
73-
(schema.OptionalProperty, True, False, "MyClassPropsTrap"),
74-
(schema.RepeatedProperty, False, True, "MyClassPropsTrap"),
75-
(schema.RepeatedOptionalProperty, True, True, "MyClassPropsTrap"),
79+
(schema.OptionalProperty, True, False, "MyClassProps"),
80+
(schema.RepeatedProperty, False, True, "MyClassProps"),
81+
(schema.RepeatedOptionalProperty, True, True, "MyClassProps"),
7682
])
7783
def test_class_with_field(generate, type, expected, property_cls, optional, repeated, trap_name):
7884
assert generate([
@@ -81,7 +87,7 @@ def test_class_with_field(generate, type, expected, property_cls, optional, repe
8187
cpp.Class(name="MyClass",
8288
fields=[cpp.Field("prop", expected, is_optional=optional,
8389
is_repeated=repeated, trap_name=trap_name)],
84-
trap_name="MyClassesTrap",
90+
trap_name="MyClasses",
8591
final=True)
8692
]
8793

@@ -94,7 +100,7 @@ def test_class_with_overridden_unsigned_field(generate, name):
94100
]) == [
95101
cpp.Class(name="MyClass",
96102
fields=[cpp.Field(name, "unsigned")],
97-
trap_name="MyClassesTrap",
103+
trap_name="MyClasses",
98104
final=True)
99105
]
100106

@@ -106,7 +112,7 @@ def test_class_with_overridden_underscore_field(generate):
106112
]) == [
107113
cpp.Class(name="MyClass",
108114
fields=[cpp.Field("something", "bar")],
109-
trap_name="MyClassesTrap",
115+
trap_name="MyClasses",
110116
final=True)
111117
]
112118

@@ -119,7 +125,7 @@ def test_class_with_keyword_field(generate, name):
119125
]) == [
120126
cpp.Class(name="MyClass",
121127
fields=[cpp.Field(name + "_", "bar")],
122-
trap_name="MyClassesTrap",
128+
trap_name="MyClasses",
123129
final=True)
124130
]
125131

swift/codegen/test/test_trapgen.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
@pytest.fixture
1111
def generate(opts, renderer, dbscheme_input):
1212
opts.cpp_output = output_dir
13+
opts.cpp_namespace = "test_namespace"
14+
opts.trap_suffix = "TrapSuffix"
15+
opts.cpp_include_dir = "my/include/dir"
1316

1417
def ret(entities):
1518
dbscheme_input.entities = entities
@@ -22,27 +25,35 @@ def ret(entities):
2225

2326

2427
@pytest.fixture
25-
def generate_traps(generate):
28+
def generate_traps(opts, generate):
2629
def ret(entities):
2730
traps, _ = generate(entities)
2831
assert isinstance(traps, cpp.TrapList)
32+
assert traps.namespace == opts.cpp_namespace
33+
assert traps.trap_suffix == opts.trap_suffix
34+
assert traps.include_dir == opts.cpp_include_dir
2935
return traps.traps
3036

3137
return ret
3238

3339

3440
@pytest.fixture
35-
def generate_tags(generate):
41+
def generate_tags(opts, generate):
3642
def ret(entities):
3743
_, tags = generate(entities)
3844
assert isinstance(tags, cpp.TagList)
45+
assert tags.namespace == opts.cpp_namespace
3946
return tags.tags
4047

4148
return ret
4249

4350

44-
def test_empty(generate):
45-
assert generate([]) == (cpp.TrapList([]), cpp.TagList([]))
51+
def test_empty_traps(generate_traps):
52+
assert generate_traps([]) == []
53+
54+
55+
def test_empty_tags(generate_tags):
56+
assert generate_tags([]) == []
4657

4758

4859
def test_one_empty_table_rejected(generate_traps):

swift/codegen/trapgen.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
#!/usr/bin/env python3
22

33
import logging
4-
import re
54

65
import inflection
76
from toposort import toposort_flatten
87

98
from swift.codegen.lib import dbscheme, generator, cpp
109

11-
1210
log = logging.getLogger(__name__)
1311

1412

@@ -70,7 +68,8 @@ def generate(opts, renderer):
7068
for d in e.rhs:
7169
tag_graph.setdefault(d.type, set()).add(e.lhs)
7270

73-
renderer.render(cpp.TrapList(traps), out / "TrapEntries.h")
71+
renderer.render(cpp.TrapList(traps, opts.cpp_namespace, opts.trap_suffix, opts.cpp_include_dir),
72+
out / "TrapEntries.h")
7473

7574
tags = []
7675
for index, tag in enumerate(toposort_flatten(tag_graph)):
@@ -80,7 +79,7 @@ def generate(opts, renderer):
8079
index=index,
8180
id=tag,
8281
))
83-
renderer.render(cpp.TagList(tags), out / "TrapTags.h")
82+
renderer.render(cpp.TagList(tags, opts.cpp_namespace), out / "TrapTags.h")
8483

8584

8685
tags = ("cpp", "dbscheme")

swift/extractor/trap/BUILD.bazel

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ genrule(
55
"TrapEntries.h",
66
"TrapTags.h",
77
],
8-
cmd = "$(location //swift/codegen:trapgen) --dbscheme $< --cpp-output $(RULEDIR)",
8+
cmd = " ".join([
9+
"$(location //swift/codegen:trapgen)",
10+
"--dbscheme $<",
11+
"--cpp-include-dir " + package_name(),
12+
"--cpp-output $(RULEDIR)",
13+
]),
914
exec_tools = ["//swift/codegen:trapgen"],
1015
)
1116

@@ -18,7 +23,12 @@ genrule(
1823
outs = [
1924
"TrapClasses.h",
2025
],
21-
cmd = "$(location //swift/codegen:cppgen) --schema $(location //swift/codegen:schema) --cpp-output $(RULEDIR)",
26+
cmd = " ".join([
27+
"$(location //swift/codegen:cppgen)",
28+
"--schema $(location //swift/codegen:schema)",
29+
"--cpp-include-dir " + package_name(),
30+
"--cpp-output $(RULEDIR)",
31+
]),
2232
exec_tools = ["//swift/codegen:cppgen"],
2333
)
2434

0 commit comments

Comments
 (0)