Make Arguments boxed

This commit is contained in:
Charlie Marsh 2024-02-09 21:54:57 -05:00
parent 7a349660e4
commit 4e23ee0e1d
48 changed files with 203 additions and 314 deletions

View File

@ -343,15 +343,16 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
Expr::Call(
call @ ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
arguments,
range: _,
},
) => {
let Arguments {
args,
keywords,
range: _,
} = &**arguments;
if checker.any_enabled(&[
// pylint
Rule::BadStringFormatCharacter,

View File

@ -57,7 +57,7 @@ fn assertion_error(msg: Option<&Expr>) -> Stmt {
ctx: ExprContext::Load,
range: TextRange::default(),
})),
arguments: Arguments {
arguments: Box::new(Arguments {
args: if let Some(msg) = msg {
Box::from([msg.clone()])
} else {
@ -65,7 +65,7 @@ fn assertion_error(msg: Option<&Expr>) -> Stmt {
},
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
}))),
cause: None,

View File

@ -1,7 +1,7 @@
use ruff_diagnostics::{AlwaysFixableViolation, Applicability, Diagnostic, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{self as ast, Arguments, Expr};
use ruff_python_ast::{self as ast, Expr};
use ruff_python_semantic::SemanticModel;
use ruff_text_size::Ranged;
@ -91,9 +91,7 @@ pub(crate) fn zip_without_explicit_strict(checker: &mut Checker, call: &ast::Exp
/// `itertools.cycle` or similar).
fn is_infinite_iterator(arg: &Expr, semantic: &SemanticModel) -> bool {
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, keywords, .. },
..
func, arguments, ..
}) = &arg
else {
return false;
@ -104,17 +102,17 @@ fn is_infinite_iterator(arg: &Expr, semantic: &SemanticModel) -> bool {
["itertools", "cycle" | "count"] => true,
["itertools", "repeat"] => {
// Ex) `itertools.repeat(1)`
if keywords.is_empty() && args.len() == 1 {
if arguments.keywords.is_empty() && arguments.args.len() == 1 {
return true;
}
// Ex) `itertools.repeat(1, None)`
if args.len() == 2 && args[1].is_none_literal_expr() {
if arguments.args.len() == 2 && arguments.args[1].is_none_literal_expr() {
return true;
}
// Ex) `iterools.repeat(1, times=None)`
for keyword in keywords.iter() {
for keyword in arguments.keywords.iter() {
if keyword.arg.as_ref().is_some_and(|name| name == "times") {
if keyword.value.is_none_literal_expr() {
return true;

View File

@ -1,7 +1,7 @@
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::comparable::ComparableKeyword;
use ruff_python_ast::{self as ast, Arguments, Expr, Keyword};
use ruff_python_ast::{self as ast, Expr, Keyword};
use ruff_text_size::Ranged;
use crate::checkers::ast::Checker;
@ -84,11 +84,7 @@ pub(crate) fn unnecessary_double_cast_or_process(
return;
};
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments {
keywords: inner_kw, ..
},
..
func, arguments, ..
}) = arg
else {
return;
@ -103,10 +99,10 @@ pub(crate) fn unnecessary_double_cast_or_process(
// Avoid collapsing nested `sorted` calls with non-identical keyword arguments
// (i.e., `key`, `reverse`).
if &*inner.id == "sorted" && &*outer.id == "sorted" {
if inner_kw.len() != outer_kw.len() {
if arguments.keywords.len() != outer_kw.len() {
return;
}
if !inner_kw.iter().all(|inner| {
if !arguments.keywords.iter().all(|inner| {
outer_kw
.iter()
.any(|outer| ComparableKeyword::from(inner) == ComparableKeyword::from(outer))

View File

@ -5,7 +5,7 @@ use ruff_diagnostics::{FixAvailability, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::visitor;
use ruff_python_ast::visitor::Visitor;
use ruff_python_ast::{self as ast, Arguments, Expr, ExprContext, Parameters, Stmt};
use ruff_python_ast::{self as ast, Expr, ExprContext, Parameters, Stmt};
use ruff_text_size::Ranged;
use crate::checkers::ast::Checker;
@ -125,23 +125,22 @@ pub(crate) fn unnecessary_map(
ObjectType::List | ObjectType::Set => {
// Only flag, e.g., `list(map(lambda x: x + 1, iterable))`.
let [Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, keywords, .. },
..
func, arguments, ..
})] = args
else {
return;
};
if args.len() != 2 {
if arguments.args.len() != 2 {
return;
}
if !keywords.is_empty() {
if !arguments.keywords.is_empty() {
return;
}
let Some(argument) = helpers::first_argument_with_matching_function("map", func, args)
let Some(argument) =
helpers::first_argument_with_matching_function("map", func, &arguments.args)
else {
return;
};
@ -170,23 +169,22 @@ pub(crate) fn unnecessary_map(
ObjectType::Dict => {
// Only flag, e.g., `dict(map(lambda v: (v, v ** 2), values))`.
let [Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, keywords, .. },
..
func, arguments, ..
})] = args
else {
return;
};
if args.len() != 2 {
if arguments.args.len() != 2 {
return;
}
if !keywords.is_empty() {
if !arguments.keywords.is_empty() {
return;
}
let Some(argument) = helpers::first_argument_with_matching_function("map", func, args)
let Some(argument) =
helpers::first_argument_with_matching_function("map", func, &arguments.args)
else {
return;
};

View File

@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Arguments, Expr, Stmt};
use ruff_python_ast::{self as ast, Expr, Stmt};
use ruff_source_file::Locator;
use ruff_text_size::Ranged;
@ -175,12 +175,8 @@ impl Violation for DotFormatInException {
/// EM101, EM102, EM103
pub(crate) fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr) {
if let Expr::Call(ast::ExprCall {
arguments: Arguments { args, .. },
..
}) = exc
{
if let Some(first) = args.first() {
if let Expr::Call(ast::ExprCall { arguments, .. }) = exc {
if let Some(first) = arguments.args.first() {
match first {
// Check for string literals.
Expr::StringLiteral(ast::ExprStringLiteral { value: string, .. }) => {

View File

@ -1,5 +1,5 @@
use ruff_diagnostics::{Diagnostic, Edit, Fix};
use ruff_python_ast::{self as ast, Arguments, Expr, Keyword, Operator};
use ruff_python_ast::{self as ast, Expr, Keyword, Operator};
use ruff_python_semantic::analyze::logging;
use ruff_python_stdlib::logging::LoggingLevel;
use ruff_text_size::Ranged;
@ -104,16 +104,14 @@ fn check_log_record_attr_clash(checker: &mut Checker, extra: &Keyword) {
}
}
Expr::Call(ast::ExprCall {
func,
arguments: Arguments { keywords, .. },
..
func, arguments, ..
}) => {
if checker
.semantic()
.resolve_call_path(func)
.is_some_and(|call_path| matches!(call_path.as_slice(), ["", "dict"]))
{
for keyword in keywords.iter() {
for keyword in arguments.keywords.iter() {
if let Some(attr) = &keyword.arg {
if is_reserved_attr(attr) {
checker.diagnostics.push(Diagnostic::new(

View File

@ -81,23 +81,18 @@ pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
for (index, call) in values.iter().enumerate() {
let Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
arguments,
range: _,
}) = &call
else {
continue;
};
if !keywords.is_empty() {
if !arguments.keywords.is_empty() {
continue;
}
let [arg] = &**args else {
let [arg] = &*arguments.args else {
continue;
};
@ -140,12 +135,7 @@ pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
.map(|expr| {
let Expr::Call(ast::ExprCall {
func: _,
arguments:
Arguments {
args,
keywords: _,
range: _,
},
arguments,
range: _,
}) = expr
else {
@ -154,7 +144,9 @@ pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
format!("Indices should only contain `{attr_name}` calls")
)
};
args.first()
arguments
.args
.first()
.unwrap_or_else(|| panic!("`{attr_name}` should have one argument"))
})
.collect();
@ -187,11 +179,11 @@ pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
});
let node3 = Expr::Call(ast::ExprCall {
func: Box::new(node2),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([node]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
});
let call = node3;

View File

@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Arguments, Decorator, Expr};
use ruff_python_ast::{self as ast, Decorator, Expr};
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
@ -137,18 +137,10 @@ fn check_mark_parentheses(checker: &mut Checker, decorator: &Decorator, marker:
match &decorator.expression {
Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
arguments,
range: _,
}) => {
if !checker.settings.flake8_pytest_style.mark_parentheses
&& args.is_empty()
&& keywords.is_empty()
{
if !checker.settings.flake8_pytest_style.mark_parentheses && arguments.is_empty() {
let fix = Fix::safe_edit(Edit::deletion(func.end(), decorator.end()));
pytest_mark_parentheses(checker, decorator, marker, fix, "", "()");
}
@ -171,11 +163,8 @@ fn check_useless_usefixtures(checker: &mut Checker, decorator: &Decorator, marke
// @pytest.mark.usefixtures
Expr::Attribute(..) => {}
// @pytest.mark.usefixtures(...)
Expr::Call(ast::ExprCall {
arguments: Arguments { args, keywords, .. },
..
}) => {
if !args.is_empty() || !keywords.is_empty() {
Expr::Call(ast::ExprCall { arguments, .. }) => {
if !arguments.is_empty() {
return;
}
}

View File

@ -7,7 +7,7 @@ use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::comparable::ComparableExpr;
use ruff_python_ast::parenthesize::parenthesized_range;
use ruff_python_ast::AstNode;
use ruff_python_ast::{self as ast, Arguments, Decorator, Expr, ExprContext};
use ruff_python_ast::{self as ast, Decorator, Expr, ExprContext};
use ruff_python_codegen::Generator;
use ruff_python_trivia::CommentRanges;
use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer};
@ -632,23 +632,19 @@ fn handle_value_rows(
pub(crate) fn parametrize(checker: &mut Checker, decorators: &[Decorator]) {
for decorator in decorators {
if is_pytest_parametrize(decorator, checker.semantic()) {
if let Expr::Call(ast::ExprCall {
arguments: Arguments { args, .. },
..
}) = &decorator.expression
{
if let Expr::Call(ast::ExprCall { arguments, .. }) = &decorator.expression {
if checker.enabled(Rule::PytestParametrizeNamesWrongType) {
if let [names, ..] = &**args {
if let [names, ..] = &*arguments.args {
check_names(checker, decorator, names);
}
}
if checker.enabled(Rule::PytestParametrizeValuesWrongType) {
if let [names, values, ..] = &**args {
if let [names, values, ..] = &*arguments.args {
check_values(checker, names, values);
}
}
if checker.enabled(Rule::PytestDuplicateParametrizeTestCases) {
if let [_, values, ..] = &**args {
if let [_, values, ..] = &*arguments.args {
check_duplicates(checker, values);
}
}

View File

@ -389,11 +389,11 @@ impl UnittestAssert {
};
let node1 = ast::ExprCall {
func: Box::new(node.into()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([(**obj).clone(), (**cls).clone()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
let isinstance = node1.into();
@ -433,11 +433,11 @@ impl UnittestAssert {
};
let node2 = ast::ExprCall {
func: Box::new(node1.into()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([(**regex).clone(), (**text).clone()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
let re_search = node2.into();

View File

@ -303,21 +303,16 @@ fn isinstance_target<'a>(call: &'a Expr, semantic: &'a SemanticModel) -> Option<
// Verify that this is an `isinstance` call.
let Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
arguments,
range: _,
}) = &call
else {
return None;
};
if args.len() != 2 {
if !arguments.keywords.is_empty() {
return None;
}
if !keywords.is_empty() {
if arguments.args.len() != 2 {
return None;
}
let Expr::Name(ast::ExprName { id: func_name, .. }) = func.as_ref() else {
@ -331,7 +326,7 @@ fn isinstance_target<'a>(call: &'a Expr, semantic: &'a SemanticModel) -> Option<
}
// Collect the target (e.g., `obj` in `isinstance(obj, int)`).
Some(&args[0])
Some(&arguments.args[0])
}
/// SIM101
@ -374,12 +369,10 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
if indices.len() > 1 {
// Grab the target used in each duplicate `isinstance` call (e.g., `obj` in
// `isinstance(obj, int)`).
let target = if let Expr::Call(ast::ExprCall {
arguments: Arguments { args, .. },
..
}) = &values[indices[0]]
{
args.first()
let target = if let Expr::Call(ast::ExprCall { arguments, .. }) = &values[indices[0]] {
arguments
.args
.first()
.expect("`isinstance` should have two arguments")
} else {
unreachable!("Indices should only contain `isinstance` calls")
@ -401,14 +394,13 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
.iter()
.map(|index| &values[*index])
.map(|expr| {
let Expr::Call(ast::ExprCall {
arguments: Arguments { args, .. },
..
}) = expr
else {
let Expr::Call(ast::ExprCall { arguments, .. }) = expr else {
unreachable!("Indices should only contain `isinstance` calls")
};
args.get(1).expect("`isinstance` should have two arguments")
arguments
.args
.get(1)
.expect("`isinstance` should have two arguments")
})
.collect();
@ -436,11 +428,11 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
};
let node2 = ast::ExprCall {
func: Box::new(node1.into()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([target.clone(), node.into()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
let call = node2.into();

View File

@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Arguments, Expr};
use ruff_python_ast::{self as ast, Expr};
use ruff_text_size::Ranged;
use crate::fix::snippet::SourceCodeSnippet;
@ -134,14 +134,12 @@ pub(crate) fn use_capital_environment_variables(checker: &mut Checker, expr: &Ex
// Ex) `os.environ.get('foo')`, `os.getenv('foo')`
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, .. },
..
func, arguments, ..
}) = expr
else {
return;
};
let Some(arg) = args.first() else {
let Some(arg) = arguments.args.first() else {
return;
};
let Expr::StringLiteral(ast::ExprStringLiteral { value: env_var, .. }) = arg else {
@ -233,13 +231,13 @@ fn check_os_environ_subscript(checker: &mut Checker, expr: &Expr) {
pub(crate) fn dict_get_with_none_default(checker: &mut Checker, expr: &Expr) {
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, keywords, .. },
arguments,
range: _,
}) = expr
else {
return;
};
if !keywords.is_empty() {
if !arguments.keywords.is_empty() {
return;
}
let Expr::Attribute(ast::ExprAttribute { value, attr, .. }) = func.as_ref() else {
@ -248,13 +246,13 @@ pub(crate) fn dict_get_with_none_default(checker: &mut Checker, expr: &Expr) {
if attr != "get" {
return;
}
let Some(key) = args.first() else {
let Some(key) = arguments.args.first() else {
return;
};
if !(key.is_literal_expr() || key.is_name_expr()) {
return;
}
let Some(default) = args.get(1) else {
let Some(default) = arguments.args.get(1) else {
return;
};
if !default.is_none_literal_expr() {

View File

@ -184,11 +184,11 @@ pub(crate) fn if_expr_with_true_false(
}
.into(),
),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([test.clone()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
}
.into(),

View File

@ -278,11 +278,11 @@ pub(crate) fn double_negation(checker: &mut Checker, expr: &Expr, op: UnaryOp, o
};
let node1 = ast::ExprCall {
func: Box::new(node.into()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([*operand.clone()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(

View File

@ -175,11 +175,11 @@ pub(crate) fn if_else_block_instead_of_dict_get(checker: &mut Checker, stmt_if:
};
let node3 = ast::ExprCall {
func: Box::new(node2.into()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([node1, node]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
let node4 = expected_var.clone();
@ -275,11 +275,11 @@ pub(crate) fn if_exp_instead_of_dict_get(
};
let fixed_node = ast::ExprCall {
func: Box::new(dict_get_node.into()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([dict_key_node, default_value_node]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};

View File

@ -160,11 +160,11 @@ pub(crate) fn needless_bool(checker: &mut Checker, stmt_if: &ast::StmtIf) {
};
let value_node = ast::ExprCall {
func: Box::new(func_node.into()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([if_test.clone()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
let return_node = ast::StmtReturn {

View File

@ -390,11 +390,11 @@ fn return_stmt(id: &str, test: &Expr, target: &Expr, iter: &Expr, generator: Gen
};
let node2 = ast::ExprCall {
func: Box::new(node1.into()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([node.into()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
let node3 = ast::StmtReturn {

View File

@ -1,6 +1,6 @@
use ast::{ExprAttribute, ExprName, Identifier};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{self as ast, Arguments, Expr, ExprCall};
use ruff_python_ast::{self as ast, Expr, ExprCall};
use ruff_text_size::Ranged;
use crate::{checkers::ast::Checker, fix::snippet::SourceCodeSnippet};
@ -61,11 +61,9 @@ impl AlwaysFixableViolation for ZipDictKeysAndValues {
/// SIM911
pub(crate) fn zip_dict_keys_and_values(checker: &mut Checker, expr: &ExprCall) {
let ExprCall {
func,
arguments: Arguments { args, keywords, .. },
..
func, arguments, ..
} = expr;
match &keywords[..] {
match &*arguments.keywords {
[] => {}
[ast::Keyword {
arg: Some(name), ..
@ -75,7 +73,7 @@ pub(crate) fn zip_dict_keys_and_values(checker: &mut Checker, expr: &ExprCall) {
if matches!(func.as_ref(), Expr::Name(ExprName { id, .. }) if &**id != "zip") {
return;
}
let [arg1, arg2] = &args[..] else {
let [arg1, arg2] = &*arguments.args else {
return;
};
let Some((var1, attr1)) = get_var_attr(arg1) else {

View File

@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Arguments, ConversionFlag, Expr};
use ruff_python_ast::{self as ast, ConversionFlag, Expr};
use ruff_text_size::TextRange;
/// Wrap an expression in a [`ast::FStringElement::Expression`] with no special formatting.
@ -26,14 +26,9 @@ fn is_simple_call(expr: &Expr) -> bool {
match expr {
Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
arguments,
range: _,
}) => args.is_empty() && keywords.is_empty() && is_simple_callee(func),
}) => arguments.is_empty() && is_simple_callee(func),
_ => false,
}
}

View File

@ -3,7 +3,7 @@ use itertools::Itertools;
use crate::fix::edits::pad;
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{self as ast, Arguments, Expr};
use ruff_python_ast::{self as ast, Expr};
use ruff_text_size::{Ranged, TextRange};
use crate::checkers::ast::Checker;
@ -103,20 +103,16 @@ fn build_fstring(joiner: &str, joinees: &[Expr]) -> Option<Expr> {
/// FLY002
pub(crate) fn static_join_to_fstring(checker: &mut Checker, expr: &Expr, joiner: &str) {
let Expr::Call(ast::ExprCall {
arguments: Arguments { args, keywords, .. },
..
}) = expr
else {
let Expr::Call(ast::ExprCall { arguments, .. }) = expr else {
return;
};
// If there are kwargs or more than one argument, this is some non-standard
// string join call.
if !keywords.is_empty() {
if !arguments.keywords.is_empty() {
return;
}
let [arg] = &**args else {
let [arg] = &*arguments.args else {
return;
};

View File

@ -3,7 +3,7 @@ use std::fmt;
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast as ast;
use ruff_python_ast::{Arguments, Expr};
use ruff_python_ast::Expr;
use ruff_text_size::Ranged;
use crate::checkers::ast::Checker;
@ -70,14 +70,12 @@ pub(crate) fn incorrect_dict_iterator(checker: &mut Checker, stmt_for: &ast::Stm
return;
};
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, .. },
..
func, arguments, ..
}) = stmt_for.iter.as_ref()
else {
return;
};
if !args.is_empty() {
if !arguments.is_empty() {
return;
}
let Expr::Attribute(ast::ExprAttribute { attr, .. }) = func.as_ref() else {

View File

@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Arguments, Expr, Stmt};
use ruff_python_ast::{self as ast, Expr, Stmt};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
@ -93,23 +93,18 @@ pub(crate) fn manual_list_comprehension(checker: &mut Checker, target: &Expr, bo
let Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
arguments,
range,
}) = value.as_ref()
else {
return;
};
if !keywords.is_empty() {
if !arguments.keywords.is_empty() {
return;
}
let [arg] = &**args else {
let [arg] = &*arguments.args else {
return;
};

View File

@ -1,7 +1,7 @@
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::helpers::any_over_expr;
use ruff_python_ast::{self as ast, Arguments, Expr, Stmt};
use ruff_python_ast::{self as ast, Expr, Stmt};
use ruff_python_semantic::analyze::typing::is_list;
use crate::checkers::ast::Checker;
@ -60,23 +60,18 @@ pub(crate) fn manual_list_copy(checker: &mut Checker, target: &Expr, body: &[Stm
let Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
arguments,
range,
}) = value.as_ref()
else {
return;
};
if !keywords.is_empty() {
if !arguments.keywords.is_empty() {
return;
}
let [arg] = &**args else {
let [arg] = &*arguments.args else {
return;
};

View File

@ -1,6 +1,6 @@
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{self as ast, Arguments, Expr, Stmt};
use ruff_python_ast::{self as ast, Expr, Stmt};
use ruff_python_semantic::analyze::typing::find_assigned_value;
use ruff_text_size::TextRange;
@ -52,19 +52,14 @@ impl AlwaysFixableViolation for UnnecessaryListCast {
pub(crate) fn unnecessary_list_cast(checker: &mut Checker, iter: &Expr, body: &[Stmt]) {
let Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords: _,
range: _,
},
arguments,
range: list_range,
}) = iter
else {
return;
};
let [arg] = &**args else {
let [arg] = &*arguments.args else {
return;
};

View File

@ -97,16 +97,11 @@ fn collect_nested_args(min_max: MinMax, args: &[Expr], semantic: &SemanticModel)
for arg in args {
if let Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
arguments,
range: _,
}) = arg
{
if let [arg] = &**args {
if let [arg] = &*arguments.args {
if arg.as_starred_expr().is_none() {
let new_arg = Expr::Starred(ast::ExprStarred {
value: Box::new(arg.clone()),
@ -117,8 +112,8 @@ fn collect_nested_args(min_max: MinMax, args: &[Expr], semantic: &SemanticModel)
continue;
}
}
if MinMax::try_from_call(func, keywords, semantic) == Some(min_max) {
inner(min_max, args, semantic, new_args);
if MinMax::try_from_call(func, &arguments.keywords, semantic) == Some(min_max) {
inner(min_max, &arguments.args, semantic, new_args);
continue;
}
}
@ -143,31 +138,29 @@ pub(crate) fn nested_min_max(
return;
};
if matches!(&args, [Expr::Call(ast::ExprCall { arguments: Arguments {args, .. }, .. })] if args.len() == 1)
{
if matches!(&args, [Expr::Call(ast::ExprCall { arguments, .. })] if arguments.args.len() == 1) {
return;
}
if args.iter().any(|arg| {
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { keywords, .. },
..
func, arguments, ..
}) = arg
else {
return false;
};
MinMax::try_from_call(func.as_ref(), keywords.as_ref(), checker.semantic()) == Some(min_max)
let keywords = arguments.keywords.as_ref();
MinMax::try_from_call(func.as_ref(), keywords, checker.semantic()) == Some(min_max)
}) {
let mut diagnostic = Diagnostic::new(NestedMinMax { func: min_max }, expr.range());
if !checker.indexer().has_comments(expr, checker.locator()) {
let flattened_expr = Expr::Call(ast::ExprCall {
func: Box::new(func.clone()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: collect_nested_args(min_max, args, checker.semantic()).into_boxed_slice(),
keywords: Box::from(keywords),
range: TextRange::default(),
},
}),
range: TextRange::default(),
});
diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement(

View File

@ -1,7 +1,7 @@
use std::{fmt, iter};
use regex::Regex;
use ruff_python_ast::{self as ast, Arguments, Expr, ExprContext, Stmt, WithItem};
use ruff_python_ast::{self as ast, Expr, ExprContext, Stmt, WithItem};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
@ -238,9 +238,7 @@ fn assignment_is_cast_expr(value: &Expr, target: &Expr, semantic: &SemanticModel
}
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, .. },
..
func, arguments, ..
}) = value
else {
return false;
@ -248,10 +246,10 @@ fn assignment_is_cast_expr(value: &Expr, target: &Expr, semantic: &SemanticModel
let Expr::Name(ast::ExprName { id: target_id, .. }) = target else {
return false;
};
if args.len() != 2 {
if arguments.args.len() != 2 {
return false;
}
let Expr::Name(ast::ExprName { id: arg_id, .. }) = &args[1] else {
let Expr::Name(ast::ExprName { id: arg_id, .. }) = &arguments.args[1] else {
return false;
};
if arg_id != target_id {

View File

@ -1,5 +1,5 @@
use itertools::Itertools;
use ruff_python_ast::{self as ast, Arguments, BoolOp, Expr};
use ruff_python_ast::{self as ast, BoolOp, Expr};
use rustc_hash::{FxHashMap, FxHashSet};
use crate::fix::edits::pad;
@ -85,9 +85,7 @@ pub(crate) fn repeated_isinstance_calls(
FxHashMap::default();
for value in values {
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, .. },
..
func, arguments, ..
}) = value
else {
continue;
@ -95,7 +93,7 @@ pub(crate) fn repeated_isinstance_calls(
if !matches!(func.as_ref(), Expr::Name(ast::ExprName { id, .. }) if &**id =="isinstance") {
continue;
}
let [obj, types] = &args[..] else {
let [obj, types] = &*arguments.args else {
continue;
};
if !checker.semantic().is_builtin("isinstance") {

View File

@ -135,7 +135,7 @@ fn match_named_tuple_assign<'a>(
};
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, keywords, .. },
arguments,
range: _,
}) = value
else {
@ -144,7 +144,7 @@ fn match_named_tuple_assign<'a>(
if !semantic.match_typing_expr(func, "NamedTuple") {
return None;
}
Some((typename, args, keywords, func))
Some((typename, &arguments.args, &arguments.keywords, func))
}
/// Generate a [`Stmt::AnnAssign`] representing the provided field definition.

View File

@ -238,9 +238,9 @@ fn match_fields_and_total(arguments: &Arguments) -> Option<(Vec<Stmt>, Option<&K
}) => Some((fields_from_dict_literal(keys, values)?, total)),
Expr::Call(ast::ExprCall {
func,
arguments: Arguments { keywords, .. },
arguments,
range: _,
}) => Some((fields_from_dict_call(func, keywords)?, total)),
}) => Some((fields_from_dict_call(func, &arguments.keywords)?, total)),
_ => None,
}
}

View File

@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Arguments, Decorator, Expr, Keyword};
use ruff_python_ast::{self as ast, Decorator, Expr, Keyword};
use ruff_text_size::{Ranged, TextRange};
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
@ -59,12 +59,7 @@ pub(crate) fn lru_cache_with_maxsize_none(checker: &mut Checker, decorator_list:
for decorator in decorator_list {
let Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
arguments,
range: _,
}) = &decorator.expression
else {
@ -72,8 +67,8 @@ pub(crate) fn lru_cache_with_maxsize_none(checker: &mut Checker, decorator_list:
};
// Look for, e.g., `import functools; @functools.lru_cache(maxsize=None)`.
if args.is_empty()
&& keywords.len() == 1
if arguments.args.is_empty()
&& arguments.keywords.len() == 1
&& checker
.semantic()
.resolve_call_path(func)
@ -83,7 +78,7 @@ pub(crate) fn lru_cache_with_maxsize_none(checker: &mut Checker, decorator_list:
arg,
value,
range: _,
} = &keywords[0];
} = &arguments.keywords[0];
if arg.as_ref().is_some_and(|arg| arg == "maxsize") && value.is_none_literal_expr() {
let mut diagnostic = Diagnostic::new(
LRUCacheWithMaxsizeNone,

View File

@ -141,12 +141,7 @@ pub(crate) fn native_literals(
) {
let ast::ExprCall {
func,
arguments:
ast::Arguments {
args,
keywords,
range: _,
},
arguments,
range: _,
} = call;
@ -154,7 +149,7 @@ pub(crate) fn native_literals(
return;
};
if !keywords.is_empty() || args.len() > 1 {
if !arguments.keywords.is_empty() || arguments.args.len() > 1 {
return;
}
@ -179,7 +174,7 @@ pub(crate) fn native_literals(
}
}
match args.first() {
match arguments.args.first() {
None => {
let mut diagnostic = Diagnostic::new(NativeLiterals { literal_type }, call.range());

View File

@ -20,11 +20,11 @@ pub(super) fn generate_method_call(name: &str, method: &str, generator: Generato
// Make it into a call `name.method()`
let call = ast::ExprCall {
func: Box::new(attr.into()),
arguments: ast::Arguments {
arguments: Box::new(ast::Arguments {
args: Box::from([]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
// And finally, turn it into a statement.

View File

@ -151,7 +151,7 @@ fn match_remove(if_stmt: &ast::StmtIf) -> Option<(&Expr, &ast::ExprName)> {
let ast::ExprCall {
func: attr,
arguments: ast::Arguments { args, keywords, .. },
arguments,
..
} = expr.as_call_expr()?;
@ -165,11 +165,11 @@ fn match_remove(if_stmt: &ast::StmtIf) -> Option<(&Expr, &ast::ExprName)> {
return None;
};
let [arg] = &**args else {
let [arg] = &*arguments.args else {
return None;
};
if func_name != "remove" || !keywords.is_empty() {
if func_name != "remove" || !arguments.keywords.is_empty() {
return None;
}
@ -190,11 +190,11 @@ fn make_suggestion(set: &ast::ExprName, element: &Expr, generator: Generator) ->
// Make the actual call `set.discard(element)`
let call = ast::ExprCall {
func: Box::new(attr.into()),
arguments: ast::Arguments {
arguments: Box::new(ast::Arguments {
args: Box::from([element.clone()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
// And finally, turn it into a statement.

View File

@ -136,9 +136,7 @@ fn find_file_open<'a>(
) -> Option<FileOpen<'a>> {
// We want to match `open(...) as var`.
let ast::ExprCall {
func,
arguments: ast::Arguments { args, keywords, .. },
..
func, arguments, ..
} = item.context_expr.as_call_expr()?;
let func = func.as_name_expr()?;
@ -151,17 +149,20 @@ fn find_file_open<'a>(
// Ignore calls with `*args` and `**kwargs`. In the exact case of `open(*filename, mode="r")`,
// it could be a match; but in all other cases, the call _could_ contain unsupported keyword
// arguments, like `buffering`.
if args.iter().any(Expr::is_starred_expr)
|| keywords.iter().any(|keyword| keyword.arg.is_none())
if arguments.args.iter().any(Expr::is_starred_expr)
|| arguments
.keywords
.iter()
.any(|keyword| keyword.arg.is_none())
{
return None;
}
// Match positional arguments, get filename and read mode.
let (filename, pos_mode) = match_open_args(args)?;
let (filename, pos_mode) = match_open_args(&arguments.args)?;
// Match keyword arguments, get keyword arguments to forward and possibly read mode.
let (keywords, kw_mode) = match_open_keywords(keywords)?;
let (keywords, kw_mode) = match_open_keywords(&arguments.keywords)?;
// `pos_mode` could've been assigned default value corresponding to "r", while
// keyword mode should override that.
@ -322,11 +323,11 @@ fn make_suggestion(open: &FileOpen<'_>, generator: Generator) -> SourceCodeSnipp
};
let call = ast::ExprCall {
func: Box::new(name.into()),
arguments: ast::Arguments {
arguments: Box::new(ast::Arguments {
args: Box::from([]),
keywords: open.keywords.iter().copied().cloned().collect(),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
SourceCodeSnippet::from_str(&generator.expr(&call.into()))

View File

@ -303,11 +303,11 @@ fn construct_starmap_call(starmap_binding: String, iter: &Expr, func: &Expr) ->
};
ast::ExprCall {
func: Box::new(starmap.into()),
arguments: ast::Arguments {
arguments: Box::new(ast::Arguments {
args: Box::from([func.clone(), iter.clone()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
}
}
@ -321,11 +321,11 @@ fn wrap_with_call_to(call: ast::ExprCall, func_name: &str) -> ast::ExprCall {
};
ast::ExprCall {
func: Box::new(name.into()),
arguments: ast::Arguments {
arguments: Box::new(ast::Arguments {
args: Box::from([call.into()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
}
}
@ -353,14 +353,12 @@ fn match_comprehension_target(comprehension: &ast::Comprehension) -> Option<Comp
/// Match that the given expression is `func(x, y, z, ...)`.
fn match_call(element: &Expr) -> Option<(&[Expr], &Expr)> {
let ast::ExprCall {
func,
arguments: ast::Arguments { args, keywords, .. },
..
func, arguments, ..
} = element.as_call_expr()?;
if !keywords.is_empty() {
if !arguments.keywords.is_empty() {
return None;
}
Some((args, func))
Some((&arguments.args, func))
}

View File

@ -359,11 +359,11 @@ fn make_suggestion(group: &AppendGroup, generator: Generator) -> String {
// Make the actual call `var.extend((elt1, elt2, ..., eltN))`
let call = ast::ExprCall {
func: Box::new(attr.into()),
arguments: ast::Arguments {
arguments: Box::new(ast::Arguments {
args: Box::from([tuple.into()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
// And finally, turn it into a statement.

View File

@ -250,11 +250,11 @@ fn generate_range_len_call(name: &str, generator: Generator) -> String {
}
.into(),
),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([var.into()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
// Construct `range(len(name))`.
@ -267,11 +267,11 @@ fn generate_range_len_call(name: &str, generator: Generator) -> String {
}
.into(),
),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([len.into()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
// And finally, turn it into a statement.

View File

@ -2,7 +2,7 @@ use anyhow::{bail, Result};
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{self as ast, Arguments, Expr};
use ruff_python_ast::{self as ast, Expr};
use ruff_python_codegen::Stylist;
use ruff_source_file::Locator;
use ruff_text_size::Ranged;
@ -69,26 +69,19 @@ pub(crate) fn explicit_f_string_type_conversion(checker: &mut Checker, f_string:
}
let Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
..
func, arguments, ..
}) = expression.as_ref()
else {
continue;
};
// Can't be a conversion otherwise.
if !keywords.is_empty() {
if !arguments.keywords.is_empty() {
continue;
}
// Can't be a conversion otherwise.
let [arg] = &**args else {
let [arg] = &*arguments.args else {
continue;
};

View File

@ -99,9 +99,7 @@ fn should_be_fstring(
for expr in semantic.current_expressions() {
match expr {
ast::Expr::Call(ast::ExprCall {
arguments: ast::Arguments { keywords, args, .. },
func,
..
arguments, func, ..
}) => {
if let ast::Expr::Attribute(ast::ExprAttribute { value, .. }) = func.as_ref() {
match value.as_ref() {
@ -123,12 +121,12 @@ fn should_be_fstring(
_ => {}
}
}
for keyword in keywords.iter() {
for keyword in arguments.keywords.iter() {
if let Some(ident) = keyword.arg.as_ref() {
arg_names.insert(ident.as_str());
}
}
for arg in args.iter() {
for arg in arguments.args.iter() {
if let ast::Expr::Name(ast::ExprName { id, .. }) = arg {
arg_names.insert(&**id);
}

View File

@ -102,12 +102,10 @@ pub(crate) fn sort_dunder_all_aug_assign(checker: &mut Checker, node: &ast::Stmt
pub(crate) fn sort_dunder_all_extend_call(
checker: &mut Checker,
ast::ExprCall {
func,
arguments: ast::Arguments { args, keywords, .. },
..
func, arguments, ..
}: &ast::ExprCall,
) {
let ([value_passed], []) = (&**args, &**keywords) else {
let ([value_passed], []) = (&*arguments.args, &*arguments.keywords) else {
return;
};
let ast::Expr::Attribute(ast::ExprAttribute {

View File

@ -158,7 +158,7 @@ fn is_constant_like(expr: &Expr) -> bool {
/// - Given `{n: 1 for n in [1,2,3]}`, generate `dict.fromkeys([1,2,3], 1)`.
fn fix_unnecessary_dict_comprehension(value: &Expr, generator: &Comprehension) -> Expr {
let iterable = generator.iter.clone();
let args = Arguments {
let arguments = Arguments {
args: if value.is_none_literal_expr() {
Box::from([iterable])
} else {
@ -173,7 +173,7 @@ fn fix_unnecessary_dict_comprehension(value: &Expr, generator: &Comprehension) -
ctx: ExprContext::Load,
range: TextRange::default(),
})),
arguments: args,
arguments: Box::new(arguments),
range: TextRange::default(),
})
}

View File

@ -2,7 +2,7 @@ use std::borrow::Cow;
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{self as ast, Arguments, Comprehension, Expr, Int};
use ruff_python_ast::{self as ast, Comprehension, Expr, Int};
use ruff_python_semantic::SemanticModel;
use ruff_python_stdlib::builtins::is_iterator;
use ruff_text_size::{Ranged, TextRange, TextSize};
@ -136,9 +136,7 @@ struct IterationTarget {
fn match_iteration_target(expr: &Expr, semantic: &SemanticModel) -> Option<IterationTarget> {
let result = match expr {
Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, .. },
..
func, arguments, ..
}) => {
let ast::ExprName { id, .. } = func.as_name_expr()?;
@ -146,7 +144,7 @@ fn match_iteration_target(expr: &Expr, semantic: &SemanticModel) -> Option<Itera
return None;
}
let [arg] = &**args else {
let [arg] = &*arguments.args else {
return None;
};

View File

@ -1,6 +1,6 @@
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{self as ast, Arguments, Expr};
use ruff_python_ast::{self as ast, Expr};
use ruff_text_size::Ranged;
use crate::checkers::ast::Checker;
@ -56,15 +56,13 @@ impl Violation for RaiseVanillaArgs {
/// TRY003
pub(crate) fn raise_vanilla_args(checker: &mut Checker, expr: &Expr) {
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, .. },
..
func, arguments, ..
}) = expr
else {
return;
};
let Some(arg) = args.first() else {
let Some(arg) = arguments.args.first() else {
return;
};

View File

@ -909,7 +909,7 @@ impl From<ExprCompare> for Expr {
pub struct ExprCall {
pub range: TextRange,
pub func: Box<Expr>,
pub arguments: Arguments,
pub arguments: Box<Arguments>,
}
impl From<ExprCall> for Expr {
@ -3891,14 +3891,14 @@ mod tests {
// 88 for Rustc < 1.76
assert!(matches!(std::mem::size_of::<Pattern>(), 80 | 88));
assert_eq!(std::mem::size_of::<Expr>(), 64);
assert_eq!(std::mem::size_of::<Expr>(), 56);
assert_eq!(std::mem::size_of::<ExprAttribute>(), 48);
assert_eq!(std::mem::size_of::<ExprAwait>(), 16);
assert_eq!(std::mem::size_of::<ExprBinOp>(), 32);
assert_eq!(std::mem::size_of::<ExprBoolOp>(), 40);
assert_eq!(std::mem::size_of::<ExprBooleanLiteral>(), 12);
assert_eq!(std::mem::size_of::<ExprBytesLiteral>(), 40);
assert_eq!(std::mem::size_of::<ExprCall>(), 56);
assert_eq!(std::mem::size_of::<ExprCall>(), 24);
assert_eq!(std::mem::size_of::<ExprCompare>(), 48);
assert_eq!(std::mem::size_of::<ExprDict>(), 40);
assert_eq!(std::mem::size_of::<ExprDictComp>(), 48);

View File

@ -43,7 +43,7 @@ fn test_parenthesized_argument() {
let expr = parse_expression(source_code).unwrap();
let call = expr.as_call_expr().unwrap();
let arguments = &call.arguments;
let arguments = &*call.arguments;
let argument = arguments.args.first().unwrap();
let parenthesized = parenthesized_range(
@ -61,7 +61,7 @@ fn test_non_parenthesized_argument() {
let expr = parse_expression(source_code).unwrap();
let call = expr.as_call_expr().unwrap();
let arguments = &call.arguments;
let arguments = &*call.arguments;
let argument = arguments.args.first().unwrap();
let parenthesized = parenthesized_range(
@ -130,7 +130,7 @@ fn test_twice_parenthesized_argument() {
let expr = parse_expression(source_code).unwrap();
let call = expr.as_call_expr().unwrap();
let arguments = &call.arguments;
let arguments = &*call.arguments;
let argument = arguments.args.first().unwrap();
let parenthesized = parenthesized_range(

View File

@ -1549,7 +1549,7 @@ AtomExpr2<Goal>: crate::parser::ParenthesizedExpr = {
Atom<Goal>,
<location:@L> <func:AtomExpr2<"all">> <arguments:Arguments> <end_location:@R> => ast::ExprCall {
func: Box::new(func.into()),
arguments,
arguments: Box::new(arguments),
range: (location..end_location).into(),
}.into(),
<location:@L> <value:AtomExpr2<"all">> "[" <slice:SubscriptList> "]" <end_location:@R> => ast::ExprSubscript {

View File

@ -1,5 +1,5 @@
// auto-generated: "lalrpop 0.20.0"
// sha3: 8f9c419cf07ccd6289047223fa22bb70c6afd0133b58ea606f601340160cab8b
// sha3: 06d23132da088f5a6184a546b53be668a940ce6dfd046b5ac08b6e70b7c9eb99
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
use ruff_python_ast::{self as ast, Int, IpyEscapeKind};
use crate::{
@ -41071,7 +41071,7 @@ fn __action541<
{
ast::ExprCall {
func: Box::new(func.into()),
arguments,
arguments: Box::new(arguments),
range: (location..end_location).into(),
}.into()
}
@ -41868,7 +41868,7 @@ fn __action588<
{
ast::ExprCall {
func: Box::new(func.into()),
arguments,
arguments: Box::new(arguments),
range: (location..end_location).into(),
}.into()
}