Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
hvitved committed Sep 12, 2024
1 parent 076dd07 commit 0419a49
Show file tree
Hide file tree
Showing 264 changed files with 2,058 additions and 851 deletions.
41 changes: 33 additions & 8 deletions misc/codegen/generators/qlgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ def get_ql_class(cls: schema.Class, lookup: typing.Dict[str, schema.Class]) -> q
properties.append(prop)
return ql.Class(
name=cls.name,
bases=cls.bases,
bases=[c for c in cls.bases],
# bases2=[base + "_Gen::" + base + "Impl" for base in cls.bases],
bases2=[base + "Impl" for base in cls.bases],
final=not cls.derived,
properties=properties,
dir=pathlib.Path(cls.group or ""),
Expand Down Expand Up @@ -207,18 +209,23 @@ def get_ql_synth_class(cls: schema.Class):

def get_import(file: pathlib.Path, root_dir: pathlib.Path):
stem = file.relative_to(root_dir / "ql/lib").with_suffix("")
return str(stem).replace("/", ".")
res = str(stem).replace("/", ".")
# if ".elements." in res:
# return res.replace("elements","generated") + "::Generated"
return res


def get_types_used_by(cls: ql.Class) -> typing.Iterable[str]:
for b in cls.bases:
yield b.base
yield b.base + "Impl"
for p in cls.properties:
yield p.type
if cls.root:
yield cls.name # used in `getResolveStep` and `resolve`


def get_classes_used_by(cls: ql.Class) -> typing.List[str]:
return sorted(set(t for t in get_types_used_by(cls) if t[0].isupper() and t != cls.name))
return sorted(set(t for t in get_types_used_by(cls) if t[0].isupper()))


def format(codeql, files):
Expand All @@ -236,6 +243,10 @@ def format(codeql, files):


def _get_path(cls: schema.Class) -> pathlib.Path:
return pathlib.Path(cls.group or "", cls.name+"Impl").with_suffix(".qll")


def _get_path2(cls: schema.Class) -> pathlib.Path:
return pathlib.Path(cls.group or "", cls.name).with_suffix(".qll")


Expand Down Expand Up @@ -315,7 +326,11 @@ def _get_stub(cls: schema.Class, base_import: str, generated_import_prefix: str)
else:
accessors = []
return ql.Stub(name=cls.name, base_import=base_import, import_prefix=generated_import_prefix,
doc=cls.doc, synth_accessors=accessors,
doc=cls.doc, synth_accessors=accessors)

def _get_stub2(cls: schema.Class, base_import: str, generated_import_prefix: str) -> ql.StubFinal:
return ql.StubFinal(name=cls.name, base_import=base_import, import_prefix=generated_import_prefix,
doc=cls.doc,
internal="ql_internal" in cls.pragmas)


Expand Down Expand Up @@ -370,6 +385,7 @@ def generate(opts, renderer):
raise RootElementHasChildren(root)

imports = {}
imports_impl = {}
generated_import_prefix = get_import(out, opts.root_dir)
registry = opts.generated_registry or pathlib.Path(
os.path.commonpath((out, stub_out, test_out)), ".generated.list")
Expand All @@ -382,24 +398,33 @@ def generate(opts, renderer):

classes_by_dir_and_name = sorted(classes.values(), key=lambda cls: (cls.dir, cls.name))
for c in classes_by_dir_and_name:
imports[c.name] = get_import(stub_out / c.path, opts.root_dir)
path = get_import(stub_out / c.path, opts.root_dir)
imports[c.name] = path
imports_impl[c.name + "Impl"] = path + "Impl"

for c in classes.values():
qll = out / c.path.with_suffix(".qll")
c.imports = [imports[t] for t in get_classes_used_by(c)]
c.imports = [
imports[t] if t in imports else imports_impl[t] for t in get_classes_used_by(c)
]
c.import_prefix = generated_import_prefix
renderer.render(c, qll)

for c in data.classes.values():
path = _get_path(c)
path2 = _get_path2(c)
stub_file = stub_out / path
base_import = get_import(out / path, opts.root_dir)
base_import = get_import(out / path2, opts.root_dir)
stub = _get_stub(c, base_import, generated_import_prefix)

if not renderer.is_customized_stub(stub_file):
renderer.render(stub, stub_file)
else:
qldoc = renderer.render_str(stub, template='ql_stub_class_qldoc')
_patch_class_qldoc(c.name, qldoc, stub_file)
stub2 = _get_stub2(c, base_import, generated_import_prefix)
stub_file2 = stub_out / path2
renderer.render(stub2, stub_file2)

# for example path/to/elements -> path/to/elements.qll
renderer.render(ql.ImportList([i for name, i in imports.items() if not classes[name].internal]),
Expand Down
17 changes: 16 additions & 1 deletion misc/codegen/lib/ql.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class Class:

name: str
bases: List[Base] = field(default_factory=list)
bases2: List[Base] = field(default_factory=list)
final: bool = False
properties: List[Property] = field(default_factory=list)
dir: pathlib.Path = pathlib.Path()
Expand All @@ -115,6 +116,7 @@ class Class:

def __post_init__(self):
self.bases = [Base(str(b), str(prev)) for b, prev in zip(self.bases, itertools.chain([""], self.bases))]
self.bases2 = [Base(str(b), str(prev)) for b, prev in zip(self.bases2, itertools.chain([""], self.bases2))]
if self.properties:
self.properties[0].first = True

Expand Down Expand Up @@ -159,13 +161,26 @@ class Stub:
base_import: str
import_prefix: str
synth_accessors: List[SynthUnderlyingAccessor] = field(default_factory=list)
internal: bool = False
doc: List[str] = field(default_factory=list)

@property
def has_synth_accessors(self) -> bool:
return bool(self.synth_accessors)

@property
def has_qldoc(self) -> bool:
return bool(self.doc)

@dataclass
class StubFinal:
template: ClassVar = 'ql_stub_final'

name: str
base_import: str
import_prefix: str
internal: bool = False
doc: List[str] = field(default_factory=list)

@property
def has_qldoc(self) -> bool:
return bool(self.doc) or self.internal
Expand Down
2 changes: 1 addition & 1 deletion misc/codegen/templates/dbscheme.mustache
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// generated by {{generator}}
// generated by {{generator}}, do not edit
{{#includes}}

// from {{src}}
Expand Down
6 changes: 3 additions & 3 deletions misc/codegen/templates/ql_class.mustache
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// generated by {{generator}}
// generated by {{generator}}, do not edit
/**
* This module provides the generated definition of `{{name}}`.
* INTERNAL: Do not import directly.
Expand All @@ -19,10 +19,10 @@ module Generated {
{{#doc}}
* {{.}}
{{/doc}}
* INTERNAL: Do not reference the `Generated::{{name}}` class directly.
* INTERNAL: Do not reference the `Generated::{{name}}Impl` class directly.
* Use the subclass `{{name}}`, where the following predicates are available.
*/
class {{name}} extends Synth::T{{name}}{{#bases}}, {{.}}{{/bases}} {
class {{name}}Impl extends Synth::T{{name}}{{#bases2}}, {{.}}{{/bases2}} {
{{#root}}
/**
* Gets the string representation of this element.
Expand Down
2 changes: 1 addition & 1 deletion misc/codegen/templates/ql_imports.mustache
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// generated by {{generator}}
// generated by {{generator}}, do not edit
/**
* This module exports all modules providing `Element` subclasses.
*/
Expand Down
2 changes: 1 addition & 1 deletion misc/codegen/templates/ql_parent.mustache
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// generated by {{generator}}
// generated by {{generator}}, do not edit
/**
* This module provides the generated parent/child relationship.
*/
Expand Down
2 changes: 1 addition & 1 deletion misc/codegen/templates/ql_stub.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ private import {{import_prefix}}.Synth
{{/has_synth_accessors}}

{{>ql_stub_class_qldoc}}
class {{name}} extends Generated::{{name}} {
class {{name}}Impl extends Generated::{{name}}Impl {
{{#synth_accessors}}
private
cached {{type}} getUnderlying{{argument}}() { this = Synth::T{{name}}({{#constructorparams}}{{^first}},{{/first}}{{param}}{{/constructorparams}})}
Expand Down
3 changes: 1 addition & 2 deletions misc/codegen/templates/ql_stub_module_qldoc.mustache
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/**
* This module provides a hand-modifiable wrapper around the generated class `{{name}}`.
{{#internal}}
*
* INTERNAL: Do not use.
{{/internal}}
*/
2 changes: 1 addition & 1 deletion misc/codegen/templates/ql_test_class.mustache
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// generated by {{generator}}
// generated by {{generator}}, do not edit

import {{elements_module}}
import TestUtils
Expand Down
2 changes: 1 addition & 1 deletion misc/codegen/templates/ql_test_missing.mustache
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// generated by {{generator}}
// generated by {{generator}}, do not edit

After a source file is added in this directory and {{generator}} is run again, test queries
will appear and this file will be deleted
2 changes: 1 addition & 1 deletion misc/codegen/templates/ql_test_property.mustache
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// generated by {{generator}}
// generated by {{generator}}, do not edit

import {{elements_module}}
import TestUtils
Expand Down
2 changes: 1 addition & 1 deletion misc/codegen/templates/rust_classes.mustache
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// generated by {{generator}}
// generated by {{generator}}, do not edit

#![cfg_attr(any(), rustfmt::skip)]

Expand Down
2 changes: 1 addition & 1 deletion misc/codegen/templates/rust_module.mustache
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// generated by {{generator}}
// generated by {{generator}}, do not edit
{{#modules}}

mod {{.}};
Expand Down
2 changes: 1 addition & 1 deletion misc/codegen/templates/rust_test_code.mustache
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// generated by {{generator}}
// generated by {{generator}}, do not edit

{{#function}}
fn {{name}}{{signature}} {
Expand Down
2 changes: 1 addition & 1 deletion rust/codegen.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# configuration file for Swift code generation default options
# configuration file for Rust code generation default options
--generate=dbscheme,rusttest,ql,rust
--dbscheme=ql/lib/rust.dbscheme
--ql-output=ql/lib/codeql/rust/generated
Expand Down
4 changes: 2 additions & 2 deletions rust/extractor/src/generated/.generated.list

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rust/extractor/src/generated/mod.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rust/extractor/src/generated/top.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 0419a49

Please sign in to comment.