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