Run shadowed-variable analyses in deferred handlers (#5181)

## Summary

This PR extracts a bunch of complex logic from `add_binding`, instead
running the the shadowing rules in the deferred handler, thereby
decoupling the binding phase (during which we build up the semantic
model) from the analysis phase, and generally making `add_binding` much
more focused.

This was made possible by improving the semantic model to better handle
deletions -- previously, we'd "lose track" of bindings if they were
deleted, which made this kind of refactor impossible.

## Test Plan

We have good automated coverage for this, but I want to benchmark it
separately.
This commit is contained in:
Charlie Marsh 2023-06-28 20:08:18 -04:00 committed by GitHub
parent 139a9f757b
commit 0e89c94947
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 222 additions and 109 deletions

View file

@ -126,6 +126,11 @@ impl<'a> Scope<'a> {
})
}
/// Returns the ID of the binding that the given binding shadows, if any.
pub fn shadowed_binding(&self, id: BindingId) -> Option<BindingId> {
self.shadowed_bindings.get(&id).copied()
}
/// Adds a reference to a star import (e.g., `from sys import *`) to this scope.
pub fn add_star_import(&mut self, import: StarImport<'a>) {
self.star_imports.push(import);