Skip to content

Commit b2b5fd2

Browse files
committed
Swift: add more parametrization
This enables codegen to run on the swift PoC branch.
1 parent ac3ccea commit b2b5fd2

File tree

11 files changed

+58
-53
lines changed

11 files changed

+58
-53
lines changed

swift/codegen/cppgen.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,23 @@
77
from swift.codegen.lib import cpp, generator, schema
88

99

10-
def _get_type(t: str) -> str:
10+
def _get_type(t: str, trap_affix: str) -> str:
1111
if t == "string":
1212
return "std::string"
1313
if t == "boolean":
1414
return "bool"
1515
if t[0].isupper():
16-
return f"TrapLabel<{t}Tag>"
16+
return f"{trap_affix}Label<{t}Tag>"
1717
return t
1818

1919

20-
def _get_field(cls: schema.Class, p: schema.Property) -> cpp.Field:
20+
def _get_field(cls: schema.Class, p: schema.Property, trap_affix: str) -> cpp.Field:
2121
trap_name = None
2222
if not p.is_single:
2323
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 ""),
26-
type=_get_type(p.type),
26+
type=_get_type(p.type, trap_affix),
2727
is_optional=p.is_optional,
2828
is_repeated=p.is_repeated,
2929
trap_name=trap_name,
@@ -33,8 +33,9 @@ def _get_field(cls: schema.Class, p: schema.Property) -> cpp.Field:
3333

3434

3535
class Processor:
36-
def __init__(self, data: Dict[str, schema.Class]):
36+
def __init__(self, data: Dict[str, schema.Class], trap_affix: str):
3737
self._classmap = data
38+
self._trap_affix = trap_affix
3839

3940
@functools.lru_cache(maxsize=None)
4041
def _get_class(self, name: str) -> cpp.Class:
@@ -45,7 +46,7 @@ def _get_class(self, name: str) -> cpp.Class:
4546
return cpp.Class(
4647
name=name,
4748
bases=[self._get_class(b) for b in cls.bases],
48-
fields=[_get_field(cls, p) for p in cls.properties],
49+
fields=[_get_field(cls, p, self._trap_affix) for p in cls.properties],
4950
final=not cls.derived,
5051
trap_name=trap_name,
5152
)
@@ -56,10 +57,10 @@ def get_classes(self):
5657

5758

5859
def generate(opts, renderer):
59-
processor = Processor({cls.name: cls for cls in schema.load(opts.schema).classes})
60+
processor = Processor({cls.name: cls for cls in schema.load(opts.schema).classes}, opts.trap_affix)
6061
out = opts.cpp_output
61-
renderer.render(cpp.ClassList(processor.get_classes(), opts.cpp_namespace, opts.trap_suffix,
62-
opts.cpp_include_dir), out / "TrapClasses.h")
62+
renderer.render(cpp.ClassList(processor.get_classes(), opts.cpp_namespace, opts.trap_affix,
63+
opts.cpp_include_dir), out / f"{opts.trap_affix}Classes.h")
6364

6465

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

swift/codegen/dbschemegen.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ def get_declarations(data: schema.Schema):
6363
return [d for cls in data.classes for d in cls_to_dbscheme(cls)]
6464

6565

66-
def get_includes(data: schema.Schema, include_dir: pathlib.Path):
66+
def get_includes(data: schema.Schema, include_dir: pathlib.Path, swift_dir: pathlib.Path):
6767
includes = []
6868
for inc in data.includes:
6969
inc = include_dir / inc
7070
with open(inc) as inclusion:
71-
includes.append(SchemeInclude(src=inc.relative_to(paths.swift_dir), data=inclusion.read()))
71+
includes.append(SchemeInclude(src=inc.relative_to(swift_dir), data=inclusion.read()))
7272
return includes
7373

7474

@@ -78,8 +78,8 @@ def generate(opts, renderer):
7878

7979
data = schema.load(input)
8080

