Skip to content

Commit

Permalink
Merge pull request #18094 from github/redsun82/rust-rename
Browse files Browse the repository at this point in the history
Codegen/Rust: allow renaming in QL
  • Loading branch information
redsun82 authored Nov 25, 2024
2 parents 8fd581d + 269ea75 commit 74aa47a
Show file tree
Hide file tree
Showing 15 changed files with 62 additions and 59 deletions.
13 changes: 8 additions & 5 deletions misc/codegen/generators/qlgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,32 +118,33 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dic
type_is_hideable="ql_hideable" in lookup[prop.type].pragmas if prop.type in lookup else False,
internal="ql_internal" in prop.pragmas,
)
ql_name = prop.pragmas.get("ql_name", prop.name)
if prop.is_single:
args.update(
singular=inflection.camelize(prop.name),
singular=inflection.camelize(ql_name),
tablename=inflection.tableize(cls.name),
tableparams=["this"] + ["result" if p is prop else "_" for p in cls.properties if p.is_single],
doc=_get_doc(cls, prop),
)
elif prop.is_repeated:
args.update(
singular=inflection.singularize(inflection.camelize(prop.name)),
plural=inflection.pluralize(inflection.camelize(prop.name)),
singular=inflection.singularize(inflection.camelize(ql_name)),
plural=inflection.pluralize(inflection.camelize(ql_name)),
tablename=inflection.tableize(f"{cls.name}_{prop.name}"),
tableparams=["this", "index", "result"] if not prop.is_unordered else ["this", "result"],
doc=_get_doc(cls, prop, plural=False),
doc_plural=_get_doc(cls, prop, plural=True),
)
elif prop.is_optional:
args.update(
singular=inflection.camelize(prop.name),
singular=inflection.camelize(ql_name),
tablename=inflection.tableize(f"{cls.name}_{prop.name}"),
tableparams=["this", "result"],
doc=_get_doc(cls, prop),
)
elif prop.is_predicate:
args.update(
singular=inflection.camelize(prop.name, uppercase_first_letter=False),
singular=inflection.camelize(ql_name, uppercase_first_letter=False),
tablename=inflection.underscore(f"{cls.name}_{prop.name}"),
tableparams=["this"],
doc=_get_doc(cls, prop),
Expand All @@ -154,6 +155,8 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dic


def get_ql_class(cls: schema.Class, lookup: typing.Dict[str, schema.Class]) -> ql.Class:
if "ql_name" in cls.pragmas:
raise Error("ql_name is not supported yet for classes, only for properties")
prev_child = ""
properties = []
for p in cls.properties:
Expand Down
27 changes: 11 additions & 16 deletions misc/codegen/lib/schemadefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ def include(source: str):
@_dataclass
class _Namespace:
""" simple namespacing mechanism """
name: str
_name: str

def add(self, pragma: "_PragmaBase", key: str | None = None):
self.__dict__[pragma.pragma] = pragma
pragma.pragma = key or f"{self.name}_{pragma.pragma}"
pragma.pragma = key or f"{self._name}_{pragma.pragma}"


@_dataclass
Expand All @@ -87,7 +87,7 @@ def modify(self, prop: _schema.Property):
prop.synth = self.synth

def negate(self) -> _schema.PropertyModifier:
return _SynthModifier(self.name, False)
return _SynthModifier(self._name, False)


qltest = _Namespace("qltest")
Expand Down Expand Up @@ -239,6 +239,7 @@ def __getitem__(self, item):
ql.add(_ParametrizedClassPragma("default_doc_name", factory=lambda doc: doc))
ql.add(_ClassPragma("hideable", inherited=True))
ql.add(_Pragma("internal"))
ql.add(_ParametrizedPragma("name", factory=lambda name: name))

cpp.add(_Pragma("skip"))

Expand All @@ -256,38 +257,32 @@ def __getitem__(self, item):
_schema.SynthInfo(on_arguments={k: _schema.get_type_name(t) for k, t in kwargs.items()})), key="synth")


@_dataclass(frozen=True)
class _PropertyModifierList(_schema.PropertyModifier):
def __init__(self):
self._mods = []
_mods: tuple[_schema.PropertyModifier, ...]

def __or__(self, other: _schema.PropertyModifier):
self._mods.append(other)
return self
return _PropertyModifierList(self._mods + (other,))

def modify(self, prop: Property):
for m in self._mods:
m.modify(prop)


class _PropertyAnnotation:
def __or__(self, other: _schema.PropertyModifier):
return _PropertyModifierList() | other


_ = _PropertyAnnotation()
_ = _PropertyModifierList(())

drop = object()


def annotate(annotated_cls: type, add_bases: _Iterable[type] | None = None, replace_bases: _Dict[type, type] | None = None, cfg: bool = False) -> _Callable[[type], _PropertyAnnotation]:
def annotate(annotated_cls: type, add_bases: _Iterable[type] | None = None, replace_bases: _Dict[type, type] | None = None, cfg: bool = False) -> _Callable[[type], _PropertyModifierList]:
"""
Add or modify schema annotations after a class has been defined previously.
The name of the class used for annotation must be `_`.
`replace_bases` can be used to replace bases on the annotated class.
"""
def decorator(cls: type) -> _PropertyAnnotation:
def decorator(cls: type) -> _PropertyModifierList:
if cls.__name__ != "_":
raise _schema.Error("Annotation classes must be named _")
if cls.__doc__ is not None:
Expand All @@ -307,7 +302,7 @@ def decorator(cls: type) -> _PropertyAnnotation:
del annotated_cls.__annotations__[p]
elif p in annotated_cls.__annotations__:
annotated_cls.__annotations__[p] |= a
elif isinstance(a, (_PropertyAnnotation, _PropertyModifierList)):
elif isinstance(a, (_PropertyModifierList, _PropertyModifierList)):
raise _schema.Error(f"annotated property {p} not present in annotated class "
f"{annotated_cls.__name__}")
else:
Expand Down
12 changes: 6 additions & 6 deletions rust/ql/.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/ql/.gitattributes

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

Original file line number Diff line number Diff line change
Expand Up @@ -514,14 +514,14 @@ module ExprTrees {

class MatchExprTree extends PostOrderTree instanceof MatchExpr {
override predicate propagatesAbnormal(AstNode child) {
child = [super.getExpr(), super.getAnArm().getExpr()]
child = [super.getScrutinee(), super.getAnArm().getExpr()]
}

override predicate first(AstNode node) { first(super.getExpr(), node) }
override predicate first(AstNode node) { first(super.getScrutinee(), node) }

override predicate succ(AstNode pred, AstNode succ, Completion c) {
// Edge from the scrutinee to the first arm or to the match expression if no arms.
last(super.getExpr(), pred, c) and
last(super.getScrutinee(), pred, c) and
(
first(super.getArm(0).getPat(), succ)
or
Expand Down

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

Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ module Impl {
*/
class MatchExpr extends Generated::MatchExpr {
override string toString() {
result = "match " + this.getExpr().toAbbreviatedString() + " { ... }"
result = "match " + this.getScrutinee().toAbbreviatedString() + " { ... }"
}

/**
Expand Down

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

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

4 changes: 2 additions & 2 deletions rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll

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

Loading

0 comments on commit 74aa47a

Please sign in to comment.