Skip to content

Commit

Permalink
[red-knot] Add symbols defined by match statements (#12926)
Browse files Browse the repository at this point in the history
## Summary

This PR adds symbols introduced by `match` statements.

There are three patterns that introduces new symbols:
* `as` pattern
* Sequence pattern
* Mapping pattern

The recursive nature of the visitor makes sure that all symbols are
added.

## Test Plan

Add test case for all types of patterns that introduces a symbol.
  • Loading branch information
dhruvmanila authored Aug 20, 2024
1 parent aefadde commit 1a8f29e
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 1 deletion.
24 changes: 24 additions & 0 deletions crates/red_knot_python_semantic/src/semantic_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1017,4 +1017,28 @@ def x():
vec!["bar", "foo", "Test", "<module>"]
);
}

#[test]
fn match_stmt_symbols() {
let TestCase { db, file } = test_case(
"
match subject:
case a: ...
case [b, c, *d]: ...
case e as f: ...
case {'x': g, **h}: ...
case Foo(i, z=j): ...
case k | l: ...
case _: ...
",
);

let global_table = symbol_table(&db, global_scope(&db, file));

assert!(global_table.symbol_by_name("Foo").unwrap().is_used());
assert_eq!(
names(&global_table),
vec!["subject", "a", "b", "c", "d", "f", "e", "h", "g", "Foo", "i", "j", "k", "l"]
);
}
}
21 changes: 20 additions & 1 deletion crates/red_knot_python_semantic/src/semantic_index/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use ruff_db::parsed::ParsedModule;
use ruff_index::IndexVec;
use ruff_python_ast as ast;
use ruff_python_ast::name::Name;
use ruff_python_ast::visitor::{walk_expr, walk_stmt, Visitor};
use ruff_python_ast::visitor::{walk_expr, walk_pattern, walk_stmt, Visitor};
use ruff_python_ast::AnyParameterRef;

use crate::ast_node_ref::AstNodeRef;
Expand Down Expand Up @@ -747,6 +747,25 @@ where
self.visit_parameter(parameter);
}
}

fn visit_pattern(&mut self, pattern: &'ast ast::Pattern) {
if let ast::Pattern::MatchAs(ast::PatternMatchAs {
name: Some(name), ..
})
| ast::Pattern::MatchStar(ast::PatternMatchStar {
name: Some(name),
range: _,
})
| ast::Pattern::MatchMapping(ast::PatternMatchMapping {
rest: Some(name), ..
}) = pattern
{
// TODO(dhruvmanila): Add definition
self.add_or_update_symbol(name.id.clone(), SymbolFlags::IS_DEFINED);
}

walk_pattern(self, pattern);
}
}

#[derive(Copy, Clone, Debug)]
Expand Down

0 comments on commit 1a8f29e

Please sign in to comment.