81-
dbscheme = Scheme(src=input.relative_to(paths.swift_dir),
82-
includes=get_includes(data, include_dir=input.parent),
81+
dbscheme = Scheme(src=input.relative_to(opts.swift_dir),
82+
includes=get_includes(data, include_dir=input.parent, swift_dir=opts.swift_dir),
8383
declarations=get_declarations(data))
8484

8585
renderer.render(dbscheme, out)

swift/codegen/lib/cpp.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class TrapList:
107107

108108
traps: List[Trap]
109109
namespace: str
110-
trap_suffix: str
110+
trap_affix: str
111111
include_dir: str
112112

113113

@@ -153,5 +153,5 @@ class ClassList:
153153

154154
classes: List[Class]
155155
namespace: str
156-
trap_suffix: str
156+
trap_affix: str
157157
include_dir: str

swift/codegen/lib/options.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@
1010

1111
def _init_options():
1212
Option("--verbose", "-v", action="store_true")
13+
Option("--swift-dir", type=_abspath, default=paths.swift_dir)
1314
Option("--schema", tags=["schema"], type=_abspath, default=paths.swift_dir / "codegen/schema.yml")
1415
Option("--dbscheme", tags=["dbscheme"], type=_abspath, default=paths.swift_dir / "ql/lib/swift.dbscheme")
1516
Option("--ql-output", tags=["ql"], type=_abspath, default=paths.swift_dir / "ql/lib/codeql/swift/generated")
1617
Option("--ql-stub-output", tags=["ql"], type=_abspath, default=paths.swift_dir / "ql/lib/codeql/swift/elements")
1718
Option("--codeql-binary", tags=["ql"], default="codeql")
1819
Option("--cpp-output", tags=["cpp"], type=_abspath, required=True)
1920
Option("--cpp-namespace", tags=["cpp"], default="codeql")
20-
Option("--trap-suffix", tags=["cpp"], default="Trap")
21+
Option("--trap-affix", tags=["cpp"], default="Trap")
2122
Option("--cpp-include-dir", tags=["cpp"], required=True)
2223

2324

swift/codegen/qlgen.py

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

33
import logging
4+
import pathlib
45
import subprocess
56

67
import inflection
@@ -47,8 +48,8 @@ def get_ql_class(cls: schema.Class):
4748
)
4849

4950

50-
def get_import(file):
51-
stem = file.relative_to(paths.swift_dir / "ql/lib").with_suffix("")
51+
def get_import(file: pathlib.Path, swift_dir: pathlib.Path):
52+
stem = file.relative_to(swift_dir / "ql/lib").with_suffix("")
5253
return str(stem).replace("/", ".")
5354

5455

@@ -89,15 +90,15 @@ def generate(opts, renderer):
8990
imports = {}
9091

9192
for c in classes:
92-
imports[c.name] = get_import(stub_out / c.path)
93+
imports[c.name] = get_import(stub_out / c.path, opts.swift_dir)
9394

9495
for c in classes:
9596
qll = (out / c.path).with_suffix(".qll")
9697
c.imports = [imports[t] for t in get_classes_used_by(c)]
9798
renderer.render(c, qll)
9899
stub_file = (stub_out / c.path).with_suffix(".qll")
99100
if not stub_file.is_file() or is_generated(stub_file):
100-
stub = ql.Stub(name=c.name, base_import=get_import(qll))
101+
stub = ql.Stub(name=c.name, base_import=get_import(qll, opts.swift_dir))
101102
renderer.render(stub, stub_file)
102103

103104
# for example path/to/syntax/generated -> path/to/syntax.qll

swift/codegen/templates/cpp_classes.mustache

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

9-
#include "{{include_dir}}/TrapLabel.h"
10-
#include "./TrapEntries.h"
9+
#include "{{include_dir}}/{{trap_affix}}Label.h"
10+
#include "./{{trap_affix}}Entries.h"
1111

1212
namespace {{namespace}} {
1313
{{#classes}}
@@ -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 << {{.}}{{trap_suffix}}{id{{#single_fields}}, {{name}}{{/single_fields}}} << '\n';
33+
out << {{.}}{{trap_affix}}{id{{#single_fields}}, {{name}}{{/single_fields}}} << '\n';
3434
{{/trap_name}}
3535
{{#fields}}
3636
{{#is_optional}}
3737
{{^is_repeated}}
38-
if ({{name}}) out << {{trap_name}}{{trap_suffix}}{id, *{{name}}} << '\n';
38+
if ({{name}}) out << {{trap_name}}{{trap_affix}}{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}}{{trap_suffix}}{id, i, {{name}}[i]};
44+
out << {{trap_name}}{{trap_affix}}{id, i, {{name}}[i]};
4545
{{/is_optional}}
4646
{{#is_optional}}
47-
if ({{name}}[i]) out << {{trap_name}}{{trap_suffix}}{id, i, *{{name}}[i]};
47+
if ({{name}}[i]) out << {{trap_name}}{{trap_affix}}{id, i, *{{name}}[i]};
4848
{{/is_optional}}
4949
}
5050
{{/is_repeated}}

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 "{{include_dir}}/TrapLabel.h"
9-
#include "./TrapTags.h"
8+
#include "{{include_dir}}/{{trap_affix}}Label.h"
9+
#include "./{{trap_affix}}Tags.h"
1010

1111
namespace {{namespace}} {
1212
{{#traps}}
1313

1414
// {{table_name}}
15-
struct {{name}}{{trap_suffix}} {
15+
struct {{name}}{{trap_affix}} {
1616
static constexpr bool is_binding = {{#id}}true{{/id}}{{^id}}false{{/id}};
1717
{{#id}}
1818
{{type}} getBoundLabel() const { return {{cpp_name}}; }
@@ -23,7 +23,7 @@ struct {{name}}{{trap_suffix}} {
2323
{{/fields}}
2424
};
2525

26-
inline std::ostream &operator<<(std::ostream &out, const {{name}}Trap &e) {
26+
inline std::ostream &operator<<(std::ostream &out, const {{name}}{{trap_affix}} &e) {
2727
out << "{{table_name}}("{{#fields}}{{^first}} << ", "{{/first}}
2828
<< {{#get_streamer}}e.{{cpp_name}}{{/get_streamer}}{{/fields}} << ")";
2929
return out;

swift/codegen/test/test_cppgen.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@
1111
def generate(opts, renderer, input):
1212
opts.cpp_output = output_dir
1313
opts.cpp_namespace = "test_namespace"
14-
opts.trap_suffix = "TestTrapSuffix"
14+
opts.trap_affix = "TestTrapAffix"
1515
opts.cpp_include_dir = "my/include/dir"
1616

1717
def ret(classes):
1818
input.classes = classes
1919
generated = run_generation(cppgen.generate, opts, renderer)
20-
assert set(generated) == {output_dir / "TrapClasses.h"}
21-
generated = generated[output_dir / "TrapClasses.h"]
20+
assert set(generated) == {output_dir / "TestTrapAffixClasses.h"}
21+
generated = generated[output_dir / "TestTrapAffixClasses.h"]
2222
assert isinstance(generated, cpp.ClassList)
2323
assert generated.namespace == opts.cpp_namespace
24-
assert generated.trap_suffix == opts.trap_suffix
24+
assert generated.trap_affix == opts.trap_affix
2525
assert generated.include_dir == opts.cpp_include_dir
2626
return generated.classes
2727

@@ -72,7 +72,7 @@ def test_complex_hierarchy_topologically_ordered(generate):
7272
("a", "a"),
7373
("string", "std::string"),
7474
("boolean", "bool"),
75-
("MyClass", "TrapLabel<MyClassTag>"),
75+
("MyClass", "TestTrapAffixLabel<MyClassTag>"),
7676
])
7777
@pytest.mark.parametrize("property_cls,optional,repeated,trap_name", [
7878
(schema.SingleProperty, False, False, None),

swift/codegen/test/test_trapgen.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@
1111
def generate(opts, renderer, dbscheme_input):
1212
opts.cpp_output = output_dir
1313
opts.cpp_namespace = "test_namespace"
14-
opts.trap_suffix = "TrapSuffix"
14+
opts.trap_affix = "TrapAffix"
1515
opts.cpp_include_dir = "my/include/dir"
1616

1717
def ret(entities):
1818
dbscheme_input.entities = entities
1919
generated = run_generation(trapgen.generate, opts, renderer)
2020
assert set(generated) == {output_dir /
21-
"TrapEntries.h", output_dir / "TrapTags.h"}
22-
return generated[output_dir / "TrapEntries.h"], generated[output_dir / "TrapTags.h"]
21+
"TrapAffixEntries.h", output_dir / "TrapAffixTags.h"}
22+
return generated[output_dir / "TrapAffixEntries.h"], generated[output_dir / "TrapAffixTags.h"]
2323

2424
return ret
2525

@@ -30,7 +30,7 @@ def ret(entities):
3030
traps, _ = generate(entities)
3131
assert isinstance(traps, cpp.TrapList)
3232
assert traps.namespace == opts.cpp_namespace
33-
assert traps.trap_suffix == opts.trap_suffix
33+
assert traps.trap_affix == opts.trap_affix
3434
assert traps.include_dir == opts.cpp_include_dir
3535
return traps.traps
3636

@@ -106,7 +106,7 @@ def test_one_table_with_two_binding_first_is_id(generate_traps):
106106
@pytest.mark.parametrize("column,field", [
107107
(dbscheme.Column("x", "string"), cpp.Field("x", "std::string")),
108108
(dbscheme.Column("y", "boolean"), cpp.Field("y", "bool")),
109-
(dbscheme.Column("z", "@db_type"), cpp.Field("z", "TrapLabel<DbTypeTag>")),
109+
(dbscheme.Column("z", "@db_type"), cpp.Field("z", "TrapAffixLabel<DbTypeTag>")),
110110
])
111111
def test_one_table_special_types(generate_traps, column, field):
112112
assert generate_traps([

swift/codegen/test/utils.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import pytest
55

6-
from swift.codegen.lib import render, schema
6+
from swift.codegen.lib import render, schema, paths
77

88
schema_dir = pathlib.Path("a", "dir")
99
schema_file = schema_dir / "schema.yml"
@@ -23,7 +23,9 @@ def renderer():
2323

2424
@pytest.fixture
2525
def opts():
26-
return mock.MagicMock()
26+
ret = mock.MagicMock()
27+
ret.swift_dir = paths.swift_dir
28+
return ret
2729

2830

2931
@pytest.fixture(autouse=True)

0 commit comments

Comments
 (0)