Move shadow tracking into Scope directly (#3854)

This commit is contained in:
Charlie Marsh 2023-04-03 15:33:44 -04:00 committed by GitHub
parent 449e08ed08
commit f4173b2a93
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 31 deletions

View file

@ -30,8 +30,8 @@ pub struct Context<'a> {
pub child_to_parent: FxHashMap<RefEquality<'a, Stmt>, RefEquality<'a, Stmt>>,
// A stack of all bindings created in any scope, at any point in execution.
pub bindings: Bindings<'a>,
// Map from binding index to indices of bindings that redefine it in other scopes.
pub redefinitions:
// Map from binding index to indexes of bindings that shadow it in other scopes.
pub shadowed_bindings:
std::collections::HashMap<BindingId, Vec<BindingId>, BuildNoHashHasher<BindingId>>,
pub exprs: Vec<RefEquality<'a, Expr>>,
pub scopes: Scopes<'a>,
@ -71,7 +71,7 @@ impl<'a> Context<'a> {
depths: FxHashMap::default(),
child_to_parent: FxHashMap::default(),
bindings: Bindings::default(),
redefinitions: IntMap::default(),
shadowed_bindings: IntMap::default(),
exprs: Vec::default(),
scopes: Scopes::default(),
scope_stack: ScopeStack::default(),

View file

@ -14,12 +14,10 @@ pub struct Scope<'a> {
/// A list of star imports in this scope. These represent _module_ imports (e.g., `sys` in
/// `from sys import *`), rather than individual bindings (e.g., individual members in `sys`).
star_imports: Vec<StarImportation<'a>>,
/// A map from bound name to binding index, for live bindings.
/// A map from bound name to binding index, for current bindings.
bindings: FxHashMap<&'a str, BindingId>,
/// A map from bound name to binding index, for bindings that were created
/// in the scope but rebound (and thus overridden) later on in the same
/// scope.
pub rebounds: FxHashMap<&'a str, Vec<BindingId>>,
/// A map from bound name to binding index, for bindings that were shadowed later in the scope.
shadowed_bindings: FxHashMap<&'a str, Vec<BindingId>>,
}
impl<'a> Scope<'a> {
@ -34,18 +32,23 @@ impl<'a> Scope<'a> {
uses_locals: false,
star_imports: Vec::default(),
bindings: FxHashMap::default(),
rebounds: FxHashMap::default(),
shadowed_bindings: FxHashMap::default(),
}
}
/// Returns the [id](BindingId) of the binding with the given name.
/// Returns the [id](BindingId) of the binding bound to the given name.
pub fn get(&self, name: &str) -> Option<&BindingId> {
self.bindings.get(name)
}
/// Adds a new binding with the given name to this scope.
pub fn add(&mut self, name: &'a str, id: BindingId) -> Option<BindingId> {
self.bindings.insert(name, id)
if let Some(id) = self.bindings.insert(name, id) {
self.shadowed_bindings.entry(name).or_default().push(id);
Some(id)
} else {
None
}
}
/// Returns `true` if this scope defines a binding with the given name.
@ -68,6 +71,15 @@ impl<'a> Scope<'a> {
self.bindings.iter()
}
/// Returns an iterator over all [bindings](BindingId) bound to the given name, including
/// those that were shadowed by later bindings.
pub fn bindings_for_name(&self, name: &str) -> impl Iterator<Item = &BindingId> {
self.bindings
.get(name)
.into_iter()
.chain(self.shadowed_bindings.get(name).into_iter().flatten().rev())
}
/// Adds a reference to a star import (e.g., `from sys import *`) to this scope.
pub fn add_star_import(&mut self, import: StarImportation<'a>) {
self.star_imports.push(import);