mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-25 05:53:51 +00:00
Avoid allocations in SimpleCallArgs
(#6021)
## Summary My intuition is that it's faster to do these checks as-needed rather than allocation new hash maps and vectors for the arguments. (We typically only query once anyway.)
This commit is contained in:
parent
f9726af4ef
commit
0d94337b96
9 changed files with 81 additions and 100 deletions
|
@ -4,7 +4,6 @@ use std::path::Path;
|
|||
|
||||
use num_traits::Zero;
|
||||
use ruff_text_size::{TextRange, TextSize};
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustpython_ast::CmpOp;
|
||||
use rustpython_parser::ast::{
|
||||
self, Arguments, Constant, ExceptHandler, Expr, Keyword, MatchCase, Pattern, Ranged, Stmt,
|
||||
|
@ -1217,67 +1216,61 @@ pub fn is_docstring_stmt(stmt: &Stmt) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// A simple representation of a call's positional and keyword arguments.
|
||||
/// A representation of a function call's positional and keyword arguments that ignores
|
||||
/// starred expressions.
|
||||
#[derive(Default)]
|
||||
pub struct SimpleCallArgs<'a> {
|
||||
args: Vec<&'a Expr>,
|
||||
kwargs: FxHashMap<&'a str, &'a Expr>,
|
||||
pub struct CallArguments<'a> {
|
||||
args: &'a [Expr],
|
||||
keywords: &'a [Keyword],
|
||||
}
|
||||
|
||||
impl<'a> SimpleCallArgs<'a> {
|
||||
pub fn new(
|
||||
args: impl IntoIterator<Item = &'a Expr>,
|
||||
keywords: impl IntoIterator<Item = &'a Keyword>,
|
||||
) -> Self {
|
||||
let args = args
|
||||
.into_iter()
|
||||
.take_while(|arg| !arg.is_starred_expr())
|
||||
.collect();
|
||||
|
||||
let kwargs = keywords
|
||||
.into_iter()
|
||||
.filter_map(|keyword| {
|
||||
let node = keyword;
|
||||
node.arg.as_ref().map(|arg| (arg.as_str(), &node.value))
|
||||
})
|
||||
.collect();
|
||||
|
||||
SimpleCallArgs { args, kwargs }
|
||||
impl<'a> CallArguments<'a> {
|
||||
pub fn new(args: &'a [Expr], keywords: &'a [Keyword]) -> Self {
|
||||
Self { args, keywords }
|
||||
}
|
||||
|
||||
/// Get the argument with the given name.
|
||||
/// If the argument is not found by name, return
|
||||
/// `None`.
|
||||
pub fn keyword_argument(&self, name: &str) -> Option<&'a Expr> {
|
||||
self.kwargs.get(name).copied()
|
||||
}
|
||||
|
||||
/// Get the argument with the given name or position.
|
||||
/// If the argument is not found with either name or position, return
|
||||
/// `None`.
|
||||
/// Get the argument with the given name or position, or `None` if no such
|
||||
/// argument exists.
|
||||
pub fn argument(&self, name: &str, position: usize) -> Option<&'a Expr> {
|
||||
self.keyword_argument(name)
|
||||
.or_else(|| self.args.get(position).copied())
|
||||
self.keywords
|
||||
.iter()
|
||||
.find(|keyword| {
|
||||
let Keyword { arg, .. } = keyword;
|
||||
arg.as_ref().map_or(false, |arg| arg == name)
|
||||
})
|
||||
.map(|keyword| &keyword.value)
|
||||
.or_else(|| {
|
||||
self.args
|
||||
.iter()
|
||||
.take_while(|expr| !expr.is_starred_expr())
|
||||
.nth(position)
|
||||
})
|
||||
}
|
||||
|
||||
/// Return the number of positional and keyword arguments.
|
||||
/// Return the number of arguments.
|
||||
pub fn len(&self) -> usize {
|
||||
self.args.len() + self.kwargs.len()
|
||||
self.args.len() + self.keywords.len()
|
||||
}
|
||||
|
||||
/// Return `true` if there are no arguments.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
/// Return the number of positional arguments.
|
||||
pub fn num_args(&self) -> usize {
|
||||
self.args.len()
|
||||
self.args
|
||||
.iter()
|
||||
.take_while(|expr| !expr.is_starred_expr())
|
||||
.count()
|
||||
}
|
||||
|
||||
/// Return the number of keyword arguments.
|
||||
pub fn num_kwargs(&self) -> usize {
|
||||
self.kwargs.len()
|
||||
}
|
||||
|
||||
/// Return `true` if there are no positional or keyword arguments.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
self.keywords
|
||||
.iter()
|
||||
.filter(|keyword| keyword.arg.is_some())
|
||||
.count()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue