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:
Charlie Marsh 2023-08-02 10:01:13 -04:00 committed by GitHub
parent 0d62ad2480
commit 981e64f82b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
107 changed files with 24258 additions and 23835 deletions

View file

@ -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,