Skip to content

Commit de0fa9e

Browse files
committed
Swift: QL generation script
Also added code generation to the swift checks.
1 parent cbdd492 commit de0fa9e

File tree

577 files changed

+4236
-58
lines changed

Some content is hidden

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

577 files changed

+4236
-58
lines changed

.github/workflows/swift-qltest.yml

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,17 @@ defaults:
1212
working-directory: swift
1313

1414
jobs:
15+
codegen:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v2
19+
- uses: ./.github/actions/fetch-codeql
20+
- uses: bazelbuild/setup-bazelisk@v2
21+
- name: Check code generation
22+
run: |
23+
bazel run //swift/codegen
24+
git add .
25+
git diff --exit-code --stat HEAD
1526
qlformat:
1627
runs-on: ubuntu-latest
1728
steps:
@@ -28,18 +39,7 @@ jobs:
2839
steps:
2940
- uses: actions/checkout@v2
3041
- uses: ./.github/actions/fetch-codeql
31-
- name: Install bazelisk - Linux
32-
if: runner.os == 'Linux'
33-
run: |
34-
sudo apt-get update
35-
sudo apt-get install -y wget
36-
wget https://github.com/bazelbuild/bazelisk/releases/download/v1.11.0/bazelisk-linux-amd64
37-
mv bazelisk-linux-amd64 /usr/local/bin/bazel
38-
chmod +x /usr/local/bin/bazel
39-
- name: Install bazelisk - macOS
40-
if: runner.os == 'MacOS'
41-
run: |
42-
brew install bazelisk
42+
- uses: bazelbuild/setup-bazelisk@v2
4343
- name: Build Swift extractor
4444
run: |
4545
bazel run //swift:create-extractor-pack
@@ -48,4 +48,3 @@ jobs:
4848
codeql test run --threads=0 --ram 5000 --search-path "${{ github.workspace }}/swift/extractor-pack" --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition ql/test
4949
env:
5050
GITHUB_TOKEN: ${{ github.token }}
51-

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ repos:
3636

3737
- id: swift-codegen
3838
name: Run Swift checked in code generation
39-
files: ^swift/(codegen/|.*/generated/|ql/lib/swift\.dbscheme$)
39+
files: ^swift/(codegen/|.*/generated/|ql/lib/(swift\.dbscheme$|codeql/swift/elements))
4040
language: system
4141
entry: bazel run //swift/codegen
4242
pass_filenames: false

swift/codegen/codegen.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from lib import generator
55
import dbschemegen
6+
import qlgen
67

78
if __name__ == "__main__":
8-
generator.run(dbschemegen.generate)
9+
generator.run(dbschemegen.generate, qlgen.generate)

swift/codegen/lib/generator.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,5 @@ def run(*generators, tags=None):
2323
`generators` should be callables taking as input an option namespace and a `render.Renderer` instance
2424
"""
2525
opts = _parse(tags)
26-
renderer = render.Renderer(dryrun=opts.check)
2726
for g in generators:
28-
g(opts, renderer)
29-
sys.exit(1 if opts.check and renderer.done_something else 0)
27+
g(opts, render.Renderer())

swift/codegen/lib/options.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99

1010

1111
def _init_options():
12-
Option("--check", "-c", action="store_true")
1312
Option("--verbose", "-v", action="store_true")
1413
Option("--schema", tags=["schema"], type=pathlib.Path, default=paths.swift_dir / "codegen/schema.yml")
1514
Option("--dbscheme", tags=["dbscheme"], type=pathlib.Path, default=paths.swift_dir / "ql/lib/swift.dbscheme")
15+
Option("--ql-output", tags=["ql"], type=pathlib.Path, default=paths.swift_dir / "ql/lib/codeql/swift/generated")
16+
Option("--ql-stub-output", tags=["ql"], type=pathlib.Path, default=paths.swift_dir / "ql/lib/codeql/swift/elements")
17+
Option("--codeql-binary", tags=["ql"], default="codeql")
1618

1719

1820
_options = collections.defaultdict(list)

swift/codegen/lib/render.py

Lines changed: 7 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
https://mustache.github.io/
66
"""
77

8-
import hashlib
98
import logging
109
import pathlib
1110

@@ -16,29 +15,13 @@
1615
log = logging.getLogger(__name__)
1716

1817

19-
def _md5(data):
20-
return hashlib.md5(data).digest()
21-
22-
2318
class Renderer:
2419
""" Template renderer using mustache templates in the `templates` directory """
2520

26-
def __init__(self, dryrun=False):
27-
""" Construct the renderer, which will not write anything if `dryrun` is `True` """
21+
def __init__(self):
2822
self.r = pystache.Renderer(search_dirs=str(paths.lib_dir / "templates"), escape=lambda u: u)
2923
self.generator = paths.exe_file.relative_to(paths.swift_dir)
30-
self.dryrun = dryrun
3124
self.written = set()
32-
self.skipped = set()
33-
self.erased = set()
34-
35-
@property
36-
def done_something(self):
37-
return bool(self.written or self.erased)
38-
39-
@property
40-
def rendered(self):
41-
return self.written | self.skipped
4225

4326
def render(self, data, output: pathlib.Path):
4427
""" Render `data` to `output`.
@@ -50,27 +33,14 @@ def render(self, data, output: pathlib.Path):
5033
mnemonic = type(data).__name__
5134
output.parent.mkdir(parents=True, exist_ok=True)
5235
data = self.r.render_name(data.template, data, generator=self.generator)
53-
if output.is_file():
54-
with open(output, "rb") as file:
55-
if _md5(data.encode()) == _md5(file.read()):
56-
log.debug(f"skipped {output.name}")
57-
self.skipped.add(output)
58-
return
59-
if self.dryrun:
60-
log.error(f"would have generated {mnemonic} {output.name}")
61-
else:
62-
with open(output, "w") as out:
63-
out.write(data)
64-
log.info(f"generated {mnemonic} {output.name}")
36+
with open(output, "w") as out:
37+
out.write(data)
38+
log.debug(f"generated {mnemonic} {output.name}")
6539
self.written.add(output)
6640

6741
def cleanup(self, existing):
6842
""" Remove files in `existing` for which no `render` has been called """
69-
for f in existing - self.written - self.skipped:
43+
for f in existing - self.written:
7044
if f.is_file():
71-
if self.dryrun:
72-
log.error(f"would have removed {f.name}")
73-
else:
74-
f.unlink()
75-
log.info(f"removed {f.name}")
76-
self.erased.add(f)
45+
f.unlink()
46+
log.info(f"removed {f.name}")
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// generated by {{generator}}
2+
{{#imports}}
3+
import {{.}}
4+
{{/imports}}
5+
6+
class {{name}}Base extends {{db_id}}{{#bases}}, {{.}}{{/bases}} {
7+
{{#root}}
8+
string toString() { none() } // overridden by subclasses
9+
10+
{{name}}Base getResolveStep() { none() } // overridden by subclasses
11+
12+
{{name}}Base resolve() {
13+
not exists(getResolveStep()) and result = this
14+
or
15+
result = getResolveStep().resolve()
16+
}
17+
{{/root}}
18+
{{#final}}
19+
override string toString() { result = "{{name}}" }
20+
{{/final}}
21+
{{#properties}}
22+
23+
{{#type_is_class}}
24+
{{type}} get{{singular}}({{#params}}{{^first}}, {{/first}}{{type}} {{param}}{{/params}}) {
25+
exists({{type}} {{local_var}} |
26+
{{tablename}}({{#tableparams}}{{^first}}, {{/first}}{{param}}{{/tableparams}})
27+
and
28+
result = {{local_var}}.resolve())
29+
}
30+
{{/type_is_class}}
31+
{{^type_is_class}}
32+
{{type}} get{{singular}}({{#params}}{{^first}}, {{/first}}{{type}} {{param}}{{/params}}) {
33+
{{tablename}}({{#tableparams}}{{^first}}, {{/first}}{{param}}{{/tableparams}})
34+
}
35+
{{/type_is_class}}
36+
{{#indefinite_article}}
37+
38+
{{type}} get{{.}}{{singular}}() {
39+
result = get{{singular}}({{#params}}{{^first}}, {{/first}}_{{/params}})
40+
}
41+
42+
int getNumberOf{{plural}}() {
43+
result = count(get{{.}}{{singular}}())
44+
}
45+
{{/indefinite_article}}
46+
{{/properties}}
47+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// generated by {{generator}}
2+
{{#imports}}
3+
import {{.}}
4+
{{/imports}}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// generated by {{generator}}, remove this comment if you wish to edit this file
2+
private import {{base_import}}
3+
4+
class {{name}} extends {{name}}Base { }

swift/codegen/prefix.dbscheme

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ sourceLocationPrefix(
77

88
answer_to_life_the_universe_and_everything(
99
int answer: int ref
10-
)
10+
);

0 commit comments

Comments
 (0)