mirror of
https://github.com/RustPython/Parser.git
synced 2025-07-13 08:05:17 +00:00
added lex error: DuplicateArguments
This commit is contained in:
parent
78bcb6fb3e
commit
8eeca31fe6
3 changed files with 68 additions and 24 deletions
|
@ -6,7 +6,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
ast,
|
ast,
|
||||||
error::{LexicalError, LexicalErrorType},
|
error::{LexicalError, LexicalErrorType},
|
||||||
function::{ArgumentList, parse_args, parse_params},
|
function::{ArgumentList, parse_args, parse_params, validate_arguments},
|
||||||
lexer,
|
lexer,
|
||||||
context::set_context,
|
context::set_context,
|
||||||
string::parse_strings,
|
string::parse_strings,
|
||||||
|
@ -552,7 +552,8 @@ FuncDef: ast::Stmt = {
|
||||||
};
|
};
|
||||||
|
|
||||||
Parameters: ast::Arguments = {
|
Parameters: ast::Arguments = {
|
||||||
"(" <a: (ParameterList<TypedParameter>)?> ")" => {
|
"(" <a: (ParameterList<TypedParameter>)?> ")" =>? {
|
||||||
|
let args = validate_arguments(
|
||||||
a.unwrap_or_else(|| ast::Arguments {
|
a.unwrap_or_else(|| ast::Arguments {
|
||||||
posonlyargs: vec![],
|
posonlyargs: vec![],
|
||||||
args: vec![],
|
args: vec![],
|
||||||
|
@ -562,6 +563,9 @@ Parameters: ast::Arguments = {
|
||||||
kwarg: None,
|
kwarg: None,
|
||||||
defaults: vec![]
|
defaults: vec![]
|
||||||
})
|
})
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(args)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -774,8 +778,9 @@ NamedExpression: ast::Expr = {
|
||||||
};
|
};
|
||||||
|
|
||||||
LambdaDef: ast::Expr = {
|
LambdaDef: ast::Expr = {
|
||||||
<location:@L> "lambda" <p:ParameterList<UntypedParameter>?> ":" <body:Test<"all">> <end_location:@R> => {
|
<location:@L> "lambda" <p:ParameterList<UntypedParameter>?> ":" <body:Test<"all">> <end_location:@R> =>? {
|
||||||
let p = p.unwrap_or_else(|| {
|
let p = validate_arguments(
|
||||||
|
p.unwrap_or_else(|| {
|
||||||
ast::Arguments {
|
ast::Arguments {
|
||||||
posonlyargs: vec![],
|
posonlyargs: vec![],
|
||||||
args: vec![],
|
args: vec![],
|
||||||
|
@ -785,8 +790,10 @@ LambdaDef: ast::Expr = {
|
||||||
kwarg: None,
|
kwarg: None,
|
||||||
defaults: vec![]
|
defaults: vec![]
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
ast::Expr {
|
))?;
|
||||||
|
|
||||||
|
Ok(ast::Expr {
|
||||||
location,
|
location,
|
||||||
end_location: Some(end_location),
|
end_location: Some(end_location),
|
||||||
custom: (),
|
custom: (),
|
||||||
|
@ -794,7 +801,7 @@ LambdaDef: ast::Expr = {
|
||||||
args: Box::new(p),
|
args: Box::new(p),
|
||||||
body: Box::new(body)
|
body: Box::new(body)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ pub enum LexicalErrorType {
|
||||||
TabError,
|
TabError,
|
||||||
TabsAfterSpaces,
|
TabsAfterSpaces,
|
||||||
DefaultArgumentError,
|
DefaultArgumentError,
|
||||||
|
DuplicateArgumentError,
|
||||||
PositionalArgumentError,
|
PositionalArgumentError,
|
||||||
UnpackedArgumentError,
|
UnpackedArgumentError,
|
||||||
DuplicateKeywordArgumentError,
|
DuplicateKeywordArgumentError,
|
||||||
|
@ -50,6 +51,9 @@ impl fmt::Display for LexicalErrorType {
|
||||||
LexicalErrorType::DefaultArgumentError => {
|
LexicalErrorType::DefaultArgumentError => {
|
||||||
write!(f, "non-default argument follows default argument")
|
write!(f, "non-default argument follows default argument")
|
||||||
}
|
}
|
||||||
|
LexicalErrorType::DuplicateArgumentError => {
|
||||||
|
write!(f, "duplicate argument in function definition")
|
||||||
|
}
|
||||||
LexicalErrorType::DuplicateKeywordArgumentError => {
|
LexicalErrorType::DuplicateKeywordArgumentError => {
|
||||||
write!(f, "keyword argument repeated")
|
write!(f, "keyword argument repeated")
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,39 @@ pub struct ArgumentList {
|
||||||
type ParameterDefs = (Vec<ast::Arg>, Vec<ast::Arg>, Vec<ast::Expr>);
|
type ParameterDefs = (Vec<ast::Arg>, Vec<ast::Arg>, Vec<ast::Expr>);
|
||||||
type ParameterDef = (ast::Arg, Option<ast::Expr>);
|
type ParameterDef = (ast::Arg, Option<ast::Expr>);
|
||||||
|
|
||||||
|
pub fn validate_arguments(
|
||||||
|
arguments: ast::Arguments
|
||||||
|
) -> Result<ast::Arguments, LexicalError> {
|
||||||
|
let mut all_args: Vec<&ast::Located<ast::ArgData>> = vec![];
|
||||||
|
|
||||||
|
all_args.extend(arguments.posonlyargs.iter());
|
||||||
|
all_args.extend(arguments.args.iter());
|
||||||
|
|
||||||
|
if let Some(a) = &arguments.vararg {
|
||||||
|
all_args.push(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
all_args.extend(arguments.kwonlyargs.iter());
|
||||||
|
|
||||||
|
if let Some(a) = &arguments.kwarg {
|
||||||
|
all_args.push(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut all_arg_names =
|
||||||
|
FxHashSet::with_hasher(Default::default());
|
||||||
|
for arg in all_args {
|
||||||
|
let arg_name = arg.node.arg.clone();
|
||||||
|
if !all_arg_names.insert(arg_name) {
|
||||||
|
return Err(LexicalError {
|
||||||
|
error: LexicalErrorType::DuplicateArgumentError,
|
||||||
|
location: arg.location,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parse_params(
|
pub fn parse_params(
|
||||||
params: (Vec<ParameterDef>, Vec<ParameterDef>),
|
params: (Vec<ParameterDef>, Vec<ParameterDef>),
|
||||||
) -> Result<ParameterDefs, LexicalError> {
|
) -> Result<ParameterDefs, LexicalError> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue