Files
codeql/rust/schema.py
2024-09-13 13:57:14 +02:00

578 lines
9.9 KiB
Python

"""
Schema description
This file should be kept simple:
* no flow control
* no aliases
* only class definitions with annotations and `include` calls
For how documentation of generated QL code works, please read `misc/codegen/schema_documentation.md`.
"""
from misc.codegen.lib.schemadefs import *
include("../shared/tree-sitter-extractor/src/generator/prefix.dbscheme")
include("prefix.dbscheme")
@qltest.skip
class Element:
pass
@qltest.skip
class Locatable(Element):
pass
@qltest.skip
class AstNode(Locatable):
pass
class Declaration(AstNode):
pass
class Module(Declaration):
# TODO name
declarations: list[Declaration] | child
@qltest.collapse_hierarchy
class Expr(AstNode):
pass
@qltest.collapse_hierarchy
class Pat(AstNode):
pass
@qltest.skip
class Label(AstNode):
name: string
@qltest.collapse_hierarchy
class Stmt(AstNode):
pass
@qltest.collapse_hierarchy
class TypeRef(AstNode):
# TODO
pass
class Function(Declaration):
"""
A function declaration. For example
```
fn foo(x: u32) -> u64 { (x + 1).into() }
```
A function declaration within a trait might not have a body:
```
trait Trait {
fn bar();
}
```
"""
name: string
body: Expr | child
# Missing,
class MissingExpr(Expr):
pass
# Path(Path),
class PathExpr(Expr):
path: "Unimplemented" | child
# If {
# condition: ExprId,
# then_branch: ExprId,
# else_branch: Option<ExprId>,
# },
class IfExpr(Expr):
condition: Expr | child
then: Expr | child
else_: optional[Expr] | child
# Let {
# pat: PatId,
# expr: ExprId,
# },
class LetExpr(Expr):
pat: Pat | child
expr: Expr | child
# Block {
# id: Option<BlockId>,
# statements: Box<[Stmt]>,
# tail: Option<ExprId>,
# label: Option<LabelId>,
# },
class BlockExprBase(Expr):
statements: list[Stmt] | child
tail: optional[Expr] | child
class BlockExpr(BlockExprBase):
label: optional[Label] | child
# Async {
# id: Option<BlockId>,
# statements: Box<[Stmt]>,
# tail: Option<ExprId>,
# },
class AsyncBlockExpr(BlockExprBase):
pass
# Const(ConstBlockId),
class ConstExpr(Expr):
expr: Expr | child
# // FIXME: Fold this into Block with an unsafe flag?
# Unsafe {
# id: Option<BlockId>,
# statements: Box<[Stmt]>,
# tail: Option<ExprId>,
# },
class UnsafeBlockExpr(BlockExprBase):
pass
# Loop {
# body: ExprId,
# label: Option<LabelId>,
# },
class LoopExpr(Expr):
body: Expr | child
label: optional[Label] | child
# Call {
# callee: ExprId,
# args: Box<[ExprId]>,
# is_assignee_expr: bool,
# },
class CallExpr(Expr):
callee: Expr | child
args: list[Expr] | child
is_assignee_expr: predicate
# MethodCall {
# receiver: ExprId,
# method_name: Name,
# args: Box<[ExprId]>,
# generic_args: Option<Box<GenericArgs>>,
# },
class MethodCallExpr(Expr):
receiver: Expr | child
method_name: string
args: list[Expr] | child
generic_args: optional["Unimplemented"] | child
# pub struct MatchArm {
# pub pat: PatId,
# pub guard: Option<ExprId>,
# pub expr: ExprId,
# }
@qltest.skip
class MatchArm(AstNode):
pat: Pat | child
guard: optional[Expr] | child
expr: Expr | child
# Match {
# expr: ExprId,
# arms: Box<[MatchArm]>,
# },
class MatchExpr(Expr):
expr: Expr | child
branches: list[MatchArm] | child
# Continue {
# label: Option<LabelId>,
# },
class ContinueExpr(Expr):
label: optional[Label] | child
# Break {
# expr: Option<ExprId>,
# label: Option<LabelId>,
# },
class BreakExpr(Expr):
expr: optional[Expr] | child
label: optional[Label] | child
# Return {
# expr: Option<ExprId>,
# },
class ReturnExpr(Expr):
expr: optional[Expr] | child
# Become {
# expr: ExprId,
# },
class BecomeExpr(Expr):
expr: Expr | child
# Yield {
# expr: Option<ExprId>,
# },
class YieldExpr(Expr):
expr: optional[Expr] | child
# Yeet {
# expr: Option<ExprId>,
# },
class YeetExpr(Expr):
expr: optional[Expr] | child
# RecordLit {
# path: Option<Box<Path>>,
# fields: Box<[RecordLitField]>,
# spread: Option<ExprId>,
# ellipsis: bool,
# is_assignee_expr: bool,
# },
class RecordFieldPat(AstNode):
name: string
pat: Pat | child
class RecordLitField(AstNode):
name: string
expr: Expr | child
class RecordLitExpr(Expr):
path: optional["Unimplemented"] | child
fields: list[RecordLitField] | child
spread: optional[Expr] | child
has_ellipsis: predicate
is_assignee_expr: predicate
# Field {
# expr: ExprId,
# name: Name,
# },
class FieldExpr(Expr):
expr: Expr | child
name: string
# Await {
# expr: ExprId,
# },
class AwaitExpr(Expr):
expr: Expr | child
# Cast {
# expr: ExprId,
# type_ref: Interned<TypeRef>,
# },
class CastExpr(Expr):
expr: Expr | child
type_ref: TypeRef | child
# Ref {
# expr: ExprId,
# rawness: Rawness,
# mutability: Mutability,
# },
class RefExpr(Expr):
expr: Expr | child
is_raw: predicate
is_mut: predicate
# Box {
# expr: ExprId,
# },
class BoxExpr(Expr):
expr: Expr | child
# UnaryOp {
# expr: ExprId,
# op: UnaryOp,
# },
class UnaryOpExpr(Expr):
expr: Expr | child
op: string
# BinaryOp {
# lhs: ExprId,
# rhs: ExprId,
# op: Option<BinaryOp>,
# },
class BinaryOpExpr(Expr):
lhs: Expr | child
rhs: Expr | child
op: optional[string]
# Range {
# lhs: Option<ExprId>,
# rhs: Option<ExprId>,
# range_type: RangeOp,
# },
class RangeExpr(Expr):
lhs: optional[Expr] | child
rhs: optional[Expr] | child
is_inclusive: predicate
# Index {
# base: ExprId,
# index: ExprId,
# is_assignee_expr: bool,
# },
class IndexExpr(Expr):
base: Expr | child
index: Expr | child
is_assignee_expr: predicate
# Closure {
# args: Box<[PatId]>,
# arg_types: Box<[Option<Interned<TypeRef>>]>,
# ret_type: Option<Interned<TypeRef>>,
# body: ExprId,
# closure_kind: ClosureKind,
# capture_by: CaptureBy,
# },
class ClosureExpr(Expr):
args: list[Pat] | child
arg_types: list[optional[TypeRef]] | child
ret_type: optional[TypeRef] | child
body: Expr | child
closure_kind: string
is_move: predicate
# Tuple {
# exprs: Box<[ExprId]>,
# is_assignee_expr: bool,
# },
class TupleExpr(Expr):
exprs: list[Expr] | child
is_assignee_expr: predicate
# Array(Array),
class ArrayExpr(Expr):
pass
# Literal(Literal),
# ElementList { elements: Box<[ExprId]>, is_assignee_expr: bool },
class ElementListExpr(ArrayExpr):
elements: list[Expr] | child
is_assignee_expr: predicate
# Repeat { initializer: ExprId, repeat: ExprId },
class RepeatExpr(ArrayExpr):
initializer: Expr | child
repeat: Expr | child
class LiteralExpr(Expr):
pass
# Underscore,
class UnderscoreExpr(Expr):
pass
# OffsetOf(OffsetOf),
class OffsetOfExpr(Expr):
container: TypeRef | child
fields: list[string]
# InlineAsm(InlineAsm),
class InlineAsmExpr(Expr):
expr: Expr | child
# Let {
# pat: PatId,
# type_ref: Option<Interned<TypeRef>>,
# initializer: Option<ExprId>,
# else_branch: Option<ExprId>,
# },
class LetStmt(Stmt):
pat: Pat | child
type_ref: optional[TypeRef] | child
initializer: optional[Expr] | child
else_: optional[Expr] | child
# Expr {
# expr: ExprId,
# has_semi: bool,
# },
class ExprStmt(Stmt):
expr: Expr | child
has_semicolon: predicate
# // At the moment, we only use this to figure out if a return expression
# // is really the last statement of a block. See #16566
# Item,
class ItemStmt(Stmt):
pass
# Missing,
class MissingPat(Pat):
pass
# Wild,
class WildPat(Pat):
pass
# Tuple { args: Box<[PatId]>, ellipsis: Option<u32> },
class TuplePat(Pat):
args: list[Pat] | child
ellipsis_index: optional[int]
# Or(Box<[PatId]>),
class OrPat(Pat):
args: list[Pat] | child
# Record { path: Option<Box<Path>>, args: Box<[RecordFieldPat]>, ellipsis: bool },
class RecordPat(Pat):
path: optional["Unimplemented"] | child
args: list[RecordFieldPat] | child
has_ellipsis: predicate
# Range { start: Option<Box<LiteralOrConst>>, end: Option<Box<LiteralOrConst>> },
class RangePat(Pat):
start: optional[Pat] | child
end: optional[Pat] | child
# Slice { prefix: Box<[PatId]>, slice: Option<PatId>, suffix: Box<[PatId]> },
class SlicePat(Pat):
prefix: list[Pat] | child
slice: optional[Pat] | child
suffix: list[Pat] | child
# Path(Box<Path>),
class PathPat(Pat):
path: "Unimplemented" | child
# Lit(ExprId),
class LitPat(Pat):
expr: Expr | child
# Bind { id: BindingId, subpat: Option<PatId> },
class BindPat(Pat):
binding_id: string
subpat: optional[Pat] | child
# TupleStruct { path: Option<Box<Path>>, args: Box<[PatId]>, ellipsis: Option<u32> },
class TupleStructPat(Pat):
path: optional["Unimplemented"] | child
args: list[Pat] | child
ellipsis_index: optional[int]
# Ref { pat: PatId, mutability: Mutability },
class RefPat(Pat):
pat: Pat | child
is_mut: predicate
# Box { inner: PatId },
class BoxPat(Pat):
inner: Pat | child
# ConstBlock(ExprId),
class ConstBlockPat(Pat):
expr: Expr | child
@qltest.skip
class Unimplemented(Declaration, TypeRef):
pass