Parses a statement that is valid after an `async` token. If the statement is not a valid `async` statement, an error will be reported and it will be parsed as a statement. See: - - - <https://docs.python.org/3/reference/compound_stmt
(&mut self)
| 2829 | /// - <https://docs.python.org/3/reference/compound_stmts.html#the-async-for-statement> |
| 2830 | /// - <https://docs.python.org/3/reference/compound_stmts.html#coroutine-function-definition> |
| 2831 | fn parse_async_statement(&mut self) -> Stmt { |
| 2832 | let async_start = self.node_start(); |
| 2833 | self.bump(TokenKind::Async); |
| 2834 | |
| 2835 | match self.current_token_kind() { |
| 2836 | // test_ok async_function_definition |
| 2837 | // async def foo(): ... |
| 2838 | TokenKind::Def => Stmt::FunctionDef(ast::StmtFunctionDef { |
| 2839 | is_async: true, |
| 2840 | ..self.parse_function_definition(DecoratorList::new(), async_start) |
| 2841 | }), |
| 2842 | |
| 2843 | // test_ok async_with_statement |
| 2844 | // async with item: ... |
| 2845 | TokenKind::With => Stmt::With(ast::StmtWith { |
| 2846 | is_async: true, |
| 2847 | ..self.parse_with_statement(async_start) |
| 2848 | }), |
| 2849 | |
| 2850 | // test_ok async_for_statement |
| 2851 | // async for target in iter: ... |
| 2852 | TokenKind::For => Stmt::For(ast::StmtFor { |
| 2853 | is_async: true, |
| 2854 | ..self.parse_for_statement(async_start) |
| 2855 | }), |
| 2856 | |
| 2857 | kind => { |
| 2858 | // test_err async_unexpected_token |
| 2859 | // async class Foo: ... |
| 2860 | // async while test: ... |
| 2861 | // async x = 1 |
| 2862 | // async async def foo(): ... |
| 2863 | // async match test: |
| 2864 | // case _: ... |
| 2865 | self.add_error( |
| 2866 | ParseErrorType::UnexpectedTokenAfterAsync(kind), |
| 2867 | self.current_token_range(), |
| 2868 | ); |
| 2869 | |
| 2870 | // Although this statement is not a valid `async` statement, |
| 2871 | // we still parse it. Guard the recursive recovery path so |
| 2872 | // `async async async ...` cannot overflow the parser stack. |
| 2873 | if let Some(stmt) = self.with_recursion(Self::parse_statement) { |
| 2874 | stmt |
| 2875 | } else { |
| 2876 | let range = self.node_range(async_start); |
| 2877 | self.add_error(ParseErrorType::RecursionLimitExceeded, range); |
| 2878 | Stmt::Expr(ast::StmtExpr { |
| 2879 | range, |
| 2880 | value: Box::new(Expr::Name(ast::ExprName { |
| 2881 | range, |
| 2882 | id: Name::new_static("async"), |
| 2883 | ctx: ExprContext::Invalid, |
| 2884 | node_index: AtomicNodeIndex::NONE, |
| 2885 | })), |
| 2886 | node_index: AtomicNodeIndex::NONE, |
| 2887 | }) |
| 2888 | } |
no test coverage detected