mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-27 12:29:28 +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
|
@ -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]);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue