Skip to content

Commit

Permalink
Avoid alloc
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Feb 8, 2024
1 parent a247350 commit b9f9008
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 16 deletions.
34 changes: 22 additions & 12 deletions crates/ruff_python_parser/src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,38 +81,33 @@ type FunctionArgument = (
pub(crate) fn parse_arguments(
function_arguments: Vec<FunctionArgument>,
) -> Result<ArgumentList, LexicalError> {
let mut args = vec![];
let mut keywords = vec![];

let mut keyword_names = FxHashSet::with_capacity_and_hasher(
function_arguments.len(),
BuildHasherDefault::default(),
);
let mut double_starred = false;
for (name, value) in function_arguments {
if let Some((start, end, name)) = name {
let mut num_args = 0;
let mut num_keywords = 0;
for (name, value) in &function_arguments {
if let Some((start, _end, name)) = name {
// Check for duplicate keyword arguments in the call.
if let Some(keyword_name) = &name {
if !keyword_names.insert(keyword_name.to_string()) {
return Err(LexicalError {
error: LexicalErrorType::DuplicateKeywordArgumentError(
keyword_name.to_string(),
),
location: start,
location: *start,
});
}
} else {
double_starred = true;
}

keywords.push(ast::Keyword {
arg: name,
value,
range: TextRange::new(start, end),
});
num_keywords += 1;
} else {
// Positional arguments mustn't follow keyword arguments.
if !keywords.is_empty() && !is_starred(&value) {
if num_keywords > 0 && !is_starred(value) {
return Err(LexicalError {
error: LexicalErrorType::PositionalArgumentError,
location: value.start(),
Expand All @@ -126,9 +121,24 @@ pub(crate) fn parse_arguments(
});
}

num_args += 1;
}
}

let mut args = Vec::with_capacity(num_args);
let mut keywords = Vec::with_capacity(num_keywords);
for (name, value) in function_arguments {
if let Some((start, end, name)) = name {
keywords.push(ast::Keyword {
arg: name,
value,
range: TextRange::new(start, end),
});
} else {
args.push(value);
}
}

Ok(ArgumentList { args, keywords })
}

Expand Down
7 changes: 6 additions & 1 deletion crates/ruff_python_parser/src/python.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -1406,7 +1406,12 @@ NotTest<Goal>: crate::parser::ParenthesizedExpr = {

Comparison<Goal>: crate::parser::ParenthesizedExpr = {
<location:@L> <left:Expression<"all">> <comparisons:(CompOp Expression<"all">)+> <end_location:@R> => {
let (ops, comparators): (Vec<ast::CmpOp>, Vec<ast::Expr>) = comparisons.into_iter().map(|(op, comparator)| (op, ast::Expr::from(comparator))).unzip();
let mut ops = Vec::with_capacity(comparisons.len());
let mut comparators = Vec::with_capacity(comparisons.len());
for (op, comparator) in comparisons {
ops.push(op);
comparators.push(comparator.into());
}
ast::ExprCompare {
left: Box::new(left.into()),
ops: ops.into_boxed_slice(),
Expand Down
16 changes: 13 additions & 3 deletions crates/ruff_python_parser/src/python.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// auto-generated: "lalrpop 0.20.0"
// sha3: f7b86f63c3c63357e51ad418f3bb2ff98007190db5da558fe98f3b2a3c5fcc44
// sha3: 0be47a83548f86178f1c8c5e786f39e7a19d37437bbfeba6b6750300a1d66340
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
use ruff_python_ast::{self as ast, Int, IpyEscapeKind};
use crate::{
Expand Down Expand Up @@ -40651,7 +40651,12 @@ fn __action515<
) -> crate::parser::ParenthesizedExpr
{
{
let (ops, comparators): (Vec<ast::CmpOp>, Vec<ast::Expr>) = comparisons.into_iter().map(|(op, comparator)| (op, ast::Expr::from(comparator))).unzip();
let mut ops = Vec::with_capacity(comparisons.len());
let mut comparators = Vec::with_capacity(comparisons.len());
for (op, comparator) in comparisons {
ops.push(op);
comparators.push(comparator.into());
}
ast::ExprCompare {
left: Box::new(left.into()),
ops: ops.into_boxed_slice(),
Expand Down Expand Up @@ -40821,7 +40826,12 @@ fn __action526<
) -> crate::parser::ParenthesizedExpr
{
{
let (ops, comparators): (Vec<ast::CmpOp>, Vec<ast::Expr>) = comparisons.into_iter().map(|(op, comparator)| (op, ast::Expr::from(comparator))).unzip();
let mut ops = Vec::with_capacity(comparisons.len());
let mut comparators = Vec::with_capacity(comparisons.len());
for (op, comparator) in comparisons {
ops.push(op);
comparators.push(comparator.into());
}
ast::ExprCompare {
left: Box::new(left.into()),
ops: ops.into_boxed_slice(),
Expand Down

0 comments on commit b9f9008

Please sign in to comment.