mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:38:25 +00:00
Introduce an Arguments
AST node for function calls and class definitions (#6259)
## Summary This PR adds a new `Arguments` AST node, which we can use for function calls and class definitions. The `Arguments` node spans from the left (open) to right (close) parentheses inclusive. In the case of classes, the `Arguments` is an option, to differentiate between: ```python # None class C: ... # Some, with empty vectors class C(): ... ``` In this PR, we don't really leverage this change (except that a few rules get much simpler, since we don't need to lex to find the start and end ranges of the parentheses, e.g., `crates/ruff/src/rules/pyupgrade/rules/lru_cache_without_parameters.rs`, `crates/ruff/src/rules/pyupgrade/rules/unnecessary_class_parentheses.rs`). In future PRs, this will be especially helpful for the formatter, since we can track comments enclosed on the node itself. ## Test Plan `cargo test`
This commit is contained in:
parent
0d62ad2480
commit
981e64f82b
107 changed files with 24258 additions and 23835 deletions
|
@ -64,8 +64,7 @@ where
|
|||
}
|
||||
Expr::Call(ast::ExprCall {
|
||||
func,
|
||||
args,
|
||||
keywords,
|
||||
arguments: ast::Arguments { args, keywords, .. },
|
||||
..
|
||||
}) => {
|
||||
// Allow `tuple()`, `list()`, and their generic forms, like `list[int]()`.
|
||||
|
|
|
@ -339,6 +339,27 @@ impl<'a> From<&'a ast::Constant> for ComparableConstant<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ComparableArguments<'a> {
|
||||
args: Vec<ComparableExpr<'a>>,
|
||||
keywords: Vec<ComparableKeyword<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a ast::Arguments> for ComparableArguments<'a> {
|
||||
fn from(arguments: &'a ast::Arguments) -> Self {
|
||||
Self {
|
||||
args: arguments.args.iter().map(Into::into).collect(),
|
||||
keywords: arguments.keywords.iter().map(Into::into).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Box<ast::Arguments>> for ComparableArguments<'a> {
|
||||
fn from(arguments: &'a Box<ast::Arguments>) -> Self {
|
||||
(arguments.as_ref()).into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ComparableParameters<'a> {
|
||||
posonlyargs: Vec<ComparableParameterWithDefault<'a>>,
|
||||
|
@ -583,8 +604,7 @@ pub struct ExprCompare<'a> {
|
|||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ExprCall<'a> {
|
||||
func: Box<ComparableExpr<'a>>,
|
||||
args: Vec<ComparableExpr<'a>>,
|
||||
keywords: Vec<ComparableKeyword<'a>>,
|
||||
arguments: ComparableArguments<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
|
@ -837,13 +857,11 @@ impl<'a> From<&'a ast::Expr> for ComparableExpr<'a> {
|
|||
}),
|
||||
ast::Expr::Call(ast::ExprCall {
|
||||
func,
|
||||
args,
|
||||
keywords,
|
||||
arguments,
|
||||
range: _range,
|
||||
}) => Self::Call(ExprCall {
|
||||
func: func.into(),
|
||||
args: args.iter().map(Into::into).collect(),
|
||||
keywords: keywords.iter().map(Into::into).collect(),
|
||||
arguments: arguments.into(),
|
||||
}),
|
||||
ast::Expr::FormattedValue(ast::ExprFormattedValue {
|
||||
value,
|
||||
|
@ -968,8 +986,7 @@ pub struct StmtAsyncFunctionDef<'a> {
|
|||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct StmtClassDef<'a> {
|
||||
name: &'a str,
|
||||
bases: Vec<ComparableExpr<'a>>,
|
||||
keywords: Vec<ComparableKeyword<'a>>,
|
||||
arguments: Option<ComparableArguments<'a>>,
|
||||
body: Vec<ComparableStmt<'a>>,
|
||||
decorator_list: Vec<ComparableDecorator<'a>>,
|
||||
type_params: Vec<ComparableTypeParam<'a>>,
|
||||
|
@ -1240,16 +1257,14 @@ impl<'a> From<&'a ast::Stmt> for ComparableStmt<'a> {
|
|||
}),
|
||||
ast::Stmt::ClassDef(ast::StmtClassDef {
|
||||
name,
|
||||
bases,
|
||||
keywords,
|
||||
arguments,
|
||||
body,
|
||||
decorator_list,
|
||||
type_params,
|
||||
range: _range,
|
||||
}) => Self::ClassDef(StmtClassDef {
|
||||
name: name.as_str(),
|
||||
bases: bases.iter().map(Into::into).collect(),
|
||||
keywords: keywords.iter().map(Into::into).collect(),
|
||||
arguments: arguments.as_ref().map(Into::into),
|
||||
body: body.iter().map(Into::into).collect(),
|
||||
decorator_list: decorator_list.iter().map(Into::into).collect(),
|
||||
type_params: type_params.iter().map(Into::into).collect(),
|
||||
|
|
|
@ -2,8 +2,8 @@ use std::borrow::Cow;
|
|||
use std::path::Path;
|
||||
|
||||
use crate::{
|
||||
self as ast, Constant, ExceptHandler, Expr, Keyword, MatchCase, Parameters, Pattern, Ranged,
|
||||
Stmt, TypeParam,
|
||||
self as ast, Arguments, Constant, ExceptHandler, Expr, Keyword, MatchCase, Parameters, Pattern,
|
||||
Ranged, Stmt, TypeParam,
|
||||
};
|
||||
use num_traits::Zero;
|
||||
use ruff_text_size::TextRange;
|
||||
|
@ -50,8 +50,7 @@ where
|
|||
// Accept empty initializers.
|
||||
if let Expr::Call(ast::ExprCall {
|
||||
func,
|
||||
args,
|
||||
keywords,
|
||||
arguments: Arguments { args, keywords, .. },
|
||||
range: _range,
|
||||
}) = expr
|
||||
{
|
||||
|
@ -237,8 +236,7 @@ where
|
|||
}) => any_over_expr(left, func) || comparators.iter().any(|expr| any_over_expr(expr, func)),
|
||||
Expr::Call(ast::ExprCall {
|
||||
func: call_func,
|
||||
args,
|
||||
keywords,
|
||||
arguments: Arguments { args, keywords, .. },
|
||||
range: _range,
|
||||
}) => {
|
||||
any_over_expr(call_func, func)
|
||||
|
@ -396,16 +394,19 @@ where
|
|||
.is_some_and(|value| any_over_expr(value, func))
|
||||
}
|
||||
Stmt::ClassDef(ast::StmtClassDef {
|
||||
bases,
|
||||
keywords,
|
||||
arguments,
|
||||
body,
|
||||
decorator_list,
|
||||
..
|
||||
}) => {
|
||||
bases.iter().any(|expr| any_over_expr(expr, func))
|
||||
|| keywords
|
||||
.iter()
|
||||
.any(|keyword| any_over_expr(&keyword.value, func))
|
||||
arguments
|
||||
.as_ref()
|
||||
.is_some_and(|Arguments { args, keywords, .. }| {
|
||||
args.iter().any(|expr| any_over_expr(expr, func))
|
||||
|| keywords
|
||||
.iter()
|
||||
.any(|keyword| any_over_expr(&keyword.value, func))
|
||||
})
|
||||
|| body.iter().any(|stmt| any_over_stmt(stmt, func))
|
||||
|| decorator_list
|
||||
.iter()
|
||||
|
@ -640,6 +641,8 @@ pub fn is_constant_non_singleton(expr: &Expr) -> bool {
|
|||
|
||||
/// Return the [`Keyword`] with the given name, if it's present in the list of
|
||||
/// [`Keyword`] arguments.
|
||||
///
|
||||
/// TODO(charlie): Make this an associated function on [`Arguments`].
|
||||
pub fn find_keyword<'a>(keywords: &'a [Keyword], keyword_name: &str) -> Option<&'a Keyword> {
|
||||
keywords.iter().find(|keyword| {
|
||||
let Keyword { arg, .. } = keyword;
|
||||
|
@ -1229,30 +1232,14 @@ impl Truthiness {
|
|||
None
|
||||
}
|
||||
}
|
||||
Expr::List(ast::ExprList {
|
||||
elts,
|
||||
range: _range,
|
||||
..
|
||||
})
|
||||
| Expr::Set(ast::ExprSet {
|
||||
elts,
|
||||
range: _range,
|
||||
})
|
||||
| Expr::Tuple(ast::ExprTuple {
|
||||
elts,
|
||||
range: _range,
|
||||
..
|
||||
}) => Some(!elts.is_empty()),
|
||||
Expr::Dict(ast::ExprDict {
|
||||
keys,
|
||||
range: _range,
|
||||
..
|
||||
}) => Some(!keys.is_empty()),
|
||||
Expr::List(ast::ExprList { elts, .. })
|
||||
| Expr::Set(ast::ExprSet { elts, .. })
|
||||
| Expr::Tuple(ast::ExprTuple { elts, .. }) => Some(!elts.is_empty()),
|
||||
Expr::Dict(ast::ExprDict { keys, .. }) => Some(!keys.is_empty()),
|
||||
Expr::Call(ast::ExprCall {
|
||||
func,
|
||||
args,
|
||||
keywords,
|
||||
range: _range,
|
||||
arguments: Arguments { args, keywords, .. },
|
||||
..
|
||||
}) => {
|
||||
if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() {
|
||||
if is_iterable_initializer(id.as_str(), |id| is_builtin(id)) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
self as ast, Alias, Comprehension, Decorator, ExceptHandler, Expr, Keyword, MatchCase, Mod,
|
||||
Parameter, ParameterWithDefault, Parameters, Pattern, Ranged, Stmt, TypeParam,
|
||||
self as ast, Alias, Arguments, Comprehension, Decorator, ExceptHandler, Expr, Keyword,
|
||||
MatchCase, Mod, Parameter, ParameterWithDefault, Parameters, Pattern, Ranged, Stmt, TypeParam,
|
||||
TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple, WithItem,
|
||||
};
|
||||
use ruff_text_size::TextRange;
|
||||
|
@ -90,6 +90,7 @@ pub enum AnyNode {
|
|||
PatternMatchAs(ast::PatternMatchAs),
|
||||
PatternMatchOr(ast::PatternMatchOr),
|
||||
Comprehension(Comprehension),
|
||||
Arguments(Arguments),
|
||||
Parameters(Parameters),
|
||||
Parameter(Parameter),
|
||||
ParameterWithDefault(ParameterWithDefault),
|
||||
|
@ -177,6 +178,7 @@ impl AnyNode {
|
|||
| AnyNode::PatternMatchAs(_)
|
||||
| AnyNode::PatternMatchOr(_)
|
||||
| AnyNode::Comprehension(_)
|
||||
| AnyNode::Arguments(_)
|
||||
| AnyNode::Parameters(_)
|
||||
| AnyNode::Parameter(_)
|
||||
| AnyNode::ParameterWithDefault(_)
|
||||
|
@ -264,6 +266,7 @@ impl AnyNode {
|
|||
| AnyNode::PatternMatchAs(_)
|
||||
| AnyNode::PatternMatchOr(_)
|
||||
| AnyNode::Comprehension(_)
|
||||
| AnyNode::Arguments(_)
|
||||
| AnyNode::Parameters(_)
|
||||
| AnyNode::Parameter(_)
|
||||
| AnyNode::ParameterWithDefault(_)
|
||||
|
@ -351,6 +354,7 @@ impl AnyNode {
|
|||
| AnyNode::PatternMatchAs(_)
|
||||
| AnyNode::PatternMatchOr(_)
|
||||
| AnyNode::Comprehension(_)
|
||||
| AnyNode::Arguments(_)
|
||||
| AnyNode::Parameters(_)
|
||||
| AnyNode::Parameter(_)
|
||||
| AnyNode::ParameterWithDefault(_)
|
||||
|
@ -438,6 +442,7 @@ impl AnyNode {
|
|||
| AnyNode::ExprLineMagic(_)
|
||||
| AnyNode::ExceptHandlerExceptHandler(_)
|
||||
| AnyNode::Comprehension(_)
|
||||
| AnyNode::Arguments(_)
|
||||
| AnyNode::Parameters(_)
|
||||
| AnyNode::Parameter(_)
|
||||
| AnyNode::ParameterWithDefault(_)
|
||||
|
@ -525,6 +530,7 @@ impl AnyNode {
|
|||
| AnyNode::PatternMatchAs(_)
|
||||
| AnyNode::PatternMatchOr(_)
|
||||
| AnyNode::Comprehension(_)
|
||||
| AnyNode::Arguments(_)
|
||||
| AnyNode::Parameters(_)
|
||||
| AnyNode::Parameter(_)
|
||||
| AnyNode::ParameterWithDefault(_)
|
||||
|
@ -631,6 +637,7 @@ impl AnyNode {
|
|||
Self::PatternMatchAs(node) => AnyNodeRef::PatternMatchAs(node),
|
||||
Self::PatternMatchOr(node) => AnyNodeRef::PatternMatchOr(node),
|
||||
Self::Comprehension(node) => AnyNodeRef::Comprehension(node),
|
||||
Self::Arguments(node) => AnyNodeRef::Arguments(node),
|
||||
Self::Parameters(node) => AnyNodeRef::Parameters(node),
|
||||
Self::Parameter(node) => AnyNodeRef::Parameter(node),
|
||||
Self::ParameterWithDefault(node) => AnyNodeRef::ParameterWithDefault(node),
|
||||
|
@ -3574,6 +3581,7 @@ impl Ranged for AnyNode {
|
|||
AnyNode::PatternMatchAs(node) => node.range(),
|
||||
AnyNode::PatternMatchOr(node) => node.range(),
|
||||
AnyNode::Comprehension(node) => node.range(),
|
||||
AnyNode::Arguments(node) => node.range(),
|
||||
AnyNode::Parameters(node) => node.range(),
|
||||
AnyNode::Parameter(node) => node.range(),
|
||||
AnyNode::ParameterWithDefault(node) => node.range(),
|
||||
|
@ -3661,6 +3669,7 @@ pub enum AnyNodeRef<'a> {
|
|||
PatternMatchAs(&'a ast::PatternMatchAs),
|
||||
PatternMatchOr(&'a ast::PatternMatchOr),
|
||||
Comprehension(&'a Comprehension),
|
||||
Arguments(&'a Arguments),
|
||||
Parameters(&'a Parameters),
|
||||
Parameter(&'a Parameter),
|
||||
ParameterWithDefault(&'a ParameterWithDefault),
|
||||
|
@ -3747,6 +3756,7 @@ impl AnyNodeRef<'_> {
|
|||
AnyNodeRef::PatternMatchAs(node) => NonNull::from(*node).cast(),
|
||||
AnyNodeRef::PatternMatchOr(node) => NonNull::from(*node).cast(),
|
||||
AnyNodeRef::Comprehension(node) => NonNull::from(*node).cast(),
|
||||
AnyNodeRef::Arguments(node) => NonNull::from(*node).cast(),
|
||||
AnyNodeRef::Parameters(node) => NonNull::from(*node).cast(),
|
||||
AnyNodeRef::Parameter(node) => NonNull::from(*node).cast(),
|
||||
AnyNodeRef::ParameterWithDefault(node) => NonNull::from(*node).cast(),
|
||||
|
@ -3839,6 +3849,7 @@ impl AnyNodeRef<'_> {
|
|||
AnyNodeRef::PatternMatchAs(_) => NodeKind::PatternMatchAs,
|
||||
AnyNodeRef::PatternMatchOr(_) => NodeKind::PatternMatchOr,
|
||||
AnyNodeRef::Comprehension(_) => NodeKind::Comprehension,
|
||||
AnyNodeRef::Arguments(_) => NodeKind::Arguments,
|
||||
AnyNodeRef::Parameters(_) => NodeKind::Parameters,
|
||||
AnyNodeRef::Parameter(_) => NodeKind::Parameter,
|
||||
AnyNodeRef::ParameterWithDefault(_) => NodeKind::ParameterWithDefault,
|
||||
|
@ -3926,6 +3937,7 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::PatternMatchAs(_)
|
||||
| AnyNodeRef::PatternMatchOr(_)
|
||||
| AnyNodeRef::Comprehension(_)
|
||||
| AnyNodeRef::Arguments(_)
|
||||
| AnyNodeRef::Parameters(_)
|
||||
| AnyNodeRef::Parameter(_)
|
||||
| AnyNodeRef::ParameterWithDefault(_)
|
||||
|
@ -4013,6 +4025,7 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::PatternMatchAs(_)
|
||||
| AnyNodeRef::PatternMatchOr(_)
|
||||
| AnyNodeRef::Comprehension(_)
|
||||
| AnyNodeRef::Arguments(_)
|
||||
| AnyNodeRef::Parameters(_)
|
||||
| AnyNodeRef::Parameter(_)
|
||||
| AnyNodeRef::ParameterWithDefault(_)
|
||||
|
@ -4099,6 +4112,7 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::PatternMatchAs(_)
|
||||
| AnyNodeRef::PatternMatchOr(_)
|
||||
| AnyNodeRef::Comprehension(_)
|
||||
| AnyNodeRef::Arguments(_)
|
||||
| AnyNodeRef::Parameters(_)
|
||||
| AnyNodeRef::Parameter(_)
|
||||
| AnyNodeRef::ParameterWithDefault(_)
|
||||
|
@ -4186,6 +4200,7 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::ExprLineMagic(_)
|
||||
| AnyNodeRef::ExceptHandlerExceptHandler(_)
|
||||
| AnyNodeRef::Comprehension(_)
|
||||
| AnyNodeRef::Arguments(_)
|
||||
| AnyNodeRef::Parameters(_)
|
||||
| AnyNodeRef::Parameter(_)
|
||||
| AnyNodeRef::ParameterWithDefault(_)
|
||||
|
@ -4273,6 +4288,7 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::PatternMatchAs(_)
|
||||
| AnyNodeRef::PatternMatchOr(_)
|
||||
| AnyNodeRef::Comprehension(_)
|
||||
| AnyNodeRef::Arguments(_)
|
||||
| AnyNodeRef::Parameters(_)
|
||||
| AnyNodeRef::Parameter(_)
|
||||
| AnyNodeRef::ParameterWithDefault(_)
|
||||
|
@ -4985,6 +5001,7 @@ impl Ranged for AnyNodeRef<'_> {
|
|||
AnyNodeRef::PatternMatchAs(node) => node.range(),
|
||||
AnyNodeRef::PatternMatchOr(node) => node.range(),
|
||||
AnyNodeRef::Comprehension(node) => node.range(),
|
||||
AnyNodeRef::Arguments(node) => node.range(),
|
||||
AnyNodeRef::Parameters(node) => node.range(),
|
||||
AnyNodeRef::Parameter(node) => node.range(),
|
||||
AnyNodeRef::ParameterWithDefault(node) => node.range(),
|
||||
|
@ -5075,6 +5092,7 @@ pub enum NodeKind {
|
|||
PatternMatchOr,
|
||||
TypeIgnoreTypeIgnore,
|
||||
Comprehension,
|
||||
Arguments,
|
||||
Parameters,
|
||||
Parameter,
|
||||
ParameterWithDefault,
|
||||
|
|
|
@ -158,13 +158,32 @@ impl From<StmtAsyncFunctionDef> for Stmt {
|
|||
pub struct StmtClassDef {
|
||||
pub range: TextRange,
|
||||
pub name: Identifier,
|
||||
pub bases: Vec<Expr>,
|
||||
pub keywords: Vec<Keyword>,
|
||||
pub arguments: Option<Arguments>,
|
||||
pub body: Vec<Stmt>,
|
||||
pub type_params: Vec<TypeParam>,
|
||||
pub decorator_list: Vec<Decorator>,
|
||||
}
|
||||
|
||||
impl StmtClassDef {
|
||||
/// Return an iterator over the bases of the class.
|
||||
pub fn bases(&self) -> impl Iterator<Item = &Expr> {
|
||||
self.arguments
|
||||
.as_ref()
|
||||
.map(|arguments| &arguments.args)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
}
|
||||
|
||||
/// Return an iterator over the metaclass keywords of the class.
|
||||
pub fn keywords(&self) -> impl Iterator<Item = &Keyword> {
|
||||
self.arguments
|
||||
.as_ref()
|
||||
.map(|arguments| &arguments.keywords)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<StmtClassDef> for Stmt {
|
||||
fn from(payload: StmtClassDef) -> Self {
|
||||
Stmt::ClassDef(payload)
|
||||
|
@ -836,8 +855,7 @@ impl From<ExprCompare> for Expr {
|
|||
pub struct ExprCall {
|
||||
pub range: TextRange,
|
||||
pub func: Box<Expr>,
|
||||
pub args: Vec<Expr>,
|
||||
pub keywords: Vec<Keyword>,
|
||||
pub arguments: Arguments,
|
||||
}
|
||||
|
||||
impl From<ExprCall> for Expr {
|
||||
|
@ -2073,6 +2091,35 @@ pub struct ParameterWithDefault {
|
|||
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>,
|
||||
}
|
||||
|
||||
pub type Suite = Vec<Stmt>;
|
||||
|
||||
impl CmpOp {
|
||||
|
@ -2934,6 +2981,11 @@ impl Ranged for crate::nodes::Decorator {
|
|||
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
|
||||
|
@ -2951,9 +3003,9 @@ mod size_assertions {
|
|||
use super::*;
|
||||
use static_assertions::assert_eq_size;
|
||||
|
||||
assert_eq_size!(Stmt, [u8; 168]);
|
||||
assert_eq_size!(Stmt, [u8; 176]);
|
||||
assert_eq_size!(StmtFunctionDef, [u8; 128]);
|
||||
assert_eq_size!(StmtClassDef, [u8; 160]);
|
||||
assert_eq_size!(StmtClassDef, [u8; 168]);
|
||||
assert_eq_size!(StmtTry, [u8; 104]);
|
||||
assert_eq_size!(Expr, [u8; 80]);
|
||||
assert_eq_size!(Constant, [u8; 32]);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{nodes, Expr, Keyword};
|
||||
use crate::{nodes, Arguments, Expr, Keyword};
|
||||
use ruff_text_size::TextRange;
|
||||
|
||||
fn relocate_keyword(keyword: &mut Keyword, location: TextRange) {
|
||||
|
@ -116,8 +116,7 @@ pub fn relocate_expr(expr: &mut Expr, location: TextRange) {
|
|||
}
|
||||
Expr::Call(nodes::ExprCall {
|
||||
func,
|
||||
args,
|
||||
keywords,
|
||||
arguments: Arguments { args, keywords, .. },
|
||||
range,
|
||||
}) => {
|
||||
*range = location;
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
pub mod preorder;
|
||||
|
||||
use crate::{
|
||||
self as ast, Alias, BoolOp, CmpOp, Comprehension, Decorator, ElifElseClause, ExceptHandler,
|
||||
Expr, ExprContext, Keyword, MatchCase, Operator, Parameter, Parameters, Pattern, Stmt,
|
||||
TypeParam, TypeParamTypeVar, UnaryOp, WithItem,
|
||||
self as ast, Alias, Arguments, BoolOp, CmpOp, Comprehension, Decorator, ElifElseClause,
|
||||
ExceptHandler, Expr, ExprContext, Keyword, MatchCase, Operator, Parameter, Parameters, Pattern,
|
||||
Stmt, TypeParam, TypeParamTypeVar, UnaryOp, WithItem,
|
||||
};
|
||||
|
||||
/// A trait for AST visitors. Visits all nodes in the AST recursively in evaluation-order.
|
||||
|
@ -52,6 +52,9 @@ pub trait Visitor<'a> {
|
|||
fn visit_format_spec(&mut self, format_spec: &'a Expr) {
|
||||
walk_format_spec(self, format_spec);
|
||||
}
|
||||
fn visit_arguments(&mut self, arguments: &'a Arguments) {
|
||||
walk_arguments(self, arguments);
|
||||
}
|
||||
fn visit_parameters(&mut self, parameters: &'a Parameters) {
|
||||
walk_parameters(self, parameters);
|
||||
}
|
||||
|
@ -143,8 +146,7 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) {
|
|||
visitor.visit_body(body);
|
||||
}
|
||||
Stmt::ClassDef(ast::StmtClassDef {
|
||||
bases,
|
||||
keywords,
|
||||
arguments,
|
||||
body,
|
||||
decorator_list,
|
||||
type_params,
|
||||
|
@ -156,11 +158,8 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) {
|
|||
for type_param in type_params {
|
||||
visitor.visit_type_param(type_param);
|
||||
}
|
||||
for expr in bases {
|
||||
visitor.visit_expr(expr);
|
||||
}
|
||||
for keyword in keywords {
|
||||
visitor.visit_keyword(keyword);
|
||||
if let Some(arguments) = arguments {
|
||||
visitor.visit_arguments(arguments);
|
||||
}
|
||||
visitor.visit_body(body);
|
||||
}
|
||||
|
@ -522,17 +521,11 @@ pub fn walk_expr<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, expr: &'a Expr) {
|
|||
}
|
||||
Expr::Call(ast::ExprCall {
|
||||
func,
|
||||
args,
|
||||
keywords,
|
||||
arguments,
|
||||
range: _range,
|
||||
}) => {
|
||||
visitor.visit_expr(func);
|
||||
for expr in args {
|
||||
visitor.visit_expr(expr);
|
||||
}
|
||||
for keyword in keywords {
|
||||
visitor.visit_keyword(keyword);
|
||||
}
|
||||
visitor.visit_arguments(arguments);
|
||||
}
|
||||
Expr::FormattedValue(ast::ExprFormattedValue {
|
||||
value, format_spec, ..
|
||||
|
@ -645,6 +638,15 @@ pub fn walk_format_spec<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, format_spe
|
|||
visitor.visit_expr(format_spec);
|
||||
}
|
||||
|
||||
pub fn walk_arguments<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, arguments: &'a Arguments) {
|
||||
for arg in &arguments.args {
|
||||
visitor.visit_expr(arg);
|
||||
}
|
||||
for keyword in &arguments.keywords {
|
||||
visitor.visit_keyword(keyword);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_parameters<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, parameters: &'a Parameters) {
|
||||
// Defaults are evaluated before annotations.
|
||||
for arg in ¶meters.posonlyargs {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use crate::{
|
||||
self as ast, Alias, BoolOp, CmpOp, Comprehension, Constant, Decorator, ElifElseClause,
|
||||
ExceptHandler, Expr, Keyword, MatchCase, Mod, Operator, Parameter, ParameterWithDefault,
|
||||
Parameters, Pattern, Stmt, TypeParam, TypeParamTypeVar, UnaryOp, WithItem,
|
||||
self as ast, Alias, Arguments, BoolOp, CmpOp, Comprehension, Constant, Decorator,
|
||||
ElifElseClause, ExceptHandler, Expr, Keyword, MatchCase, Mod, Operator, Parameter,
|
||||
ParameterWithDefault, Parameters, Pattern, Stmt, TypeParam, TypeParamTypeVar, UnaryOp,
|
||||
WithItem,
|
||||
};
|
||||
|
||||
/// Visitor that traverses all nodes recursively in pre-order.
|
||||
|
@ -56,6 +57,10 @@ pub trait PreorderVisitor<'a> {
|
|||
walk_format_spec(self, format_spec);
|
||||
}
|
||||
|
||||
fn visit_arguments(&mut self, arguments: &'a Arguments) {
|
||||
walk_arguments(self, arguments);
|
||||
}
|
||||
|
||||
fn visit_parameters(&mut self, parameters: &'a Parameters) {
|
||||
walk_parameters(self, parameters);
|
||||
}
|
||||
|
@ -166,8 +171,7 @@ where
|
|||
}
|
||||
|
||||
Stmt::ClassDef(ast::StmtClassDef {
|
||||
bases,
|
||||
keywords,
|
||||
arguments,
|
||||
body,
|
||||
decorator_list,
|
||||
type_params,
|
||||
|
@ -181,12 +185,8 @@ where
|
|||
visitor.visit_type_param(type_param);
|
||||
}
|
||||
|
||||
for expr in bases {
|
||||
visitor.visit_expr(expr);
|
||||
}
|
||||
|
||||
for keyword in keywords {
|
||||
visitor.visit_keyword(keyword);
|
||||
if let Some(arguments) = arguments {
|
||||
visitor.visit_arguments(arguments);
|
||||
}
|
||||
|
||||
visitor.visit_body(body);
|
||||
|
@ -592,17 +592,11 @@ where
|
|||
|
||||
Expr::Call(ast::ExprCall {
|
||||
func,
|
||||
args,
|
||||
keywords,
|
||||
arguments,
|
||||
range: _range,
|
||||
}) => {
|
||||
visitor.visit_expr(func);
|
||||
for expr in args {
|
||||
visitor.visit_expr(expr);
|
||||
}
|
||||
for keyword in keywords {
|
||||
visitor.visit_keyword(keyword);
|
||||
}
|
||||
visitor.visit_arguments(arguments);
|
||||
}
|
||||
|
||||
Expr::FormattedValue(ast::ExprFormattedValue {
|
||||
|
@ -749,6 +743,19 @@ pub fn walk_format_spec<'a, V: PreorderVisitor<'a> + ?Sized>(
|
|||
visitor.visit_expr(format_spec);
|
||||
}
|
||||
|
||||
pub fn walk_arguments<'a, V>(visitor: &mut V, arguments: &'a Arguments)
|
||||
where
|
||||
V: PreorderVisitor<'a> + ?Sized,
|
||||
{
|
||||
for arg in &arguments.args {
|
||||
visitor.visit_expr(arg);
|
||||
}
|
||||
|
||||
for keyword in &arguments.keywords {
|
||||
visitor.visit_keyword(keyword);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_parameters<'a, V>(visitor: &mut V, parameters: &'a Parameters)
|
||||
where
|
||||
V: PreorderVisitor<'a> + ?Sized,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue