mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 11:59:10 +00:00
3333 lines
84 KiB
Rust
3333 lines
84 KiB
Rust
#![allow(clippy::derive_partial_eq_without_eq)]
|
|
|
|
use std::fmt;
|
|
use std::fmt::Debug;
|
|
use std::ops::Deref;
|
|
|
|
use num_bigint::BigInt;
|
|
|
|
use ruff_text_size::{Ranged, TextRange, TextSize};
|
|
|
|
/// See also [mod](https://docs.python.org/3/library/ast.html#ast.mod)
|
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
|
pub enum Mod {
|
|
Module(ModModule),
|
|
Expression(ModExpression),
|
|
}
|
|
|
|
/// See also [Module](https://docs.python.org/3/library/ast.html#ast.Module)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ModModule {
|
|
pub range: TextRange,
|
|
pub body: Vec<Stmt>,
|
|
}
|
|
|
|
impl From<ModModule> for Mod {
|
|
fn from(payload: ModModule) -> Self {
|
|
Mod::Module(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Expression](https://docs.python.org/3/library/ast.html#ast.Expression)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ModExpression {
|
|
pub range: TextRange,
|
|
pub body: Box<Expr>,
|
|
}
|
|
|
|
impl From<ModExpression> for Mod {
|
|
fn from(payload: ModExpression) -> Self {
|
|
Mod::Expression(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [stmt](https://docs.python.org/3/library/ast.html#ast.stmt)
|
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
|
pub enum Stmt {
|
|
#[is(name = "function_def_stmt")]
|
|
FunctionDef(StmtFunctionDef),
|
|
#[is(name = "class_def_stmt")]
|
|
ClassDef(StmtClassDef),
|
|
#[is(name = "return_stmt")]
|
|
Return(StmtReturn),
|
|
#[is(name = "delete_stmt")]
|
|
Delete(StmtDelete),
|
|
#[is(name = "assign_stmt")]
|
|
Assign(StmtAssign),
|
|
#[is(name = "aug_assign_stmt")]
|
|
AugAssign(StmtAugAssign),
|
|
#[is(name = "ann_assign_stmt")]
|
|
AnnAssign(StmtAnnAssign),
|
|
#[is(name = "type_alias_stmt")]
|
|
TypeAlias(StmtTypeAlias),
|
|
#[is(name = "for_stmt")]
|
|
For(StmtFor),
|
|
#[is(name = "while_stmt")]
|
|
While(StmtWhile),
|
|
#[is(name = "if_stmt")]
|
|
If(StmtIf),
|
|
#[is(name = "with_stmt")]
|
|
With(StmtWith),
|
|
#[is(name = "match_stmt")]
|
|
Match(StmtMatch),
|
|
#[is(name = "raise_stmt")]
|
|
Raise(StmtRaise),
|
|
#[is(name = "try_stmt")]
|
|
Try(StmtTry),
|
|
#[is(name = "assert_stmt")]
|
|
Assert(StmtAssert),
|
|
#[is(name = "import_stmt")]
|
|
Import(StmtImport),
|
|
#[is(name = "import_from_stmt")]
|
|
ImportFrom(StmtImportFrom),
|
|
#[is(name = "global_stmt")]
|
|
Global(StmtGlobal),
|
|
#[is(name = "nonlocal_stmt")]
|
|
Nonlocal(StmtNonlocal),
|
|
#[is(name = "expr_stmt")]
|
|
Expr(StmtExpr),
|
|
#[is(name = "pass_stmt")]
|
|
Pass(StmtPass),
|
|
#[is(name = "break_stmt")]
|
|
Break(StmtBreak),
|
|
#[is(name = "continue_stmt")]
|
|
Continue(StmtContinue),
|
|
|
|
// Jupyter notebook specific
|
|
#[is(name = "ipy_escape_command_stmt")]
|
|
IpyEscapeCommand(StmtIpyEscapeCommand),
|
|
}
|
|
|
|
/// An AST node used to represent a IPython escape command at the statement level.
|
|
///
|
|
/// For example,
|
|
/// ```python
|
|
/// %matplotlib inline
|
|
/// ```
|
|
///
|
|
/// ## Terminology
|
|
///
|
|
/// Escape commands are special IPython syntax which starts with a token to identify
|
|
/// the escape kind followed by the command value itself. [Escape kind] are the kind
|
|
/// of escape commands that are recognized by the token: `%`, `%%`, `!`, `!!`,
|
|
/// `?`, `??`, `/`, `;`, and `,`.
|
|
///
|
|
/// Help command (or Dynamic Object Introspection as it's called) are the escape commands
|
|
/// of the kind `?` and `??`. For example, `?str.replace`. Help end command are a subset
|
|
/// of Help command where the token can be at the end of the line i.e., after the value.
|
|
/// For example, `str.replace?`.
|
|
///
|
|
/// Here's where things get tricky. I'll divide the help end command into two types for
|
|
/// better understanding:
|
|
/// 1. Strict version: The token is _only_ at the end of the line. For example,
|
|
/// `str.replace?` or `str.replace??`.
|
|
/// 2. Combined version: Along with the `?` or `??` token, which are at the end of the
|
|
/// line, there are other escape kind tokens that are present at the start as well.
|
|
/// For example, `%matplotlib?` or `%%timeit?`.
|
|
///
|
|
/// Priority comes into picture for the "Combined version" mentioned above. How do
|
|
/// we determine the escape kind if there are tokens on both side of the value, i.e., which
|
|
/// token to choose? The Help end command always takes priority over any other token which
|
|
/// means that if there is `?`/`??` at the end then that is used to determine the kind.
|
|
/// For example, in `%matplotlib?` the escape kind is determined using the `?` token
|
|
/// instead of `%` token.
|
|
///
|
|
/// ## Syntax
|
|
///
|
|
/// `<IpyEscapeKind><Command value>`
|
|
///
|
|
/// The simplest form is an escape kind token followed by the command value. For example,
|
|
/// `%matplotlib inline`, `/foo`, `!pwd`, etc.
|
|
///
|
|
/// `<Command value><IpyEscapeKind ("?" or "??")>`
|
|
///
|
|
/// The help end escape command would be the reverse of the above syntax. Here, the
|
|
/// escape kind token can only be either `?` or `??` and it is at the end of the line.
|
|
/// For example, `str.replace?`, `math.pi??`, etc.
|
|
///
|
|
/// `<IpyEscapeKind><Command value><EscapeKind ("?" or "??")>`
|
|
///
|
|
/// The final syntax is the combined version of the above two. For example, `%matplotlib?`,
|
|
/// `%%timeit??`, etc.
|
|
///
|
|
/// [Escape kind]: IpyEscapeKind
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtIpyEscapeCommand {
|
|
pub range: TextRange,
|
|
pub kind: IpyEscapeKind,
|
|
pub value: String,
|
|
}
|
|
|
|
impl From<StmtIpyEscapeCommand> for Stmt {
|
|
fn from(payload: StmtIpyEscapeCommand) -> Self {
|
|
Stmt::IpyEscapeCommand(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [FunctionDef](https://docs.python.org/3/library/ast.html#ast.FunctionDef) and
|
|
/// [AsyncFunctionDef](https://docs.python.org/3/library/ast.html#ast.AsyncFunctionDef).
|
|
///
|
|
/// This type differs from the original Python AST, as it collapses the
|
|
/// synchronous and asynchronous variants into a single type.
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtFunctionDef {
|
|
pub range: TextRange,
|
|
pub is_async: bool,
|
|
pub decorator_list: Vec<Decorator>,
|
|
pub name: Identifier,
|
|
pub type_params: Option<TypeParams>,
|
|
pub parameters: Box<Parameters>,
|
|
pub returns: Option<Box<Expr>>,
|
|
pub body: Vec<Stmt>,
|
|
}
|
|
|
|
impl From<StmtFunctionDef> for Stmt {
|
|
fn from(payload: StmtFunctionDef) -> Self {
|
|
Stmt::FunctionDef(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [ClassDef](https://docs.python.org/3/library/ast.html#ast.ClassDef)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtClassDef {
|
|
pub range: TextRange,
|
|
pub decorator_list: Vec<Decorator>,
|
|
pub name: Identifier,
|
|
pub type_params: Option<Box<TypeParams>>,
|
|
pub arguments: Option<Box<Arguments>>,
|
|
pub body: Vec<Stmt>,
|
|
}
|
|
|
|
impl StmtClassDef {
|
|
/// Return an iterator over the bases of the class.
|
|
pub fn bases(&self) -> &[Expr] {
|
|
match &self.arguments {
|
|
Some(arguments) => &arguments.args,
|
|
None => &[],
|
|
}
|
|
}
|
|
|
|
/// Return an iterator over the metaclass keywords of the class.
|
|
pub fn keywords(&self) -> &[Keyword] {
|
|
match &self.arguments {
|
|
Some(arguments) => &arguments.keywords,
|
|
None => &[],
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<StmtClassDef> for Stmt {
|
|
fn from(payload: StmtClassDef) -> Self {
|
|
Stmt::ClassDef(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Return](https://docs.python.org/3/library/ast.html#ast.Return)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtReturn {
|
|
pub range: TextRange,
|
|
pub value: Option<Box<Expr>>,
|
|
}
|
|
|
|
impl From<StmtReturn> for Stmt {
|
|
fn from(payload: StmtReturn) -> Self {
|
|
Stmt::Return(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Delete](https://docs.python.org/3/library/ast.html#ast.Delete)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtDelete {
|
|
pub range: TextRange,
|
|
pub targets: Vec<Expr>,
|
|
}
|
|
|
|
impl From<StmtDelete> for Stmt {
|
|
fn from(payload: StmtDelete) -> Self {
|
|
Stmt::Delete(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [TypeAlias](https://docs.python.org/3/library/ast.html#ast.TypeAlias)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtTypeAlias {
|
|
pub range: TextRange,
|
|
pub name: Box<Expr>,
|
|
pub type_params: Option<TypeParams>,
|
|
pub value: Box<Expr>,
|
|
}
|
|
|
|
impl From<StmtTypeAlias> for Stmt {
|
|
fn from(payload: StmtTypeAlias) -> Self {
|
|
Stmt::TypeAlias(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Assign](https://docs.python.org/3/library/ast.html#ast.Assign)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtAssign {
|
|
pub range: TextRange,
|
|
pub targets: Vec<Expr>,
|
|
pub value: Box<Expr>,
|
|
}
|
|
|
|
impl From<StmtAssign> for Stmt {
|
|
fn from(payload: StmtAssign) -> Self {
|
|
Stmt::Assign(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [AugAssign](https://docs.python.org/3/library/ast.html#ast.AugAssign)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtAugAssign {
|
|
pub range: TextRange,
|
|
pub target: Box<Expr>,
|
|
pub op: Operator,
|
|
pub value: Box<Expr>,
|
|
}
|
|
|
|
impl From<StmtAugAssign> for Stmt {
|
|
fn from(payload: StmtAugAssign) -> Self {
|
|
Stmt::AugAssign(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [AnnAssign](https://docs.python.org/3/library/ast.html#ast.AnnAssign)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtAnnAssign {
|
|
pub range: TextRange,
|
|
pub target: Box<Expr>,
|
|
pub annotation: Box<Expr>,
|
|
pub value: Option<Box<Expr>>,
|
|
pub simple: bool,
|
|
}
|
|
|
|
impl From<StmtAnnAssign> for Stmt {
|
|
fn from(payload: StmtAnnAssign) -> Self {
|
|
Stmt::AnnAssign(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [For](https://docs.python.org/3/library/ast.html#ast.For) and
|
|
/// [AsyncFor](https://docs.python.org/3/library/ast.html#ast.AsyncFor).
|
|
///
|
|
/// This type differs from the original Python AST, as it collapses the
|
|
/// synchronous and asynchronous variants into a single type.
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtFor {
|
|
pub range: TextRange,
|
|
pub is_async: bool,
|
|
pub target: Box<Expr>,
|
|
pub iter: Box<Expr>,
|
|
pub body: Vec<Stmt>,
|
|
pub orelse: Vec<Stmt>,
|
|
}
|
|
|
|
impl From<StmtFor> for Stmt {
|
|
fn from(payload: StmtFor) -> Self {
|
|
Stmt::For(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [While](https://docs.python.org/3/library/ast.html#ast.While) and
|
|
/// [AsyncWhile](https://docs.python.org/3/library/ast.html#ast.AsyncWhile).
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtWhile {
|
|
pub range: TextRange,
|
|
pub test: Box<Expr>,
|
|
pub body: Vec<Stmt>,
|
|
pub orelse: Vec<Stmt>,
|
|
}
|
|
|
|
impl From<StmtWhile> for Stmt {
|
|
fn from(payload: StmtWhile) -> Self {
|
|
Stmt::While(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [If](https://docs.python.org/3/library/ast.html#ast.If)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtIf {
|
|
pub range: TextRange,
|
|
pub test: Box<Expr>,
|
|
pub body: Vec<Stmt>,
|
|
pub elif_else_clauses: Vec<ElifElseClause>,
|
|
}
|
|
|
|
impl From<StmtIf> for Stmt {
|
|
fn from(payload: StmtIf) -> Self {
|
|
Stmt::If(payload)
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ElifElseClause {
|
|
pub range: TextRange,
|
|
pub test: Option<Expr>,
|
|
pub body: Vec<Stmt>,
|
|
}
|
|
|
|
/// See also [With](https://docs.python.org/3/library/ast.html#ast.With) and
|
|
/// [AsyncWith](https://docs.python.org/3/library/ast.html#ast.AsyncWith).
|
|
///
|
|
/// This type differs from the original Python AST, as it collapses the
|
|
/// synchronous and asynchronous variants into a single type.
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtWith {
|
|
pub range: TextRange,
|
|
pub is_async: bool,
|
|
pub items: Vec<WithItem>,
|
|
pub body: Vec<Stmt>,
|
|
}
|
|
|
|
impl From<StmtWith> for Stmt {
|
|
fn from(payload: StmtWith) -> Self {
|
|
Stmt::With(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Match](https://docs.python.org/3/library/ast.html#ast.Match)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtMatch {
|
|
pub range: TextRange,
|
|
pub subject: Box<Expr>,
|
|
pub cases: Vec<MatchCase>,
|
|
}
|
|
|
|
impl From<StmtMatch> for Stmt {
|
|
fn from(payload: StmtMatch) -> Self {
|
|
Stmt::Match(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Raise](https://docs.python.org/3/library/ast.html#ast.Raise)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtRaise {
|
|
pub range: TextRange,
|
|
pub exc: Option<Box<Expr>>,
|
|
pub cause: Option<Box<Expr>>,
|
|
}
|
|
|
|
impl From<StmtRaise> for Stmt {
|
|
fn from(payload: StmtRaise) -> Self {
|
|
Stmt::Raise(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Try](https://docs.python.org/3/library/ast.html#ast.Try) and
|
|
/// [TryStar](https://docs.python.org/3/library/ast.html#ast.TryStar)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtTry {
|
|
pub range: TextRange,
|
|
pub body: Vec<Stmt>,
|
|
pub handlers: Vec<ExceptHandler>,
|
|
pub orelse: Vec<Stmt>,
|
|
pub finalbody: Vec<Stmt>,
|
|
pub is_star: bool,
|
|
}
|
|
|
|
impl From<StmtTry> for Stmt {
|
|
fn from(payload: StmtTry) -> Self {
|
|
Stmt::Try(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Assert](https://docs.python.org/3/library/ast.html#ast.Assert)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtAssert {
|
|
pub range: TextRange,
|
|
pub test: Box<Expr>,
|
|
pub msg: Option<Box<Expr>>,
|
|
}
|
|
|
|
impl From<StmtAssert> for Stmt {
|
|
fn from(payload: StmtAssert) -> Self {
|
|
Stmt::Assert(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Import](https://docs.python.org/3/library/ast.html#ast.Import)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtImport {
|
|
pub range: TextRange,
|
|
pub names: Vec<Alias>,
|
|
}
|
|
|
|
impl From<StmtImport> for Stmt {
|
|
fn from(payload: StmtImport) -> Self {
|
|
Stmt::Import(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [ImportFrom](https://docs.python.org/3/library/ast.html#ast.ImportFrom)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtImportFrom {
|
|
pub range: TextRange,
|
|
pub module: Option<Identifier>,
|
|
pub names: Vec<Alias>,
|
|
pub level: Option<Int>,
|
|
}
|
|
|
|
impl From<StmtImportFrom> for Stmt {
|
|
fn from(payload: StmtImportFrom) -> Self {
|
|
Stmt::ImportFrom(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Global](https://docs.python.org/3/library/ast.html#ast.Global)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtGlobal {
|
|
pub range: TextRange,
|
|
pub names: Vec<Identifier>,
|
|
}
|
|
|
|
impl From<StmtGlobal> for Stmt {
|
|
fn from(payload: StmtGlobal) -> Self {
|
|
Stmt::Global(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Nonlocal](https://docs.python.org/3/library/ast.html#ast.Nonlocal)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtNonlocal {
|
|
pub range: TextRange,
|
|
pub names: Vec<Identifier>,
|
|
}
|
|
|
|
impl From<StmtNonlocal> for Stmt {
|
|
fn from(payload: StmtNonlocal) -> Self {
|
|
Stmt::Nonlocal(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Expr](https://docs.python.org/3/library/ast.html#ast.Expr)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtExpr {
|
|
pub range: TextRange,
|
|
pub value: Box<Expr>,
|
|
}
|
|
|
|
impl From<StmtExpr> for Stmt {
|
|
fn from(payload: StmtExpr) -> Self {
|
|
Stmt::Expr(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Pass](https://docs.python.org/3/library/ast.html#ast.Pass)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtPass {
|
|
pub range: TextRange,
|
|
}
|
|
|
|
impl From<StmtPass> for Stmt {
|
|
fn from(payload: StmtPass) -> Self {
|
|
Stmt::Pass(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Break](https://docs.python.org/3/library/ast.html#ast.Break)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtBreak {
|
|
pub range: TextRange,
|
|
}
|
|
|
|
impl From<StmtBreak> for Stmt {
|
|
fn from(payload: StmtBreak) -> Self {
|
|
Stmt::Break(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Continue](https://docs.python.org/3/library/ast.html#ast.Continue)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct StmtContinue {
|
|
pub range: TextRange,
|
|
}
|
|
|
|
impl From<StmtContinue> for Stmt {
|
|
fn from(payload: StmtContinue) -> Self {
|
|
Stmt::Continue(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [expr](https://docs.python.org/3/library/ast.html#ast.expr)
|
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
|
pub enum Expr {
|
|
#[is(name = "bool_op_expr")]
|
|
BoolOp(ExprBoolOp),
|
|
#[is(name = "named_expr_expr")]
|
|
NamedExpr(ExprNamedExpr),
|
|
#[is(name = "bin_op_expr")]
|
|
BinOp(ExprBinOp),
|
|
#[is(name = "unary_op_expr")]
|
|
UnaryOp(ExprUnaryOp),
|
|
#[is(name = "lambda_expr")]
|
|
Lambda(ExprLambda),
|
|
#[is(name = "if_exp_expr")]
|
|
IfExp(ExprIfExp),
|
|
#[is(name = "dict_expr")]
|
|
Dict(ExprDict),
|
|
#[is(name = "set_expr")]
|
|
Set(ExprSet),
|
|
#[is(name = "list_comp_expr")]
|
|
ListComp(ExprListComp),
|
|
#[is(name = "set_comp_expr")]
|
|
SetComp(ExprSetComp),
|
|
#[is(name = "dict_comp_expr")]
|
|
DictComp(ExprDictComp),
|
|
#[is(name = "generator_exp_expr")]
|
|
GeneratorExp(ExprGeneratorExp),
|
|
#[is(name = "await_expr")]
|
|
Await(ExprAwait),
|
|
#[is(name = "yield_expr")]
|
|
Yield(ExprYield),
|
|
#[is(name = "yield_from_expr")]
|
|
YieldFrom(ExprYieldFrom),
|
|
#[is(name = "compare_expr")]
|
|
Compare(ExprCompare),
|
|
#[is(name = "call_expr")]
|
|
Call(ExprCall),
|
|
#[is(name = "formatted_value_expr")]
|
|
FormattedValue(ExprFormattedValue),
|
|
#[is(name = "f_string_expr")]
|
|
FString(ExprFString),
|
|
#[is(name = "constant_expr")]
|
|
Constant(ExprConstant),
|
|
#[is(name = "attribute_expr")]
|
|
Attribute(ExprAttribute),
|
|
#[is(name = "subscript_expr")]
|
|
Subscript(ExprSubscript),
|
|
#[is(name = "starred_expr")]
|
|
Starred(ExprStarred),
|
|
#[is(name = "name_expr")]
|
|
Name(ExprName),
|
|
#[is(name = "list_expr")]
|
|
List(ExprList),
|
|
#[is(name = "tuple_expr")]
|
|
Tuple(ExprTuple),
|
|
#[is(name = "slice_expr")]
|
|
Slice(ExprSlice),
|
|
|
|
// Jupyter notebook specific
|
|
#[is(name = "ipy_escape_command_expr")]
|
|
IpyEscapeCommand(ExprIpyEscapeCommand),
|
|
}
|
|
|
|
/// An AST node used to represent a IPython escape command at the expression level.
|
|
///
|
|
/// For example,
|
|
/// ```python
|
|
/// dir = !pwd
|
|
/// ```
|
|
///
|
|
/// Here, the escape kind can only be `!` or `%` otherwise it is a syntax error.
|
|
///
|
|
/// For more information related to terminology and syntax of escape commands,
|
|
/// see [`StmtIpyEscapeCommand`].
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprIpyEscapeCommand {
|
|
pub range: TextRange,
|
|
pub kind: IpyEscapeKind,
|
|
pub value: String,
|
|
}
|
|
|
|
impl From<ExprIpyEscapeCommand> for Expr {
|
|
fn from(payload: ExprIpyEscapeCommand) -> Self {
|
|
Expr::IpyEscapeCommand(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [BoolOp](https://docs.python.org/3/library/ast.html#ast.BoolOp)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprBoolOp {
|
|
pub range: TextRange,
|
|
pub op: BoolOp,
|
|
pub values: Vec<Expr>,
|
|
}
|
|
|
|
impl From<ExprBoolOp> for Expr {
|
|
fn from(payload: ExprBoolOp) -> Self {
|
|
Expr::BoolOp(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [NamedExpr](https://docs.python.org/3/library/ast.html#ast.NamedExpr)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprNamedExpr {
|
|
pub range: TextRange,
|
|
pub target: Box<Expr>,
|
|
pub value: Box<Expr>,
|
|
}
|
|
|
|
impl From<ExprNamedExpr> for Expr {
|
|
fn from(payload: ExprNamedExpr) -> Self {
|
|
Expr::NamedExpr(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [BinOp](https://docs.python.org/3/library/ast.html#ast.BinOp)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprBinOp {
|
|
pub range: TextRange,
|
|
pub left: Box<Expr>,
|
|
pub op: Operator,
|
|
pub right: Box<Expr>,
|
|
}
|
|
|
|
impl From<ExprBinOp> for Expr {
|
|
fn from(payload: ExprBinOp) -> Self {
|
|
Expr::BinOp(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [UnaryOp](https://docs.python.org/3/library/ast.html#ast.UnaryOp)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprUnaryOp {
|
|
pub range: TextRange,
|
|
pub op: UnaryOp,
|
|
pub operand: Box<Expr>,
|
|
}
|
|
|
|
impl From<ExprUnaryOp> for Expr {
|
|
fn from(payload: ExprUnaryOp) -> Self {
|
|
Expr::UnaryOp(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Lambda](https://docs.python.org/3/library/ast.html#ast.Lambda)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprLambda {
|
|
pub range: TextRange,
|
|
pub parameters: Option<Box<Parameters>>,
|
|
pub body: Box<Expr>,
|
|
}
|
|
|
|
impl From<ExprLambda> for Expr {
|
|
fn from(payload: ExprLambda) -> Self {
|
|
Expr::Lambda(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [IfExp](https://docs.python.org/3/library/ast.html#ast.IfExp)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprIfExp {
|
|
pub range: TextRange,
|
|
pub test: Box<Expr>,
|
|
pub body: Box<Expr>,
|
|
pub orelse: Box<Expr>,
|
|
}
|
|
|
|
impl From<ExprIfExp> for Expr {
|
|
fn from(payload: ExprIfExp) -> Self {
|
|
Expr::IfExp(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Dict](https://docs.python.org/3/library/ast.html#ast.Dict)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprDict {
|
|
pub range: TextRange,
|
|
pub keys: Vec<Option<Expr>>,
|
|
pub values: Vec<Expr>,
|
|
}
|
|
|
|
impl From<ExprDict> for Expr {
|
|
fn from(payload: ExprDict) -> Self {
|
|
Expr::Dict(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Set](https://docs.python.org/3/library/ast.html#ast.Set)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprSet {
|
|
pub range: TextRange,
|
|
pub elts: Vec<Expr>,
|
|
}
|
|
|
|
impl From<ExprSet> for Expr {
|
|
fn from(payload: ExprSet) -> Self {
|
|
Expr::Set(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [ListComp](https://docs.python.org/3/library/ast.html#ast.ListComp)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprListComp {
|
|
pub range: TextRange,
|
|
pub elt: Box<Expr>,
|
|
pub generators: Vec<Comprehension>,
|
|
}
|
|
|
|
impl From<ExprListComp> for Expr {
|
|
fn from(payload: ExprListComp) -> Self {
|
|
Expr::ListComp(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [SetComp](https://docs.python.org/3/library/ast.html#ast.SetComp)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprSetComp {
|
|
pub range: TextRange,
|
|
pub elt: Box<Expr>,
|
|
pub generators: Vec<Comprehension>,
|
|
}
|
|
|
|
impl From<ExprSetComp> for Expr {
|
|
fn from(payload: ExprSetComp) -> Self {
|
|
Expr::SetComp(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [DictComp](https://docs.python.org/3/library/ast.html#ast.DictComp)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprDictComp {
|
|
pub range: TextRange,
|
|
pub key: Box<Expr>,
|
|
pub value: Box<Expr>,
|
|
pub generators: Vec<Comprehension>,
|
|
}
|
|
|
|
impl From<ExprDictComp> for Expr {
|
|
fn from(payload: ExprDictComp) -> Self {
|
|
Expr::DictComp(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [GeneratorExp](https://docs.python.org/3/library/ast.html#ast.GeneratorExp)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprGeneratorExp {
|
|
pub range: TextRange,
|
|
pub elt: Box<Expr>,
|
|
pub generators: Vec<Comprehension>,
|
|
}
|
|
|
|
impl From<ExprGeneratorExp> for Expr {
|
|
fn from(payload: ExprGeneratorExp) -> Self {
|
|
Expr::GeneratorExp(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Await](https://docs.python.org/3/library/ast.html#ast.Await)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprAwait {
|
|
pub range: TextRange,
|
|
pub value: Box<Expr>,
|
|
}
|
|
|
|
impl From<ExprAwait> for Expr {
|
|
fn from(payload: ExprAwait) -> Self {
|
|
Expr::Await(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Yield](https://docs.python.org/3/library/ast.html#ast.Yield)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprYield {
|
|
pub range: TextRange,
|
|
pub value: Option<Box<Expr>>,
|
|
}
|
|
|
|
impl From<ExprYield> for Expr {
|
|
fn from(payload: ExprYield) -> Self {
|
|
Expr::Yield(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [YieldFrom](https://docs.python.org/3/library/ast.html#ast.YieldFrom)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprYieldFrom {
|
|
pub range: TextRange,
|
|
pub value: Box<Expr>,
|
|
}
|
|
|
|
impl From<ExprYieldFrom> for Expr {
|
|
fn from(payload: ExprYieldFrom) -> Self {
|
|
Expr::YieldFrom(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Compare](https://docs.python.org/3/library/ast.html#ast.Compare)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprCompare {
|
|
pub range: TextRange,
|
|
pub left: Box<Expr>,
|
|
pub ops: Vec<CmpOp>,
|
|
pub comparators: Vec<Expr>,
|
|
}
|
|
|
|
impl From<ExprCompare> for Expr {
|
|
fn from(payload: ExprCompare) -> Self {
|
|
Expr::Compare(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Call](https://docs.python.org/3/library/ast.html#ast.Call)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprCall {
|
|
pub range: TextRange,
|
|
pub func: Box<Expr>,
|
|
pub arguments: Arguments,
|
|
}
|
|
|
|
impl From<ExprCall> for Expr {
|
|
fn from(payload: ExprCall) -> Self {
|
|
Expr::Call(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [FormattedValue](https://docs.python.org/3/library/ast.html#ast.FormattedValue)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprFormattedValue {
|
|
pub range: TextRange,
|
|
pub value: Box<Expr>,
|
|
pub debug_text: Option<DebugText>,
|
|
pub conversion: ConversionFlag,
|
|
pub format_spec: Option<Box<Expr>>,
|
|
}
|
|
|
|
impl From<ExprFormattedValue> for Expr {
|
|
fn from(payload: ExprFormattedValue) -> Self {
|
|
Expr::FormattedValue(payload)
|
|
}
|
|
}
|
|
|
|
/// Transforms a value prior to formatting it.
|
|
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, is_macro::Is)]
|
|
#[repr(i8)]
|
|
#[allow(clippy::cast_possible_wrap)]
|
|
pub enum ConversionFlag {
|
|
/// No conversion
|
|
None = -1, // CPython uses -1
|
|
/// Converts by calling `str(<value>)`.
|
|
Str = b's' as i8,
|
|
/// Converts by calling `ascii(<value>)`.
|
|
Ascii = b'a' as i8,
|
|
/// Converts by calling `repr(<value>)`.
|
|
Repr = b'r' as i8,
|
|
}
|
|
|
|
impl ConversionFlag {
|
|
pub fn to_byte(&self) -> Option<u8> {
|
|
match self {
|
|
Self::None => None,
|
|
flag => Some(*flag as u8),
|
|
}
|
|
}
|
|
pub fn to_char(&self) -> Option<char> {
|
|
Some(self.to_byte()? as char)
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
|
pub struct DebugText {
|
|
/// The text between the `{` and the expression node.
|
|
pub leading: String,
|
|
/// The text between the expression and the conversion, the format_spec, or the `}`, depending on what's present in the source
|
|
pub trailing: String,
|
|
}
|
|
|
|
/// See also [JoinedStr](https://docs.python.org/3/library/ast.html#ast.JoinedStr)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprFString {
|
|
pub range: TextRange,
|
|
pub values: Vec<Expr>,
|
|
/// Whether the f-string contains multiple string tokens that were implicitly concatenated.
|
|
pub implicit_concatenated: bool,
|
|
}
|
|
|
|
impl From<ExprFString> for Expr {
|
|
fn from(payload: ExprFString) -> Self {
|
|
Expr::FString(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Constant](https://docs.python.org/3/library/ast.html#ast.Constant)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprConstant {
|
|
pub range: TextRange,
|
|
pub value: Constant,
|
|
pub kind: Option<String>,
|
|
}
|
|
|
|
impl From<ExprConstant> for Expr {
|
|
fn from(payload: ExprConstant) -> Self {
|
|
Expr::Constant(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Attribute](https://docs.python.org/3/library/ast.html#ast.Attribute)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprAttribute {
|
|
pub range: TextRange,
|
|
pub value: Box<Expr>,
|
|
pub attr: Identifier,
|
|
pub ctx: ExprContext,
|
|
}
|
|
|
|
impl From<ExprAttribute> for Expr {
|
|
fn from(payload: ExprAttribute) -> Self {
|
|
Expr::Attribute(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Subscript](https://docs.python.org/3/library/ast.html#ast.Subscript)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprSubscript {
|
|
pub range: TextRange,
|
|
pub value: Box<Expr>,
|
|
pub slice: Box<Expr>,
|
|
pub ctx: ExprContext,
|
|
}
|
|
|
|
impl From<ExprSubscript> for Expr {
|
|
fn from(payload: ExprSubscript) -> Self {
|
|
Expr::Subscript(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Starred](https://docs.python.org/3/library/ast.html#ast.Starred)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprStarred {
|
|
pub range: TextRange,
|
|
pub value: Box<Expr>,
|
|
pub ctx: ExprContext,
|
|
}
|
|
|
|
impl From<ExprStarred> for Expr {
|
|
fn from(payload: ExprStarred) -> Self {
|
|
Expr::Starred(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Name](https://docs.python.org/3/library/ast.html#ast.Name)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprName {
|
|
pub range: TextRange,
|
|
pub id: String,
|
|
pub ctx: ExprContext,
|
|
}
|
|
|
|
impl From<ExprName> for Expr {
|
|
fn from(payload: ExprName) -> Self {
|
|
Expr::Name(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [List](https://docs.python.org/3/library/ast.html#ast.List)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprList {
|
|
pub range: TextRange,
|
|
pub elts: Vec<Expr>,
|
|
pub ctx: ExprContext,
|
|
}
|
|
|
|
impl From<ExprList> for Expr {
|
|
fn from(payload: ExprList) -> Self {
|
|
Expr::List(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Tuple](https://docs.python.org/3/library/ast.html#ast.Tuple)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprTuple {
|
|
pub range: TextRange,
|
|
pub elts: Vec<Expr>,
|
|
pub ctx: ExprContext,
|
|
}
|
|
|
|
impl From<ExprTuple> for Expr {
|
|
fn from(payload: ExprTuple) -> Self {
|
|
Expr::Tuple(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [Slice](https://docs.python.org/3/library/ast.html#ast.Slice)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExprSlice {
|
|
pub range: TextRange,
|
|
pub lower: Option<Box<Expr>>,
|
|
pub upper: Option<Box<Expr>>,
|
|
pub step: Option<Box<Expr>>,
|
|
}
|
|
|
|
impl From<ExprSlice> for Expr {
|
|
fn from(payload: ExprSlice) -> Self {
|
|
Expr::Slice(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [expr_context](https://docs.python.org/3/library/ast.html#ast.expr_context)
|
|
#[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)]
|
|
pub enum ExprContext {
|
|
Load,
|
|
Store,
|
|
Del,
|
|
}
|
|
impl ExprContext {
|
|
#[inline]
|
|
pub const fn load(&self) -> Option<ExprContextLoad> {
|
|
match self {
|
|
ExprContext::Load => Some(ExprContextLoad),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn store(&self) -> Option<ExprContextStore> {
|
|
match self {
|
|
ExprContext::Store => Some(ExprContextStore),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn del(&self) -> Option<ExprContextDel> {
|
|
match self {
|
|
ExprContext::Del => Some(ExprContextDel),
|
|
_ => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct ExprContextLoad;
|
|
impl From<ExprContextLoad> for ExprContext {
|
|
fn from(_: ExprContextLoad) -> Self {
|
|
ExprContext::Load
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<ExprContext> for ExprContextLoad {
|
|
#[inline]
|
|
fn eq(&self, other: &ExprContext) -> bool {
|
|
matches!(other, ExprContext::Load)
|
|
}
|
|
}
|
|
|
|
pub struct ExprContextStore;
|
|
impl From<ExprContextStore> for ExprContext {
|
|
fn from(_: ExprContextStore) -> Self {
|
|
ExprContext::Store
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<ExprContext> for ExprContextStore {
|
|
#[inline]
|
|
fn eq(&self, other: &ExprContext) -> bool {
|
|
matches!(other, ExprContext::Store)
|
|
}
|
|
}
|
|
|
|
pub struct ExprContextDel;
|
|
impl From<ExprContextDel> for ExprContext {
|
|
fn from(_: ExprContextDel) -> Self {
|
|
ExprContext::Del
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<ExprContext> for ExprContextDel {
|
|
#[inline]
|
|
fn eq(&self, other: &ExprContext) -> bool {
|
|
matches!(other, ExprContext::Del)
|
|
}
|
|
}
|
|
|
|
/// See also [boolop](https://docs.python.org/3/library/ast.html#ast.BoolOp)
|
|
#[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)]
|
|
pub enum BoolOp {
|
|
And,
|
|
Or,
|
|
}
|
|
impl BoolOp {
|
|
#[inline]
|
|
pub const fn and(&self) -> Option<BoolOpAnd> {
|
|
match self {
|
|
BoolOp::And => Some(BoolOpAnd),
|
|
BoolOp::Or => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn or(&self) -> Option<BoolOpOr> {
|
|
match self {
|
|
BoolOp::Or => Some(BoolOpOr),
|
|
BoolOp::And => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct BoolOpAnd;
|
|
impl From<BoolOpAnd> for BoolOp {
|
|
fn from(_: BoolOpAnd) -> Self {
|
|
BoolOp::And
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<BoolOp> for BoolOpAnd {
|
|
#[inline]
|
|
fn eq(&self, other: &BoolOp) -> bool {
|
|
matches!(other, BoolOp::And)
|
|
}
|
|
}
|
|
|
|
pub struct BoolOpOr;
|
|
impl From<BoolOpOr> for BoolOp {
|
|
fn from(_: BoolOpOr) -> Self {
|
|
BoolOp::Or
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<BoolOp> for BoolOpOr {
|
|
#[inline]
|
|
fn eq(&self, other: &BoolOp) -> bool {
|
|
matches!(other, BoolOp::Or)
|
|
}
|
|
}
|
|
|
|
/// See also [operator](https://docs.python.org/3/library/ast.html#ast.operator)
|
|
#[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)]
|
|
pub enum Operator {
|
|
Add,
|
|
Sub,
|
|
Mult,
|
|
MatMult,
|
|
Div,
|
|
Mod,
|
|
Pow,
|
|
LShift,
|
|
RShift,
|
|
BitOr,
|
|
BitXor,
|
|
BitAnd,
|
|
FloorDiv,
|
|
}
|
|
impl Operator {
|
|
#[inline]
|
|
pub const fn operator_add(&self) -> Option<OperatorAdd> {
|
|
match self {
|
|
Operator::Add => Some(OperatorAdd),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn operator_sub(&self) -> Option<OperatorSub> {
|
|
match self {
|
|
Operator::Sub => Some(OperatorSub),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn operator_mult(&self) -> Option<OperatorMult> {
|
|
match self {
|
|
Operator::Mult => Some(OperatorMult),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn operator_mat_mult(&self) -> Option<OperatorMatMult> {
|
|
match self {
|
|
Operator::MatMult => Some(OperatorMatMult),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn operator_div(&self) -> Option<OperatorDiv> {
|
|
match self {
|
|
Operator::Div => Some(OperatorDiv),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn operator_mod(&self) -> Option<OperatorMod> {
|
|
match self {
|
|
Operator::Mod => Some(OperatorMod),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn operator_pow(&self) -> Option<OperatorPow> {
|
|
match self {
|
|
Operator::Pow => Some(OperatorPow),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn operator_l_shift(&self) -> Option<OperatorLShift> {
|
|
match self {
|
|
Operator::LShift => Some(OperatorLShift),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn operator_r_shift(&self) -> Option<OperatorRShift> {
|
|
match self {
|
|
Operator::RShift => Some(OperatorRShift),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn operator_bit_or(&self) -> Option<OperatorBitOr> {
|
|
match self {
|
|
Operator::BitOr => Some(OperatorBitOr),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn operator_bit_xor(&self) -> Option<OperatorBitXor> {
|
|
match self {
|
|
Operator::BitXor => Some(OperatorBitXor),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn operator_bit_and(&self) -> Option<OperatorBitAnd> {
|
|
match self {
|
|
Operator::BitAnd => Some(OperatorBitAnd),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn operator_floor_div(&self) -> Option<OperatorFloorDiv> {
|
|
match self {
|
|
Operator::FloorDiv => Some(OperatorFloorDiv),
|
|
_ => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct OperatorAdd;
|
|
impl From<OperatorAdd> for Operator {
|
|
fn from(_: OperatorAdd) -> Self {
|
|
Operator::Add
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<Operator> for OperatorAdd {
|
|
#[inline]
|
|
fn eq(&self, other: &Operator) -> bool {
|
|
matches!(other, Operator::Add)
|
|
}
|
|
}
|
|
|
|
pub struct OperatorSub;
|
|
impl From<OperatorSub> for Operator {
|
|
fn from(_: OperatorSub) -> Self {
|
|
Operator::Sub
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<Operator> for OperatorSub {
|
|
#[inline]
|
|
fn eq(&self, other: &Operator) -> bool {
|
|
matches!(other, Operator::Sub)
|
|
}
|
|
}
|
|
|
|
pub struct OperatorMult;
|
|
impl From<OperatorMult> for Operator {
|
|
fn from(_: OperatorMult) -> Self {
|
|
Operator::Mult
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<Operator> for OperatorMult {
|
|
#[inline]
|
|
fn eq(&self, other: &Operator) -> bool {
|
|
matches!(other, Operator::Mult)
|
|
}
|
|
}
|
|
|
|
pub struct OperatorMatMult;
|
|
impl From<OperatorMatMult> for Operator {
|
|
fn from(_: OperatorMatMult) -> Self {
|
|
Operator::MatMult
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<Operator> for OperatorMatMult {
|
|
#[inline]
|
|
fn eq(&self, other: &Operator) -> bool {
|
|
matches!(other, Operator::MatMult)
|
|
}
|
|
}
|
|
|
|
pub struct OperatorDiv;
|
|
impl From<OperatorDiv> for Operator {
|
|
fn from(_: OperatorDiv) -> Self {
|
|
Operator::Div
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<Operator> for OperatorDiv {
|
|
#[inline]
|
|
fn eq(&self, other: &Operator) -> bool {
|
|
matches!(other, Operator::Div)
|
|
}
|
|
}
|
|
|
|
pub struct OperatorMod;
|
|
impl From<OperatorMod> for Operator {
|
|
fn from(_: OperatorMod) -> Self {
|
|
Operator::Mod
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<Operator> for OperatorMod {
|
|
#[inline]
|
|
fn eq(&self, other: &Operator) -> bool {
|
|
matches!(other, Operator::Mod)
|
|
}
|
|
}
|
|
|
|
pub struct OperatorPow;
|
|
impl From<OperatorPow> for Operator {
|
|
fn from(_: OperatorPow) -> Self {
|
|
Operator::Pow
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<Operator> for OperatorPow {
|
|
#[inline]
|
|
fn eq(&self, other: &Operator) -> bool {
|
|
matches!(other, Operator::Pow)
|
|
}
|
|
}
|
|
|
|
pub struct OperatorLShift;
|
|
impl From<OperatorLShift> for Operator {
|
|
fn from(_: OperatorLShift) -> Self {
|
|
Operator::LShift
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<Operator> for OperatorLShift {
|
|
#[inline]
|
|
fn eq(&self, other: &Operator) -> bool {
|
|
matches!(other, Operator::LShift)
|
|
}
|
|
}
|
|
|
|
pub struct OperatorRShift;
|
|
impl From<OperatorRShift> for Operator {
|
|
fn from(_: OperatorRShift) -> Self {
|
|
Operator::RShift
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<Operator> for OperatorRShift {
|
|
#[inline]
|
|
fn eq(&self, other: &Operator) -> bool {
|
|
matches!(other, Operator::RShift)
|
|
}
|
|
}
|
|
|
|
pub struct OperatorBitOr;
|
|
impl From<OperatorBitOr> for Operator {
|
|
fn from(_: OperatorBitOr) -> Self {
|
|
Operator::BitOr
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<Operator> for OperatorBitOr {
|
|
#[inline]
|
|
fn eq(&self, other: &Operator) -> bool {
|
|
matches!(other, Operator::BitOr)
|
|
}
|
|
}
|
|
|
|
pub struct OperatorBitXor;
|
|
impl From<OperatorBitXor> for Operator {
|
|
fn from(_: OperatorBitXor) -> Self {
|
|
Operator::BitXor
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<Operator> for OperatorBitXor {
|
|
#[inline]
|
|
fn eq(&self, other: &Operator) -> bool {
|
|
matches!(other, Operator::BitXor)
|
|
}
|
|
}
|
|
|
|
pub struct OperatorBitAnd;
|
|
impl From<OperatorBitAnd> for Operator {
|
|
fn from(_: OperatorBitAnd) -> Self {
|
|
Operator::BitAnd
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<Operator> for OperatorBitAnd {
|
|
#[inline]
|
|
fn eq(&self, other: &Operator) -> bool {
|
|
matches!(other, Operator::BitAnd)
|
|
}
|
|
}
|
|
|
|
pub struct OperatorFloorDiv;
|
|
impl From<OperatorFloorDiv> for Operator {
|
|
fn from(_: OperatorFloorDiv) -> Self {
|
|
Operator::FloorDiv
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<Operator> for OperatorFloorDiv {
|
|
#[inline]
|
|
fn eq(&self, other: &Operator) -> bool {
|
|
matches!(other, Operator::FloorDiv)
|
|
}
|
|
}
|
|
|
|
/// See also [unaryop](https://docs.python.org/3/library/ast.html#ast.unaryop)
|
|
#[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)]
|
|
pub enum UnaryOp {
|
|
Invert,
|
|
Not,
|
|
UAdd,
|
|
USub,
|
|
}
|
|
impl UnaryOp {
|
|
#[inline]
|
|
pub const fn invert(&self) -> Option<UnaryOpInvert> {
|
|
match self {
|
|
UnaryOp::Invert => Some(UnaryOpInvert),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn not(&self) -> Option<UnaryOpNot> {
|
|
match self {
|
|
UnaryOp::Not => Some(UnaryOpNot),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn u_add(&self) -> Option<UnaryOpUAdd> {
|
|
match self {
|
|
UnaryOp::UAdd => Some(UnaryOpUAdd),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn u_sub(&self) -> Option<UnaryOpUSub> {
|
|
match self {
|
|
UnaryOp::USub => Some(UnaryOpUSub),
|
|
_ => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct UnaryOpInvert;
|
|
impl From<UnaryOpInvert> for UnaryOp {
|
|
fn from(_: UnaryOpInvert) -> Self {
|
|
UnaryOp::Invert
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<UnaryOp> for UnaryOpInvert {
|
|
#[inline]
|
|
fn eq(&self, other: &UnaryOp) -> bool {
|
|
matches!(other, UnaryOp::Invert)
|
|
}
|
|
}
|
|
|
|
pub struct UnaryOpNot;
|
|
impl From<UnaryOpNot> for UnaryOp {
|
|
fn from(_: UnaryOpNot) -> Self {
|
|
UnaryOp::Not
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<UnaryOp> for UnaryOpNot {
|
|
#[inline]
|
|
fn eq(&self, other: &UnaryOp) -> bool {
|
|
matches!(other, UnaryOp::Not)
|
|
}
|
|
}
|
|
|
|
pub struct UnaryOpUAdd;
|
|
impl From<UnaryOpUAdd> for UnaryOp {
|
|
fn from(_: UnaryOpUAdd) -> Self {
|
|
UnaryOp::UAdd
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<UnaryOp> for UnaryOpUAdd {
|
|
#[inline]
|
|
fn eq(&self, other: &UnaryOp) -> bool {
|
|
matches!(other, UnaryOp::UAdd)
|
|
}
|
|
}
|
|
|
|
pub struct UnaryOpUSub;
|
|
impl From<UnaryOpUSub> for UnaryOp {
|
|
fn from(_: UnaryOpUSub) -> Self {
|
|
UnaryOp::USub
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<UnaryOp> for UnaryOpUSub {
|
|
#[inline]
|
|
fn eq(&self, other: &UnaryOp) -> bool {
|
|
matches!(other, UnaryOp::USub)
|
|
}
|
|
}
|
|
|
|
/// See also [cmpop](https://docs.python.org/3/library/ast.html#ast.cmpop)
|
|
#[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)]
|
|
pub enum CmpOp {
|
|
Eq,
|
|
NotEq,
|
|
Lt,
|
|
LtE,
|
|
Gt,
|
|
GtE,
|
|
Is,
|
|
IsNot,
|
|
In,
|
|
NotIn,
|
|
}
|
|
impl CmpOp {
|
|
#[inline]
|
|
pub const fn cmp_op_eq(&self) -> Option<CmpOpEq> {
|
|
match self {
|
|
CmpOp::Eq => Some(CmpOpEq),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn cmp_op_not_eq(&self) -> Option<CmpOpNotEq> {
|
|
match self {
|
|
CmpOp::NotEq => Some(CmpOpNotEq),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn cmp_op_lt(&self) -> Option<CmpOpLt> {
|
|
match self {
|
|
CmpOp::Lt => Some(CmpOpLt),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn cmp_op_lt_e(&self) -> Option<CmpOpLtE> {
|
|
match self {
|
|
CmpOp::LtE => Some(CmpOpLtE),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn cmp_op_gt(&self) -> Option<CmpOpGt> {
|
|
match self {
|
|
CmpOp::Gt => Some(CmpOpGt),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn cmp_op_gt_e(&self) -> Option<CmpOpGtE> {
|
|
match self {
|
|
CmpOp::GtE => Some(CmpOpGtE),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn cmp_op_is(&self) -> Option<CmpOpIs> {
|
|
match self {
|
|
CmpOp::Is => Some(CmpOpIs),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn cmp_op_is_not(&self) -> Option<CmpOpIsNot> {
|
|
match self {
|
|
CmpOp::IsNot => Some(CmpOpIsNot),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn cmp_op_in(&self) -> Option<CmpOpIn> {
|
|
match self {
|
|
CmpOp::In => Some(CmpOpIn),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub const fn cmp_op_not_in(&self) -> Option<CmpOpNotIn> {
|
|
match self {
|
|
CmpOp::NotIn => Some(CmpOpNotIn),
|
|
_ => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct CmpOpEq;
|
|
impl From<CmpOpEq> for CmpOp {
|
|
fn from(_: CmpOpEq) -> Self {
|
|
CmpOp::Eq
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<CmpOp> for CmpOpEq {
|
|
#[inline]
|
|
fn eq(&self, other: &CmpOp) -> bool {
|
|
matches!(other, CmpOp::Eq)
|
|
}
|
|
}
|
|
|
|
pub struct CmpOpNotEq;
|
|
impl From<CmpOpNotEq> for CmpOp {
|
|
fn from(_: CmpOpNotEq) -> Self {
|
|
CmpOp::NotEq
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<CmpOp> for CmpOpNotEq {
|
|
#[inline]
|
|
fn eq(&self, other: &CmpOp) -> bool {
|
|
matches!(other, CmpOp::NotEq)
|
|
}
|
|
}
|
|
|
|
pub struct CmpOpLt;
|
|
impl From<CmpOpLt> for CmpOp {
|
|
fn from(_: CmpOpLt) -> Self {
|
|
CmpOp::Lt
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<CmpOp> for CmpOpLt {
|
|
#[inline]
|
|
fn eq(&self, other: &CmpOp) -> bool {
|
|
matches!(other, CmpOp::Lt)
|
|
}
|
|
}
|
|
|
|
pub struct CmpOpLtE;
|
|
impl From<CmpOpLtE> for CmpOp {
|
|
fn from(_: CmpOpLtE) -> Self {
|
|
CmpOp::LtE
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<CmpOp> for CmpOpLtE {
|
|
#[inline]
|
|
fn eq(&self, other: &CmpOp) -> bool {
|
|
matches!(other, CmpOp::LtE)
|
|
}
|
|
}
|
|
|
|
pub struct CmpOpGt;
|
|
impl From<CmpOpGt> for CmpOp {
|
|
fn from(_: CmpOpGt) -> Self {
|
|
CmpOp::Gt
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<CmpOp> for CmpOpGt {
|
|
#[inline]
|
|
fn eq(&self, other: &CmpOp) -> bool {
|
|
matches!(other, CmpOp::Gt)
|
|
}
|
|
}
|
|
|
|
pub struct CmpOpGtE;
|
|
impl From<CmpOpGtE> for CmpOp {
|
|
fn from(_: CmpOpGtE) -> Self {
|
|
CmpOp::GtE
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<CmpOp> for CmpOpGtE {
|
|
#[inline]
|
|
fn eq(&self, other: &CmpOp) -> bool {
|
|
matches!(other, CmpOp::GtE)
|
|
}
|
|
}
|
|
|
|
pub struct CmpOpIs;
|
|
impl From<CmpOpIs> for CmpOp {
|
|
fn from(_: CmpOpIs) -> Self {
|
|
CmpOp::Is
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<CmpOp> for CmpOpIs {
|
|
#[inline]
|
|
fn eq(&self, other: &CmpOp) -> bool {
|
|
matches!(other, CmpOp::Is)
|
|
}
|
|
}
|
|
|
|
pub struct CmpOpIsNot;
|
|
impl From<CmpOpIsNot> for CmpOp {
|
|
fn from(_: CmpOpIsNot) -> Self {
|
|
CmpOp::IsNot
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<CmpOp> for CmpOpIsNot {
|
|
#[inline]
|
|
fn eq(&self, other: &CmpOp) -> bool {
|
|
matches!(other, CmpOp::IsNot)
|
|
}
|
|
}
|
|
|
|
pub struct CmpOpIn;
|
|
impl From<CmpOpIn> for CmpOp {
|
|
fn from(_: CmpOpIn) -> Self {
|
|
CmpOp::In
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<CmpOp> for CmpOpIn {
|
|
#[inline]
|
|
fn eq(&self, other: &CmpOp) -> bool {
|
|
matches!(other, CmpOp::In)
|
|
}
|
|
}
|
|
|
|
pub struct CmpOpNotIn;
|
|
impl From<CmpOpNotIn> for CmpOp {
|
|
fn from(_: CmpOpNotIn) -> Self {
|
|
CmpOp::NotIn
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<CmpOp> for CmpOpNotIn {
|
|
#[inline]
|
|
fn eq(&self, other: &CmpOp) -> bool {
|
|
matches!(other, CmpOp::NotIn)
|
|
}
|
|
}
|
|
|
|
/// See also [comprehension](https://docs.python.org/3/library/ast.html#ast.comprehension)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct Comprehension {
|
|
pub range: TextRange,
|
|
pub target: Expr,
|
|
pub iter: Expr,
|
|
pub ifs: Vec<Expr>,
|
|
pub is_async: bool,
|
|
}
|
|
|
|
/// See also [excepthandler](https://docs.python.org/3/library/ast.html#ast.excepthandler)
|
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
|
pub enum ExceptHandler {
|
|
ExceptHandler(ExceptHandlerExceptHandler),
|
|
}
|
|
|
|
/// See also [ExceptHandler](https://docs.python.org/3/library/ast.html#ast.ExceptHandler)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ExceptHandlerExceptHandler {
|
|
pub range: TextRange,
|
|
pub type_: Option<Box<Expr>>,
|
|
pub name: Option<Identifier>,
|
|
pub body: Vec<Stmt>,
|
|
}
|
|
|
|
impl From<ExceptHandlerExceptHandler> for ExceptHandler {
|
|
fn from(payload: ExceptHandlerExceptHandler) -> Self {
|
|
ExceptHandler::ExceptHandler(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [arg](https://docs.python.org/3/library/ast.html#ast.arg)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct Parameter {
|
|
pub range: TextRange,
|
|
pub name: Identifier,
|
|
pub annotation: Option<Box<Expr>>,
|
|
}
|
|
|
|
/// See also [keyword](https://docs.python.org/3/library/ast.html#ast.keyword)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct Keyword {
|
|
pub range: TextRange,
|
|
pub arg: Option<Identifier>,
|
|
pub value: Expr,
|
|
}
|
|
|
|
/// See also [alias](https://docs.python.org/3/library/ast.html#ast.alias)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct Alias {
|
|
pub range: TextRange,
|
|
pub name: Identifier,
|
|
pub asname: Option<Identifier>,
|
|
}
|
|
|
|
/// See also [withitem](https://docs.python.org/3/library/ast.html#ast.withitem)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct WithItem {
|
|
pub range: TextRange,
|
|
pub context_expr: Expr,
|
|
pub optional_vars: Option<Box<Expr>>,
|
|
}
|
|
|
|
/// See also [match_case](https://docs.python.org/3/library/ast.html#ast.match_case)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct MatchCase {
|
|
pub range: TextRange,
|
|
pub pattern: Pattern,
|
|
pub guard: Option<Box<Expr>>,
|
|
pub body: Vec<Stmt>,
|
|
}
|
|
|
|
/// See also [pattern](https://docs.python.org/3/library/ast.html#ast.pattern)
|
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
|
pub enum Pattern {
|
|
MatchValue(PatternMatchValue),
|
|
MatchSingleton(PatternMatchSingleton),
|
|
MatchSequence(PatternMatchSequence),
|
|
MatchMapping(PatternMatchMapping),
|
|
MatchClass(PatternMatchClass),
|
|
MatchStar(PatternMatchStar),
|
|
MatchAs(PatternMatchAs),
|
|
MatchOr(PatternMatchOr),
|
|
}
|
|
|
|
/// See also [MatchValue](https://docs.python.org/3/library/ast.html#ast.MatchValue)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct PatternMatchValue {
|
|
pub range: TextRange,
|
|
pub value: Box<Expr>,
|
|
}
|
|
|
|
impl From<PatternMatchValue> for Pattern {
|
|
fn from(payload: PatternMatchValue) -> Self {
|
|
Pattern::MatchValue(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [MatchSingleton](https://docs.python.org/3/library/ast.html#ast.MatchSingleton)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct PatternMatchSingleton {
|
|
pub range: TextRange,
|
|
pub value: Constant,
|
|
}
|
|
|
|
impl From<PatternMatchSingleton> for Pattern {
|
|
fn from(payload: PatternMatchSingleton) -> Self {
|
|
Pattern::MatchSingleton(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [MatchSequence](https://docs.python.org/3/library/ast.html#ast.MatchSequence)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct PatternMatchSequence {
|
|
pub range: TextRange,
|
|
pub patterns: Vec<Pattern>,
|
|
}
|
|
|
|
impl From<PatternMatchSequence> for Pattern {
|
|
fn from(payload: PatternMatchSequence) -> Self {
|
|
Pattern::MatchSequence(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [MatchMapping](https://docs.python.org/3/library/ast.html#ast.MatchMapping)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct PatternMatchMapping {
|
|
pub range: TextRange,
|
|
pub keys: Vec<Expr>,
|
|
pub patterns: Vec<Pattern>,
|
|
pub rest: Option<Identifier>,
|
|
}
|
|
|
|
impl From<PatternMatchMapping> for Pattern {
|
|
fn from(payload: PatternMatchMapping) -> Self {
|
|
Pattern::MatchMapping(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [MatchClass](https://docs.python.org/3/library/ast.html#ast.MatchClass)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct PatternMatchClass {
|
|
pub range: TextRange,
|
|
pub cls: Box<Expr>,
|
|
pub arguments: PatternArguments,
|
|
}
|
|
|
|
impl From<PatternMatchClass> for Pattern {
|
|
fn from(payload: PatternMatchClass) -> Self {
|
|
Pattern::MatchClass(payload)
|
|
}
|
|
}
|
|
|
|
/// An AST node to represent the arguments to a [`PatternMatchClass`], i.e., the
|
|
/// parenthesized contents in `case Point(1, x=0, y=0)`.
|
|
///
|
|
/// Like [`Arguments`], but for [`PatternMatchClass`].
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct PatternArguments {
|
|
pub range: TextRange,
|
|
pub patterns: Vec<Pattern>,
|
|
pub keywords: Vec<PatternKeyword>,
|
|
}
|
|
|
|
/// An AST node to represent the keyword arguments to a [`PatternMatchClass`], i.e., the
|
|
/// `x=0` and `y=0` in `case Point(x=0, y=0)`.
|
|
///
|
|
/// Like [`Keyword`], but for [`PatternMatchClass`].
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct PatternKeyword {
|
|
pub range: TextRange,
|
|
pub attr: Identifier,
|
|
pub pattern: Pattern,
|
|
}
|
|
|
|
/// See also [MatchStar](https://docs.python.org/3/library/ast.html#ast.MatchStar)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct PatternMatchStar {
|
|
pub range: TextRange,
|
|
pub name: Option<Identifier>,
|
|
}
|
|
|
|
impl From<PatternMatchStar> for Pattern {
|
|
fn from(payload: PatternMatchStar) -> Self {
|
|
Pattern::MatchStar(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [MatchAs](https://docs.python.org/3/library/ast.html#ast.MatchAs)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct PatternMatchAs {
|
|
pub range: TextRange,
|
|
pub pattern: Option<Box<Pattern>>,
|
|
pub name: Option<Identifier>,
|
|
}
|
|
|
|
impl From<PatternMatchAs> for Pattern {
|
|
fn from(payload: PatternMatchAs) -> Self {
|
|
Pattern::MatchAs(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [MatchOr](https://docs.python.org/3/library/ast.html#ast.MatchOr)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct PatternMatchOr {
|
|
pub range: TextRange,
|
|
pub patterns: Vec<Pattern>,
|
|
}
|
|
|
|
impl From<PatternMatchOr> for Pattern {
|
|
fn from(payload: PatternMatchOr) -> Self {
|
|
Pattern::MatchOr(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [type_param](https://docs.python.org/3/library/ast.html#ast.type_param)
|
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
|
pub enum TypeParam {
|
|
TypeVar(TypeParamTypeVar),
|
|
ParamSpec(TypeParamParamSpec),
|
|
TypeVarTuple(TypeParamTypeVarTuple),
|
|
}
|
|
|
|
/// See also [TypeVar](https://docs.python.org/3/library/ast.html#ast.TypeVar)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct TypeParamTypeVar {
|
|
pub range: TextRange,
|
|
pub name: Identifier,
|
|
pub bound: Option<Box<Expr>>,
|
|
}
|
|
|
|
impl From<TypeParamTypeVar> for TypeParam {
|
|
fn from(payload: TypeParamTypeVar) -> Self {
|
|
TypeParam::TypeVar(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [ParamSpec](https://docs.python.org/3/library/ast.html#ast.ParamSpec)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct TypeParamParamSpec {
|
|
pub range: TextRange,
|
|
pub name: Identifier,
|
|
}
|
|
|
|
impl From<TypeParamParamSpec> for TypeParam {
|
|
fn from(payload: TypeParamParamSpec) -> Self {
|
|
TypeParam::ParamSpec(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [TypeVarTuple](https://docs.python.org/3/library/ast.html#ast.TypeVarTuple)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct TypeParamTypeVarTuple {
|
|
pub range: TextRange,
|
|
pub name: Identifier,
|
|
}
|
|
|
|
impl From<TypeParamTypeVarTuple> for TypeParam {
|
|
fn from(payload: TypeParamTypeVarTuple) -> Self {
|
|
TypeParam::TypeVarTuple(payload)
|
|
}
|
|
}
|
|
|
|
/// See also [decorator](https://docs.python.org/3/library/ast.html#ast.decorator)
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct Decorator {
|
|
pub range: TextRange,
|
|
pub expression: Expr,
|
|
}
|
|
|
|
/// An alternative type of AST `arguments`. This is ruff_python_parser-friendly and human-friendly definition of function arguments.
|
|
/// This form also has advantage to implement pre-order traverse.
|
|
///
|
|
/// `defaults` and `kw_defaults` fields are removed and the default values are placed under each [`ParameterWithDefault`] typed argument.
|
|
/// `vararg` and `kwarg` are still typed as `arg` because they never can have a default value.
|
|
///
|
|
/// The original Python-style AST type orders `kwonlyargs` fields by default existence; [Parameters] has location-ordered `kwonlyargs` fields.
|
|
///
|
|
/// NOTE: This type differs from the original Python AST. See: [arguments](https://docs.python.org/3/library/ast.html#ast.arguments).
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct Parameters {
|
|
pub range: TextRange,
|
|
pub posonlyargs: Vec<ParameterWithDefault>,
|
|
pub args: Vec<ParameterWithDefault>,
|
|
pub vararg: Option<Box<Parameter>>,
|
|
pub kwonlyargs: Vec<ParameterWithDefault>,
|
|
pub kwarg: Option<Box<Parameter>>,
|
|
}
|
|
|
|
impl Parameters {
|
|
/// Returns `true` if a parameter with the given name included in this [`Parameters`].
|
|
pub fn includes(&self, name: &str) -> bool {
|
|
if self
|
|
.posonlyargs
|
|
.iter()
|
|
.chain(&self.args)
|
|
.chain(&self.kwonlyargs)
|
|
.any(|arg| arg.parameter.name.as_str() == name)
|
|
{
|
|
return true;
|
|
}
|
|
if let Some(arg) = &self.vararg {
|
|
if arg.name.as_str() == name {
|
|
return true;
|
|
}
|
|
}
|
|
if let Some(arg) = &self.kwarg {
|
|
if arg.name.as_str() == name {
|
|
return true;
|
|
}
|
|
}
|
|
false
|
|
}
|
|
}
|
|
|
|
/// An alternative type of AST `arg`. This is used for each function argument that might have a default value.
|
|
/// Used by `Arguments` original type.
|
|
///
|
|
/// NOTE: This type is different from original Python AST.
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ParameterWithDefault {
|
|
pub range: TextRange,
|
|
pub parameter: Parameter,
|
|
pub default: Option<Box<Expr>>,
|
|
}
|
|
|
|
/// An AST node used to represent the arguments passed to a function call or class definition.
|
|
///
|
|
/// For example, given:
|
|
/// ```python
|
|
/// foo(1, 2, 3, bar=4, baz=5)
|
|
/// ```
|
|
/// The `Arguments` node would span from the left to right parentheses (inclusive), and contain
|
|
/// the arguments and keyword arguments in the order they appear in the source code.
|
|
///
|
|
/// Similarly, given:
|
|
/// ```python
|
|
/// class Foo(Bar, baz=1, qux=2):
|
|
/// pass
|
|
/// ```
|
|
/// The `Arguments` node would again span from the left to right parentheses (inclusive), and
|
|
/// contain the `Bar` argument and the `baz` and `qux` keyword arguments in the order they
|
|
/// appear in the source code.
|
|
///
|
|
/// In the context of a class definition, the Python-style AST refers to the arguments as `bases`,
|
|
/// as they represent the "explicitly specified base classes", while the keyword arguments are
|
|
/// typically used for `metaclass`, with any additional arguments being passed to the `metaclass`.
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct Arguments {
|
|
pub range: TextRange,
|
|
pub args: Vec<Expr>,
|
|
pub keywords: Vec<Keyword>,
|
|
}
|
|
|
|
impl Arguments {
|
|
/// Return the number of positional and keyword arguments.
|
|
pub fn len(&self) -> usize {
|
|
self.args.len() + self.keywords.len()
|
|
}
|
|
|
|
/// Return `true` if there are no positional or keyword arguments.
|
|
pub fn is_empty(&self) -> bool {
|
|
self.len() == 0
|
|
}
|
|
|
|
/// Return the [`Keyword`] with the given name, or `None` if no such [`Keyword`] exists.
|
|
pub fn find_keyword(&self, keyword_name: &str) -> Option<&Keyword> {
|
|
self.keywords.iter().find(|keyword| {
|
|
let Keyword { arg, .. } = keyword;
|
|
arg.as_ref().is_some_and(|arg| arg == keyword_name)
|
|
})
|
|
}
|
|
|
|
/// Return the positional argument at the given index, or `None` if no such argument exists.
|
|
pub fn find_positional(&self, position: usize) -> Option<&Expr> {
|
|
self.args
|
|
.iter()
|
|
.take_while(|expr| !expr.is_starred_expr())
|
|
.nth(position)
|
|
}
|
|
|
|
/// Return the argument with the given name or at the given position, or `None` if no such
|
|
/// argument exists. Used to retrieve arguments that can be provided _either_ as keyword or
|
|
/// positional arguments.
|
|
pub fn find_argument(&self, name: &str, position: usize) -> Option<&Expr> {
|
|
self.find_keyword(name)
|
|
.map(|keyword| &keyword.value)
|
|
.or_else(|| self.find_positional(position))
|
|
}
|
|
}
|
|
|
|
/// An AST node used to represent a sequence of type parameters.
|
|
///
|
|
/// For example, given:
|
|
/// ```python
|
|
/// class C[T, U, V]: ...
|
|
/// ```
|
|
/// The `TypeParams` node would span from the left to right brackets (inclusive), and contain
|
|
/// the `T`, `U`, and `V` type parameters in the order they appear in the source code.
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct TypeParams {
|
|
pub range: TextRange,
|
|
pub type_params: Vec<TypeParam>,
|
|
}
|
|
|
|
impl Deref for TypeParams {
|
|
type Target = [TypeParam];
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.type_params
|
|
}
|
|
}
|
|
|
|
pub type Suite = Vec<Stmt>;
|
|
|
|
impl CmpOp {
|
|
pub fn as_str(&self) -> &'static str {
|
|
match self {
|
|
CmpOp::Eq => "==",
|
|
CmpOp::NotEq => "!=",
|
|
CmpOp::Lt => "<",
|
|
CmpOp::LtE => "<=",
|
|
CmpOp::Gt => ">",
|
|
CmpOp::GtE => ">=",
|
|
CmpOp::Is => "is",
|
|
CmpOp::IsNot => "is not",
|
|
CmpOp::In => "in",
|
|
CmpOp::NotIn => "not in",
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Parameters {
|
|
pub fn empty(range: TextRange) -> Self {
|
|
Self {
|
|
range,
|
|
posonlyargs: Vec::new(),
|
|
args: Vec::new(),
|
|
vararg: None,
|
|
kwonlyargs: Vec::new(),
|
|
kwarg: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[allow(clippy::borrowed_box)] // local utility
|
|
fn clone_boxed_expr(expr: &Box<Expr>) -> Box<Expr> {
|
|
let expr: &Expr = expr.as_ref();
|
|
Box::new(expr.clone())
|
|
}
|
|
|
|
impl ParameterWithDefault {
|
|
pub fn as_parameter(&self) -> &Parameter {
|
|
&self.parameter
|
|
}
|
|
|
|
pub fn to_parameter(&self) -> (Parameter, Option<Box<Expr>>) {
|
|
let ParameterWithDefault {
|
|
range: _,
|
|
parameter,
|
|
default,
|
|
} = self;
|
|
(parameter.clone(), default.as_ref().map(clone_boxed_expr))
|
|
}
|
|
pub fn into_parameter(self) -> (Parameter, Option<Box<Expr>>) {
|
|
let ParameterWithDefault {
|
|
range: _,
|
|
parameter,
|
|
default,
|
|
} = self;
|
|
(parameter, default)
|
|
}
|
|
}
|
|
|
|
impl Parameters {
|
|
pub fn defaults(&self) -> impl std::iter::Iterator<Item = &Expr> {
|
|
self.posonlyargs
|
|
.iter()
|
|
.chain(self.args.iter())
|
|
.filter_map(|arg| arg.default.as_ref().map(std::convert::AsRef::as_ref))
|
|
}
|
|
|
|
#[allow(clippy::type_complexity)]
|
|
pub fn split_kwonlyargs(&self) -> (Vec<&Parameter>, Vec<(&Parameter, &Expr)>) {
|
|
let mut args = Vec::new();
|
|
let mut with_defaults = Vec::new();
|
|
for arg in &self.kwonlyargs {
|
|
if let Some(ref default) = arg.default {
|
|
with_defaults.push((arg.as_parameter(), &**default));
|
|
} else {
|
|
args.push(arg.as_parameter());
|
|
}
|
|
}
|
|
(args, with_defaults)
|
|
}
|
|
}
|
|
|
|
/// The kind of escape command as defined in [IPython Syntax] in the IPython codebase.
|
|
///
|
|
/// [IPython Syntax]: https://github.com/ipython/ipython/blob/635815e8f1ded5b764d66cacc80bbe25e9e2587f/IPython/core/inputtransformer2.py#L335-L343
|
|
#[derive(PartialEq, Eq, Debug, Clone, Hash, Copy)]
|
|
pub enum IpyEscapeKind {
|
|
/// Send line to underlying system shell (`!`).
|
|
Shell,
|
|
/// Send line to system shell and capture output (`!!`).
|
|
ShCap,
|
|
/// Show help on object (`?`).
|
|
Help,
|
|
/// Show help on object, with extra verbosity (`??`).
|
|
Help2,
|
|
/// Call magic function (`%`).
|
|
Magic,
|
|
/// Call cell magic function (`%%`).
|
|
Magic2,
|
|
/// Call first argument with rest of line as arguments after splitting on whitespace
|
|
/// and quote each as string (`,`).
|
|
Quote,
|
|
/// Call first argument with rest of line as an argument quoted as a single string (`;`).
|
|
Quote2,
|
|
/// Call first argument with rest of line as arguments (`/`).
|
|
Paren,
|
|
}
|
|
|
|
impl TryFrom<char> for IpyEscapeKind {
|
|
type Error = String;
|
|
|
|
fn try_from(ch: char) -> Result<Self, Self::Error> {
|
|
match ch {
|
|
'!' => Ok(IpyEscapeKind::Shell),
|
|
'?' => Ok(IpyEscapeKind::Help),
|
|
'%' => Ok(IpyEscapeKind::Magic),
|
|
',' => Ok(IpyEscapeKind::Quote),
|
|
';' => Ok(IpyEscapeKind::Quote2),
|
|
'/' => Ok(IpyEscapeKind::Paren),
|
|
_ => Err(format!("Unexpected magic escape: {ch}")),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl TryFrom<[char; 2]> for IpyEscapeKind {
|
|
type Error = String;
|
|
|
|
fn try_from(ch: [char; 2]) -> Result<Self, Self::Error> {
|
|
match ch {
|
|
['!', '!'] => Ok(IpyEscapeKind::ShCap),
|
|
['?', '?'] => Ok(IpyEscapeKind::Help2),
|
|
['%', '%'] => Ok(IpyEscapeKind::Magic2),
|
|
[c1, c2] => Err(format!("Unexpected magic escape: {c1}{c2}")),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for IpyEscapeKind {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
f.write_str(self.as_str())
|
|
}
|
|
}
|
|
|
|
impl IpyEscapeKind {
|
|
/// Returns the length of the escape kind token.
|
|
pub fn prefix_len(self) -> TextSize {
|
|
let len = match self {
|
|
IpyEscapeKind::Shell
|
|
| IpyEscapeKind::Magic
|
|
| IpyEscapeKind::Help
|
|
| IpyEscapeKind::Quote
|
|
| IpyEscapeKind::Quote2
|
|
| IpyEscapeKind::Paren => 1,
|
|
IpyEscapeKind::ShCap | IpyEscapeKind::Magic2 | IpyEscapeKind::Help2 => 2,
|
|
};
|
|
len.into()
|
|
}
|
|
|
|
/// Returns `true` if the escape kind is help i.e., `?` or `??`.
|
|
pub const fn is_help(self) -> bool {
|
|
matches!(self, IpyEscapeKind::Help | IpyEscapeKind::Help2)
|
|
}
|
|
|
|
/// Returns `true` if the escape kind is magic i.e., `%` or `%%`.
|
|
pub const fn is_magic(self) -> bool {
|
|
matches!(self, IpyEscapeKind::Magic | IpyEscapeKind::Magic2)
|
|
}
|
|
|
|
pub fn as_str(self) -> &'static str {
|
|
match self {
|
|
IpyEscapeKind::Shell => "!",
|
|
IpyEscapeKind::ShCap => "!!",
|
|
IpyEscapeKind::Help => "?",
|
|
IpyEscapeKind::Help2 => "??",
|
|
IpyEscapeKind::Magic => "%",
|
|
IpyEscapeKind::Magic2 => "%%",
|
|
IpyEscapeKind::Quote => ",",
|
|
IpyEscapeKind::Quote2 => ";",
|
|
IpyEscapeKind::Paren => "/",
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
|
pub struct Identifier {
|
|
id: String,
|
|
range: TextRange,
|
|
}
|
|
|
|
impl Identifier {
|
|
#[inline]
|
|
pub fn new(id: impl Into<String>, range: TextRange) -> Self {
|
|
Self {
|
|
id: id.into(),
|
|
range,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Identifier {
|
|
#[inline]
|
|
pub fn as_str(&self) -> &str {
|
|
self.id.as_str()
|
|
}
|
|
}
|
|
|
|
impl PartialEq<str> for Identifier {
|
|
#[inline]
|
|
fn eq(&self, other: &str) -> bool {
|
|
self.id == other
|
|
}
|
|
}
|
|
|
|
impl PartialEq<String> for Identifier {
|
|
#[inline]
|
|
fn eq(&self, other: &String) -> bool {
|
|
&self.id == other
|
|
}
|
|
}
|
|
|
|
impl std::ops::Deref for Identifier {
|
|
type Target = str;
|
|
#[inline]
|
|
fn deref(&self) -> &Self::Target {
|
|
self.id.as_str()
|
|
}
|
|
}
|
|
|
|
impl AsRef<str> for Identifier {
|
|
#[inline]
|
|
fn as_ref(&self) -> &str {
|
|
self.id.as_str()
|
|
}
|
|
}
|
|
|
|
impl AsRef<String> for Identifier {
|
|
#[inline]
|
|
fn as_ref(&self) -> &String {
|
|
&self.id
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Display for Identifier {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
std::fmt::Display::fmt(&self.id, f)
|
|
}
|
|
}
|
|
|
|
impl From<Identifier> for String {
|
|
#[inline]
|
|
fn from(identifier: Identifier) -> String {
|
|
identifier.id
|
|
}
|
|
}
|
|
|
|
impl Ranged for Identifier {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
pub struct Int(u32);
|
|
|
|
impl Int {
|
|
pub fn new(i: u32) -> Self {
|
|
Self(i)
|
|
}
|
|
pub fn to_u32(&self) -> u32 {
|
|
self.0
|
|
}
|
|
pub fn to_usize(&self) -> usize {
|
|
self.0 as _
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<u32> for Int {
|
|
#[inline]
|
|
fn eq(&self, other: &u32) -> bool {
|
|
self.0 == *other
|
|
}
|
|
}
|
|
|
|
impl std::cmp::PartialEq<usize> for Int {
|
|
#[inline]
|
|
fn eq(&self, other: &usize) -> bool {
|
|
self.0 as usize == *other
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
|
|
pub enum Constant {
|
|
None,
|
|
Bool(bool),
|
|
Str(StringConstant),
|
|
Bytes(BytesConstant),
|
|
Int(BigInt),
|
|
Float(f64),
|
|
Complex { real: f64, imag: f64 },
|
|
Ellipsis,
|
|
}
|
|
|
|
impl Constant {
|
|
/// Returns `true` if the constant is a string or bytes constant that contains multiple,
|
|
/// implicitly concatenated string tokens.
|
|
pub fn is_implicit_concatenated(&self) -> bool {
|
|
match self {
|
|
Constant::Str(value) => value.implicit_concatenated,
|
|
Constant::Bytes(value) => value.implicit_concatenated,
|
|
_ => false,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
pub struct StringConstant {
|
|
/// The string value as resolved by the parser (i.e., without quotes, or escape sequences, or
|
|
/// implicit concatenations).
|
|
pub value: String,
|
|
/// Whether the string contains multiple string tokens that were implicitly concatenated.
|
|
pub implicit_concatenated: bool,
|
|
}
|
|
|
|
impl Deref for StringConstant {
|
|
type Target = str;
|
|
fn deref(&self) -> &Self::Target {
|
|
self.value.as_str()
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
pub struct BytesConstant {
|
|
/// The bytes value as resolved by the parser (i.e., without quotes, or escape sequences, or
|
|
/// implicit concatenations).
|
|
pub value: Vec<u8>,
|
|
/// Whether the string contains multiple string tokens that were implicitly concatenated.
|
|
pub implicit_concatenated: bool,
|
|
}
|
|
|
|
impl Deref for BytesConstant {
|
|
type Target = [u8];
|
|
fn deref(&self) -> &Self::Target {
|
|
self.value.as_slice()
|
|
}
|
|
}
|
|
|
|
impl From<Vec<u8>> for Constant {
|
|
fn from(value: Vec<u8>) -> Constant {
|
|
Self::Bytes(BytesConstant {
|
|
value,
|
|
implicit_concatenated: false,
|
|
})
|
|
}
|
|
}
|
|
impl From<String> for Constant {
|
|
fn from(value: String) -> Constant {
|
|
Self::Str(StringConstant {
|
|
value,
|
|
implicit_concatenated: false,
|
|
})
|
|
}
|
|
}
|
|
impl From<bool> for Constant {
|
|
fn from(value: bool) -> Constant {
|
|
Self::Bool(value)
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "rustpython-literal")]
|
|
impl std::fmt::Display for Constant {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Constant::None => f.pad("None"),
|
|
Constant::Bool(b) => f.pad(if *b { "True" } else { "False" }),
|
|
Constant::Str(s) => rustpython_literal::escape::UnicodeEscape::new_repr(s.as_str())
|
|
.str_repr()
|
|
.write(f),
|
|
Constant::Bytes(b) => {
|
|
let escape = rustpython_literal::escape::AsciiEscape::new_repr(b);
|
|
let repr = escape.bytes_repr().to_string().unwrap();
|
|
f.pad(&repr)
|
|
}
|
|
Constant::Int(i) => std::fmt::Display::fmt(&i, f),
|
|
Constant::Float(fp) => f.pad(&rustpython_literal::float::to_string(*fp)),
|
|
Constant::Complex { real, imag } => {
|
|
if *real == 0.0 {
|
|
write!(f, "{imag}j")
|
|
} else {
|
|
write!(f, "({real}{imag:+}j)")
|
|
}
|
|
}
|
|
Constant::Ellipsis => f.pad("..."),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Ranged for crate::nodes::ModModule {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ModExpression {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::Mod {
|
|
fn range(&self) -> TextRange {
|
|
match self {
|
|
Self::Module(node) => node.range(),
|
|
Self::Expression(node) => node.range(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Ranged for crate::nodes::StmtFunctionDef {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtClassDef {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtReturn {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtDelete {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtTypeAlias {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtAssign {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtAugAssign {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtAnnAssign {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtFor {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtWhile {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtIf {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ElifElseClause {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtWith {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtMatch {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtRaise {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtTry {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtAssert {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtImport {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtImportFrom {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtGlobal {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtNonlocal {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtExpr {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtPass {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtBreak {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtContinue {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::StmtIpyEscapeCommand {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::Stmt {
|
|
fn range(&self) -> TextRange {
|
|
match self {
|
|
Self::FunctionDef(node) => node.range(),
|
|
Self::ClassDef(node) => node.range(),
|
|
Self::Return(node) => node.range(),
|
|
Self::Delete(node) => node.range(),
|
|
Self::TypeAlias(node) => node.range(),
|
|
Self::Assign(node) => node.range(),
|
|
Self::AugAssign(node) => node.range(),
|
|
Self::AnnAssign(node) => node.range(),
|
|
Self::For(node) => node.range(),
|
|
Self::While(node) => node.range(),
|
|
Self::If(node) => node.range(),
|
|
Self::With(node) => node.range(),
|
|
Self::Match(node) => node.range(),
|
|
Self::Raise(node) => node.range(),
|
|
Self::Try(node) => node.range(),
|
|
Self::Assert(node) => node.range(),
|
|
Self::Import(node) => node.range(),
|
|
Self::ImportFrom(node) => node.range(),
|
|
Self::Global(node) => node.range(),
|
|
Self::Nonlocal(node) => node.range(),
|
|
Self::Expr(node) => node.range(),
|
|
Self::Pass(node) => node.range(),
|
|
Self::Break(node) => node.range(),
|
|
Self::Continue(node) => node.range(),
|
|
Stmt::IpyEscapeCommand(node) => node.range(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Ranged for crate::nodes::ExprBoolOp {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprNamedExpr {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprBinOp {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprUnaryOp {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprLambda {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprIfExp {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprDict {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprSet {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprListComp {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprSetComp {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprDictComp {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprGeneratorExp {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprAwait {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprYield {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprYieldFrom {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprCompare {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprCall {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprFormattedValue {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprFString {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprConstant {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprAttribute {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprSubscript {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprStarred {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprName {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprList {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprTuple {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprSlice {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExprIpyEscapeCommand {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::Expr {
|
|
fn range(&self) -> TextRange {
|
|
match self {
|
|
Self::BoolOp(node) => node.range(),
|
|
Self::NamedExpr(node) => node.range(),
|
|
Self::BinOp(node) => node.range(),
|
|
Self::UnaryOp(node) => node.range(),
|
|
Self::Lambda(node) => node.range(),
|
|
Self::IfExp(node) => node.range(),
|
|
Self::Dict(node) => node.range(),
|
|
Self::Set(node) => node.range(),
|
|
Self::ListComp(node) => node.range(),
|
|
Self::SetComp(node) => node.range(),
|
|
Self::DictComp(node) => node.range(),
|
|
Self::GeneratorExp(node) => node.range(),
|
|
Self::Await(node) => node.range(),
|
|
Self::Yield(node) => node.range(),
|
|
Self::YieldFrom(node) => node.range(),
|
|
Self::Compare(node) => node.range(),
|
|
Self::Call(node) => node.range(),
|
|
Self::FormattedValue(node) => node.range(),
|
|
Self::FString(node) => node.range(),
|
|
Self::Constant(node) => node.range(),
|
|
Self::Attribute(node) => node.range(),
|
|
Self::Subscript(node) => node.range(),
|
|
Self::Starred(node) => node.range(),
|
|
Self::Name(node) => node.range(),
|
|
Self::List(node) => node.range(),
|
|
Self::Tuple(node) => node.range(),
|
|
Self::Slice(node) => node.range(),
|
|
Expr::IpyEscapeCommand(node) => node.range(),
|
|
}
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::Comprehension {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ExceptHandlerExceptHandler {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::ExceptHandler {
|
|
fn range(&self) -> TextRange {
|
|
match self {
|
|
Self::ExceptHandler(node) => node.range(),
|
|
}
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::Parameter {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::Keyword {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::Alias {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::WithItem {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::MatchCase {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::PatternMatchValue {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::PatternMatchSingleton {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::PatternMatchSequence {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::PatternMatchMapping {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::PatternMatchClass {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::PatternMatchStar {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::PatternMatchAs {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::PatternMatchOr {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::Pattern {
|
|
fn range(&self) -> TextRange {
|
|
match self {
|
|
Self::MatchValue(node) => node.range(),
|
|
Self::MatchSingleton(node) => node.range(),
|
|
Self::MatchSequence(node) => node.range(),
|
|
Self::MatchMapping(node) => node.range(),
|
|
Self::MatchClass(node) => node.range(),
|
|
Self::MatchStar(node) => node.range(),
|
|
Self::MatchAs(node) => node.range(),
|
|
Self::MatchOr(node) => node.range(),
|
|
}
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::PatternArguments {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::PatternKeyword {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
|
|
impl Ranged for crate::nodes::TypeParams {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::TypeParamTypeVar {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::TypeParamTypeVarTuple {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::TypeParamParamSpec {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::TypeParam {
|
|
fn range(&self) -> TextRange {
|
|
match self {
|
|
Self::TypeVar(node) => node.range(),
|
|
Self::TypeVarTuple(node) => node.range(),
|
|
Self::ParamSpec(node) => node.range(),
|
|
}
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::Decorator {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::Arguments {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::Parameters {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl Ranged for crate::nodes::ParameterWithDefault {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
|
|
/// An expression that may be parenthesized.
|
|
#[derive(Clone, Debug)]
|
|
pub struct ParenthesizedExpr {
|
|
/// The range of the expression, including any parentheses.
|
|
pub range: TextRange,
|
|
/// The underlying expression.
|
|
pub expr: Expr,
|
|
}
|
|
impl Ranged for ParenthesizedExpr {
|
|
fn range(&self) -> TextRange {
|
|
self.range
|
|
}
|
|
}
|
|
impl From<Expr> for ParenthesizedExpr {
|
|
fn from(expr: Expr) -> Self {
|
|
ParenthesizedExpr {
|
|
range: expr.range(),
|
|
expr,
|
|
}
|
|
}
|
|
}
|
|
impl From<ParenthesizedExpr> for Expr {
|
|
fn from(parenthesized_expr: ParenthesizedExpr) -> Self {
|
|
parenthesized_expr.expr
|
|
}
|
|
}
|
|
impl From<ExprIpyEscapeCommand> for ParenthesizedExpr {
|
|
fn from(payload: ExprIpyEscapeCommand) -> Self {
|
|
Expr::IpyEscapeCommand(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprBoolOp> for ParenthesizedExpr {
|
|
fn from(payload: ExprBoolOp) -> Self {
|
|
Expr::BoolOp(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprNamedExpr> for ParenthesizedExpr {
|
|
fn from(payload: ExprNamedExpr) -> Self {
|
|
Expr::NamedExpr(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprBinOp> for ParenthesizedExpr {
|
|
fn from(payload: ExprBinOp) -> Self {
|
|
Expr::BinOp(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprUnaryOp> for ParenthesizedExpr {
|
|
fn from(payload: ExprUnaryOp) -> Self {
|
|
Expr::UnaryOp(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprLambda> for ParenthesizedExpr {
|
|
fn from(payload: ExprLambda) -> Self {
|
|
Expr::Lambda(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprIfExp> for ParenthesizedExpr {
|
|
fn from(payload: ExprIfExp) -> Self {
|
|
Expr::IfExp(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprDict> for ParenthesizedExpr {
|
|
fn from(payload: ExprDict) -> Self {
|
|
Expr::Dict(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprSet> for ParenthesizedExpr {
|
|
fn from(payload: ExprSet) -> Self {
|
|
Expr::Set(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprListComp> for ParenthesizedExpr {
|
|
fn from(payload: ExprListComp) -> Self {
|
|
Expr::ListComp(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprSetComp> for ParenthesizedExpr {
|
|
fn from(payload: ExprSetComp) -> Self {
|
|
Expr::SetComp(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprDictComp> for ParenthesizedExpr {
|
|
fn from(payload: ExprDictComp) -> Self {
|
|
Expr::DictComp(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprGeneratorExp> for ParenthesizedExpr {
|
|
fn from(payload: ExprGeneratorExp) -> Self {
|
|
Expr::GeneratorExp(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprAwait> for ParenthesizedExpr {
|
|
fn from(payload: ExprAwait) -> Self {
|
|
Expr::Await(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprYield> for ParenthesizedExpr {
|
|
fn from(payload: ExprYield) -> Self {
|
|
Expr::Yield(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprYieldFrom> for ParenthesizedExpr {
|
|
fn from(payload: ExprYieldFrom) -> Self {
|
|
Expr::YieldFrom(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprCompare> for ParenthesizedExpr {
|
|
fn from(payload: ExprCompare) -> Self {
|
|
Expr::Compare(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprCall> for ParenthesizedExpr {
|
|
fn from(payload: ExprCall) -> Self {
|
|
Expr::Call(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprFormattedValue> for ParenthesizedExpr {
|
|
fn from(payload: ExprFormattedValue) -> Self {
|
|
Expr::FormattedValue(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprFString> for ParenthesizedExpr {
|
|
fn from(payload: ExprFString) -> Self {
|
|
Expr::FString(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprConstant> for ParenthesizedExpr {
|
|
fn from(payload: ExprConstant) -> Self {
|
|
Expr::Constant(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprAttribute> for ParenthesizedExpr {
|
|
fn from(payload: ExprAttribute) -> Self {
|
|
Expr::Attribute(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprSubscript> for ParenthesizedExpr {
|
|
fn from(payload: ExprSubscript) -> Self {
|
|
Expr::Subscript(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprStarred> for ParenthesizedExpr {
|
|
fn from(payload: ExprStarred) -> Self {
|
|
Expr::Starred(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprName> for ParenthesizedExpr {
|
|
fn from(payload: ExprName) -> Self {
|
|
Expr::Name(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprList> for ParenthesizedExpr {
|
|
fn from(payload: ExprList) -> Self {
|
|
Expr::List(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprTuple> for ParenthesizedExpr {
|
|
fn from(payload: ExprTuple) -> Self {
|
|
Expr::Tuple(payload).into()
|
|
}
|
|
}
|
|
impl From<ExprSlice> for ParenthesizedExpr {
|
|
fn from(payload: ExprSlice) -> Self {
|
|
Expr::Slice(payload).into()
|
|
}
|
|
}
|
|
|
|
#[cfg(target_pointer_width = "64")]
|
|
mod size_assertions {
|
|
use static_assertions::assert_eq_size;
|
|
|
|
#[allow(clippy::wildcard_imports)]
|
|
use super::*;
|
|
|
|
assert_eq_size!(Stmt, [u8; 144]);
|
|
assert_eq_size!(StmtFunctionDef, [u8; 144]);
|
|
assert_eq_size!(StmtClassDef, [u8; 104]);
|
|
assert_eq_size!(StmtTry, [u8; 112]);
|
|
assert_eq_size!(Expr, [u8; 80]);
|
|
assert_eq_size!(Constant, [u8; 40]);
|
|
assert_eq_size!(Pattern, [u8; 96]);
|
|
assert_eq_size!(Mod, [u8; 32]);
|
|
}
|