MCPcopy Create free account
hub / github.com/astral-sh/ruff / try_parse_match_statement

Method try_parse_match_statement

crates/ruff_python_parser/src/parser/statement.rs:2544–2601  ·  view source on GitHub ↗

Try parsing a `match` statement. This uses speculative parsing to remove the ambiguity of whether the `match` token is used as a keyword or an identifier. This ambiguity arises only in if the `match` token is followed by certain tokens. For example, if `match` is followed by `[`, we can't know if it's used in the context of a subscript expression or as a list expression: ```python # Subscript ex

(&mut self)

Source from the content-addressed store, hash-verified

2542 ///
2543 /// See: <https://docs.python.org/3/reference/compound_stmts.html#the-match-statement>
2544 fn try_parse_match_statement(&mut self) -> Option<ast::StmtMatch> {
2545 let checkpoint = self.checkpoint();
2546
2547 let start = self.node_start();
2548 self.bump(TokenKind::Match);
2549
2550 let subject = self.parse_match_subject_expression();
2551
2552 match self.current_token_kind() {
2553 // test_ok match_annotated_assignment
2554 // match[0]: int
2555 // match [x, y, z]: dict
2556 TokenKind::Colon if self.peek() == TokenKind::Newline => {
2557 // `match` is a keyword — colon followed by newline confirms
2558 // this is a match statement, not an annotated assignment like
2559 // `match [x, y, z]: {dict}` or `match[0]: int`.
2560 self.bump(TokenKind::Colon);
2561
2562 let cases = self.parse_match_body();
2563
2564 Some(ast::StmtMatch {
2565 subject: Box::new(subject),
2566 cases,
2567 range: self.node_range(start),
2568 node_index: AtomicNodeIndex::NONE,
2569 })
2570 }
2571 TokenKind::Newline if matches!(self.peek2(), (TokenKind::Indent, TokenKind::Case)) => {
2572 // `match` is a keyword
2573
2574 // test_err match_expected_colon
2575 // match [1, 2]
2576 // case _: ...
2577 self.add_error(
2578 ParseErrorType::ExpectedToken {
2579 found: self.current_token_kind(),
2580 expected: TokenKind::Colon,
2581 },
2582 self.current_token_range(),
2583 );
2584
2585 let cases = self.parse_match_body();
2586
2587 Some(ast::StmtMatch {
2588 subject: Box::new(subject),
2589 cases,
2590 range: self.node_range(start),
2591 node_index: AtomicNodeIndex::NONE,
2592 })
2593 }
2594 _ => {
2595 // `match` is an identifier
2596 self.rewind(checkpoint);
2597
2598 None
2599 }
2600 }
2601 }

Callers 1

parse_statementMethod · 0.80

Calls 11

node_startMethod · 0.80
current_token_kindMethod · 0.80
parse_match_bodyMethod · 0.80
node_rangeMethod · 0.80
current_token_rangeMethod · 0.80
checkpointMethod · 0.45
bumpMethod · 0.45
peekMethod · 0.45
add_errorMethod · 0.45
rewindMethod · 0.45

Tested by

no test coverage detected