mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 05:45:24 +00:00
Add definitions for match statement (#13147)
## Summary This PR adds definition for match patterns. ## Test Plan Update the existing test case for match statement symbols to verify that the definitions are added as well.
This commit is contained in:
parent
9986397d56
commit
17eb65b26f
6 changed files with 189 additions and 16 deletions
|
@ -26,7 +26,7 @@ use crate::semantic_index::use_def::{FlowSnapshot, UseDefMapBuilder};
|
|||
use crate::semantic_index::SemanticIndex;
|
||||
use crate::Db;
|
||||
|
||||
use super::definition::WithItemDefinitionNodeRef;
|
||||
use super::definition::{MatchPatternDefinitionNodeRef, WithItemDefinitionNodeRef};
|
||||
|
||||
pub(super) struct SemanticIndexBuilder<'db> {
|
||||
// Builder state
|
||||
|
@ -600,6 +600,17 @@ where
|
|||
self.visit_body(body);
|
||||
self.visit_body(orelse);
|
||||
}
|
||||
ast::Stmt::Match(ast::StmtMatch {
|
||||
subject,
|
||||
cases,
|
||||
range: _,
|
||||
}) => {
|
||||
self.add_standalone_expression(subject);
|
||||
self.visit_expr(subject);
|
||||
for case in cases {
|
||||
self.visit_match_case(case);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
walk_stmt(self, stmt);
|
||||
}
|
||||
|
@ -803,22 +814,77 @@ where
|
|||
}
|
||||
|
||||
fn visit_pattern(&mut self, pattern: &'ast ast::Pattern) {
|
||||
if let ast::Pattern::MatchAs(ast::PatternMatchAs {
|
||||
name: Some(name), ..
|
||||
})
|
||||
| ast::Pattern::MatchStar(ast::PatternMatchStar {
|
||||
// The definition visitor will recurse into the pattern so avoid walking it here.
|
||||
let mut definition_visitor = MatchPatternDefinitionVisitor::new(self, pattern);
|
||||
definition_visitor.visit_pattern(pattern);
|
||||
}
|
||||
}
|
||||
|
||||
/// A visitor that adds symbols and definitions for the identifiers in a match pattern.
|
||||
struct MatchPatternDefinitionVisitor<'a, 'db> {
|
||||
/// The semantic index builder in which to add the symbols and definitions.
|
||||
builder: &'a mut SemanticIndexBuilder<'db>,
|
||||
/// The index of the current node in the pattern.
|
||||
index: u32,
|
||||
/// The pattern being visited. This pattern is the outermost pattern that is being visited
|
||||
/// and is required to add the definitions.
|
||||
pattern: &'a ast::Pattern,
|
||||
}
|
||||
|
||||
impl<'a, 'db> MatchPatternDefinitionVisitor<'a, 'db> {
|
||||
fn new(builder: &'a mut SemanticIndexBuilder<'db>, pattern: &'a ast::Pattern) -> Self {
|
||||
Self {
|
||||
index: 0,
|
||||
builder,
|
||||
pattern,
|
||||
}
|
||||
}
|
||||
|
||||
fn add_symbol_and_definition(&mut self, identifier: &ast::Identifier) {
|
||||
let symbol = self
|
||||
.builder
|
||||
.add_or_update_symbol(identifier.id().clone(), SymbolFlags::IS_DEFINED);
|
||||
self.builder.add_definition(
|
||||
symbol,
|
||||
MatchPatternDefinitionNodeRef {
|
||||
pattern: self.pattern,
|
||||
identifier,
|
||||
index: self.index,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, 'db> Visitor<'ast> for MatchPatternDefinitionVisitor<'_, 'db>
|
||||
where
|
||||
'ast: 'db,
|
||||
{
|
||||
fn visit_expr(&mut self, expr: &'ast ast::Expr) {
|
||||
self.builder.visit_expr(expr);
|
||||
}
|
||||
|
||||
fn visit_pattern(&mut self, pattern: &'ast ast::Pattern) {
|
||||
if let ast::Pattern::MatchStar(ast::PatternMatchStar {
|
||||
name: Some(name),
|
||||
range: _,
|
||||
}) = pattern
|
||||
{
|
||||
self.add_symbol_and_definition(name);
|
||||
}
|
||||
|
||||
walk_pattern(self, pattern);
|
||||
|
||||
if let ast::Pattern::MatchAs(ast::PatternMatchAs {
|
||||
name: Some(name), ..
|
||||
})
|
||||
| ast::Pattern::MatchMapping(ast::PatternMatchMapping {
|
||||
rest: Some(name), ..
|
||||
}) = pattern
|
||||
{
|
||||
// TODO(dhruvmanila): Add definition
|
||||
self.add_or_update_symbol(name.id.clone(), SymbolFlags::IS_DEFINED);
|
||||
self.add_symbol_and_definition(name);
|
||||
}
|
||||
|
||||
walk_pattern(self, pattern);
|
||||
self.index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue