Parses a parameter list for the given function kind. See:
(&mut self, function_kind: FunctionKind)
| 3308 | /// |
| 3309 | /// See: <https://docs.python.org/3/reference/compound_stmts.html#grammar-token-python-grammar-parameter_list> |
| 3310 | pub(super) fn parse_parameters(&mut self, function_kind: FunctionKind) -> ast::Parameters { |
| 3311 | let start = self.node_start(); |
| 3312 | |
| 3313 | if matches!(function_kind, FunctionKind::FunctionDef) { |
| 3314 | self.expect(TokenKind::Lpar); |
| 3315 | } |
| 3316 | |
| 3317 | // TODO(dhruvmanila): This has the same problem as `parse_match_pattern_mapping` |
| 3318 | // has where if there are multiple kwarg or vararg, the last one will win and |
| 3319 | // the parser will drop the previous ones. Another thing is the vararg and kwarg |
| 3320 | // uses `Parameter` (not `ParameterWithDefault`) which means that the parser cannot |
| 3321 | // recover well from `*args=(1, 2)`. |
| 3322 | let mut parameters = ast::Parameters::default(); |
| 3323 | let parameters_snapshot = self.parameter_scratch.snapshot(); |
| 3324 | let mut args_snapshot = None; |
| 3325 | let mut kwonlyargs_snapshot = None; |
| 3326 | |
| 3327 | let mut seen_default_param = false; // `a=10` |
| 3328 | let mut seen_positional_only_separator = false; // `/` |
| 3329 | let mut seen_keyword_only_separator = false; // `*` |
| 3330 | let mut seen_keyword_only_param_after_separator = false; |
| 3331 | |
| 3332 | // Range of the keyword only separator if it's the last parameter in the list. |
| 3333 | let mut last_keyword_only_separator_range = None; |
| 3334 | |
| 3335 | self.parse_comma_separated_list(RecoveryContextKind::Parameters(function_kind), |parser| { |
| 3336 | let param_start = parser.node_start(); |
| 3337 | |
| 3338 | if parameters.kwarg.is_some() { |
| 3339 | // test_err params_follows_var_keyword_param |
| 3340 | // def foo(**kwargs, a, /, b=10, *, *args): ... |
| 3341 | parser.add_error( |
| 3342 | ParseErrorType::ParamAfterVarKeywordParam, |
| 3343 | parser.current_token_range(), |
| 3344 | ); |
| 3345 | } |
| 3346 | |
| 3347 | match parser.current_token_kind() { |
| 3348 | TokenKind::Star => { |
| 3349 | let star_range = parser.current_token_range(); |
| 3350 | parser.bump(TokenKind::Star); |
| 3351 | |
| 3352 | kwonlyargs_snapshot |
| 3353 | .get_or_insert_with(|| parser.parameter_scratch.snapshot()); |
| 3354 | |
| 3355 | if parser.at_name_or_soft_keyword() { |
| 3356 | let param = parser.parse_parameter(param_start, function_kind, AllowStarAnnotation::Yes); |
| 3357 | let param_star_range = parser.node_range(star_range.start()); |
| 3358 | |
| 3359 | if parser.at(TokenKind::Equal) { |
| 3360 | // test_err params_var_positional_with_default |
| 3361 | // def foo(a, *args=(1, 2)): ... |
| 3362 | parser.add_error( |
| 3363 | ParseErrorType::VarParameterWithDefault, |
| 3364 | parser.current_token_range(), |
| 3365 | ); |
| 3366 | } |
| 3367 |
no test coverage detected