mirror of
https://github.com/github/codeql.git
synced 2026-05-05 05:35:13 +02:00
Rust: archiving + skeleton def translator
This commit is contained in:
141
misc/codegen/lib/rust.py
Normal file
141
misc/codegen/lib/rust.py
Normal file
@@ -0,0 +1,141 @@
|
||||
import dataclasses
|
||||
import re
|
||||
import typing
|
||||
|
||||
# taken from https://doc.rust-lang.org/reference/keywords.html
|
||||
keywords = {
|
||||
"as",
|
||||
"break",
|
||||
"const",
|
||||
"continue",
|
||||
"crate",
|
||||
"else",
|
||||
"enum",
|
||||
"extern",
|
||||
"false",
|
||||
"fn",
|
||||
"for",
|
||||
"if",
|
||||
"impl",
|
||||
"in",
|
||||
"let",
|
||||
"loop",
|
||||
"match",
|
||||
"mod",
|
||||
"move",
|
||||
"mut",
|
||||
"pub",
|
||||
"ref",
|
||||
"return",
|
||||
"self",
|
||||
"Self",
|
||||
"static",
|
||||
"struct",
|
||||
"super",
|
||||
"trait",
|
||||
"true",
|
||||
"type",
|
||||
"unsafe",
|
||||
"use",
|
||||
"where",
|
||||
"while",
|
||||
"async",
|
||||
"await",
|
||||
"dyn",
|
||||
"abstract",
|
||||
"become",
|
||||
"box",
|
||||
"do",
|
||||
"final",
|
||||
"macro",
|
||||
"override",
|
||||
"priv",
|
||||
"typeof",
|
||||
"unsized",
|
||||
"virtual",
|
||||
"yield",
|
||||
"try",
|
||||
}
|
||||
|
||||
_field_overrides = [
|
||||
(
|
||||
re.compile(r"(start|end)_(line|column)|(.*_)?index|width|num_.*"),
|
||||
{"base_type": "usize"},
|
||||
),
|
||||
(re.compile(r"(.*)_"), lambda m: {"field_name": m[1]}),
|
||||
]
|
||||
|
||||
|
||||
def get_field_override(field: str):
|
||||
for r, o in _field_overrides:
|
||||
m = r.fullmatch(field)
|
||||
if m:
|
||||
return o(m) if callable(o) else o
|
||||
return {}
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Field:
|
||||
field_name: str
|
||||
base_type: str
|
||||
table_name: str = None
|
||||
is_optional: bool = False
|
||||
is_repeated: bool = False
|
||||
is_unordered: bool = False
|
||||
is_predicate: bool = False
|
||||
first: bool = False
|
||||
|
||||
def __post_init__(self):
|
||||
if self.field_name in keywords:
|
||||
self.field_name += "_"
|
||||
|
||||
@property
|
||||
def type(self) -> str:
|
||||
type = self.base_type
|
||||
if self.is_optional:
|
||||
type = f"Option<{type}>"
|
||||
if self.is_repeated:
|
||||
type = f"Vec<{type}>"
|
||||
return type
|
||||
|
||||
# using @property breaks pystache internals here
|
||||
def emitter(self):
|
||||
if self.type == "String":
|
||||
return lambda x: f"quoted(&{x})"
|
||||
else:
|
||||
return lambda x: x
|
||||
|
||||
@property
|
||||
def is_single(self):
|
||||
return not (self.is_optional or self.is_repeated or self.is_predicate)
|
||||
|
||||
@property
|
||||
def is_label(self):
|
||||
return self.base_type == "TrapLabel"
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Class:
|
||||
name: str
|
||||
table_name: str
|
||||
fields: list[Field] = dataclasses.field(default_factory=list)
|
||||
|
||||
@property
|
||||
def single_fields(self):
|
||||
return [f for f in self.fields if f.is_single]
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ClassList:
|
||||
template: typing.ClassVar[str] = "rust_classes"
|
||||
|
||||
classes: list[Class]
|
||||
source: str
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ModuleList:
|
||||
template: typing.ClassVar[str] = "rust_module"
|
||||
|
||||
modules: list[str]
|
||||
source: str
|
||||
Reference in New Issue
Block a user