From 9bb23b0a38bd0532dc70c018b99a1ad30774f31c Mon Sep 17 00:00:00 2001 From: Dhruv Manilawala Date: Fri, 19 Apr 2024 16:46:15 +0530 Subject: [PATCH] Expect indented case block instead of match stmt (#11033) ## Summary This PR adds a new `Clause::Case` and uses it to parse the body of a `case` block. Earlier, it was using `Match` which would give an incorrect error message like: ``` | 1 | match subject: 2 | case 1: 3 | case 2: ... | ^^^^ Syntax Error: Expected an indented block after `match` statement | ``` ## Test Plan Add test case and update the snapshot. --- .../inline/err/case_expect_indented_block.py | 3 + .../src/parser/statement.rs | 11 ++- ..._syntax@case_expect_indented_block.py.snap | 84 +++++++++++++++++++ 3 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 crates/ruff_python_parser/resources/inline/err/case_expect_indented_block.py create mode 100644 crates/ruff_python_parser/tests/snapshots/invalid_syntax@case_expect_indented_block.py.snap diff --git a/crates/ruff_python_parser/resources/inline/err/case_expect_indented_block.py b/crates/ruff_python_parser/resources/inline/err/case_expect_indented_block.py new file mode 100644 index 0000000000..168641812d --- /dev/null +++ b/crates/ruff_python_parser/resources/inline/err/case_expect_indented_block.py @@ -0,0 +1,3 @@ +match subject: + case 1: + case 2: ... diff --git a/crates/ruff_python_parser/src/parser/statement.rs b/crates/ruff_python_parser/src/parser/statement.rs index f98dc33253..4edf574021 100644 --- a/crates/ruff_python_parser/src/parser/statement.rs +++ b/crates/ruff_python_parser/src/parser/statement.rs @@ -2492,7 +2492,12 @@ impl<'src> Parser<'src> { }; self.expect(TokenKind::Colon); - let body = self.parse_body(Clause::Match); + + // test_err case_expect_indented_block + // match subject: + // case 1: + // case 2: ... + let body = self.parse_body(Clause::Case); ast::MatchCase { pattern, @@ -3363,7 +3368,7 @@ enum Clause { Class, While, FunctionDef, - Match, + Case, Try, Except, Finally, @@ -3380,7 +3385,7 @@ impl Display for Clause { Clause::Class => write!(f, "`class` definition"), Clause::While => write!(f, "`while` statement"), Clause::FunctionDef => write!(f, "function definition"), - Clause::Match => write!(f, "`match` statement"), + Clause::Case => write!(f, "`case` block"), Clause::Try => write!(f, "`try` statement"), Clause::Except => write!(f, "`except` clause"), Clause::Finally => write!(f, "`finally` clause"), diff --git a/crates/ruff_python_parser/tests/snapshots/invalid_syntax@case_expect_indented_block.py.snap b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@case_expect_indented_block.py.snap new file mode 100644 index 0000000000..a72d0cac0a --- /dev/null +++ b/crates/ruff_python_parser/tests/snapshots/invalid_syntax@case_expect_indented_block.py.snap @@ -0,0 +1,84 @@ +--- +source: crates/ruff_python_parser/tests/fixtures.rs +input_file: crates/ruff_python_parser/resources/inline/err/case_expect_indented_block.py +--- +## AST + +``` +Module( + ModModule { + range: 0..43, + body: [ + Match( + StmtMatch { + range: 0..42, + subject: Name( + ExprName { + range: 6..13, + id: "subject", + ctx: Load, + }, + ), + cases: [ + MatchCase { + range: 19..26, + pattern: MatchValue( + PatternMatchValue { + range: 24..25, + value: NumberLiteral( + ExprNumberLiteral { + range: 24..25, + value: Int( + 1, + ), + }, + ), + }, + ), + guard: None, + body: [], + }, + MatchCase { + range: 31..42, + pattern: MatchValue( + PatternMatchValue { + range: 36..37, + value: NumberLiteral( + ExprNumberLiteral { + range: 36..37, + value: Int( + 2, + ), + }, + ), + }, + ), + guard: None, + body: [ + Expr( + StmtExpr { + range: 39..42, + value: EllipsisLiteral( + ExprEllipsisLiteral { + range: 39..42, + }, + ), + }, + ), + ], + }, + ], + }, + ), + ], + }, +) +``` +## Errors + + | +1 | match subject: +2 | case 1: +3 | case 2: ... + | ^^^^ Syntax Error: Expected an indented block after `case` block + |