mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
52 lines
1.6 KiB
Rust
52 lines
1.6 KiB
Rust
use std::collections::HashSet;
|
|
|
|
use crate::ast;
|
|
use crate::error::{LexicalError, LexicalErrorType};
|
|
|
|
type FunctionArgument = (Option<Option<String>>, ast::Expression);
|
|
|
|
pub fn parse_args(func_args: Vec<FunctionArgument>) -> Result<ast::ArgumentList, LexicalError> {
|
|
let mut args = vec![];
|
|
let mut keywords = vec![];
|
|
|
|
let mut keyword_names = HashSet::with_capacity(func_args.len());
|
|
for (name, value) in func_args {
|
|
match name {
|
|
Some(n) => {
|
|
if let Some(keyword_name) = n.clone() {
|
|
if keyword_names.contains(&keyword_name) {
|
|
return Err(LexicalError {
|
|
error: LexicalErrorType::DuplicateKeywordArgumentError,
|
|
location: value.location.clone(),
|
|
});
|
|
}
|
|
|
|
keyword_names.insert(keyword_name.clone());
|
|
}
|
|
|
|
keywords.push(ast::Keyword { name: n, value });
|
|
}
|
|
None => {
|
|
// Allow starred args after keyword arguments.
|
|
if !keywords.is_empty() && !is_starred(&value) {
|
|
return Err(LexicalError {
|
|
error: LexicalErrorType::PositionalArgumentError,
|
|
location: value.location.clone(),
|
|
});
|
|
}
|
|
|
|
args.push(value);
|
|
}
|
|
}
|
|
}
|
|
Ok(ast::ArgumentList { args, keywords })
|
|
}
|
|
|
|
fn is_starred(exp: &ast::Expression) -> bool {
|
|
if let ast::ExpressionType::Starred { .. } = exp.node {
|
|
true
|
|
} else {
|
|
false
|
|
}
|
|
}
|