Parses a function definition. The given `start` offset is the start of either of the following: - `def` token - `async` token if it's an asynchronous function definition with no decorators - `@` token if the function definition has decorators # Panics If the parser isn't positioned at a `def` token. See:
(
&mut self,
decorator_list: DecoratorList,
start: TextSize,
)
| 1993 | /// |
| 1994 | /// See: <https://docs.python.org/3/reference/compound_stmts.html#function-definitions> |
| 1995 | fn parse_function_definition( |
| 1996 | &mut self, |
| 1997 | decorator_list: DecoratorList, |
| 1998 | start: TextSize, |
| 1999 | ) -> ast::StmtFunctionDef { |
| 2000 | self.bump(TokenKind::Def); |
| 2001 | |
| 2002 | // test_err function_def_missing_identifier |
| 2003 | // def (): ... |
| 2004 | // def () -> int: ... |
| 2005 | let name = self.parse_identifier(); |
| 2006 | |
| 2007 | // test_err function_def_unclosed_type_param_list |
| 2008 | // def foo[T1, *T2(a, b): |
| 2009 | // return a + b |
| 2010 | // x = 10 |
| 2011 | let type_params = self.try_parse_type_params(); |
| 2012 | |
| 2013 | // test_ok function_type_params_py312 |
| 2014 | // # parse_options: {"target-version": "3.12"} |
| 2015 | // def foo[T](): ... |
| 2016 | |
| 2017 | // test_err function_type_params_py311 |
| 2018 | // # parse_options: {"target-version": "3.11"} |
| 2019 | // def foo[T](): ... |
| 2020 | // def foo[](): ... |
| 2021 | if let Some(ast::TypeParams { range, .. }) = &type_params { |
| 2022 | self.add_unsupported_syntax_error( |
| 2023 | UnsupportedSyntaxErrorKind::TypeParameterList, |
| 2024 | *range, |
| 2025 | ); |
| 2026 | } |
| 2027 | |
| 2028 | // test_ok function_def_parameter_range |
| 2029 | // def foo( |
| 2030 | // first: int, |
| 2031 | // second: int, |
| 2032 | // ) -> int: ... |
| 2033 | |
| 2034 | // test_err function_def_unclosed_parameter_list |
| 2035 | // def foo(a: int, b: |
| 2036 | // def foo(): |
| 2037 | // return 42 |
| 2038 | // def foo(a: int, b: str |
| 2039 | // x = 10 |
| 2040 | let parameters = self.parse_parameters(FunctionKind::FunctionDef); |
| 2041 | |
| 2042 | let returns = if self.eat(TokenKind::Rarrow) { |
| 2043 | if self.at_expr() { |
| 2044 | // test_ok function_def_valid_return_expr |
| 2045 | // def foo() -> int | str: ... |
| 2046 | // def foo() -> lambda x: x: ... |
| 2047 | // def foo() -> int if True else str: ... |
| 2048 | |
| 2049 | // test_err function_def_invalid_return_expr |
| 2050 | // def foo() -> *int: ... |
| 2051 | // def foo() -> (*int): ... |
| 2052 | // def foo() -> yield x: ... |
no test coverage detected