Move dead_scopes to deferred.scopes (#5171)

## Summary

This is more consistent with the rest of the `deferred` patterns.
This commit is contained in:
Charlie Marsh 2023-06-18 11:57:38 -04:00 committed by GitHub
parent 524a2045ba
commit a6cf31cc89
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 9 additions and 8 deletions

View file

@ -1,13 +1,14 @@
use ruff_text_size::TextRange;
use rustpython_parser::ast::Expr;
use ruff_python_semantic::Snapshot;
use ruff_python_semantic::{ScopeId, Snapshot};
/// A collection of AST nodes that are deferred for later analysis.
/// Used to, e.g., store functions, whose bodies shouldn't be analyzed until all
/// module-level definitions have been analyzed.
#[derive(Debug, Default)]
pub(crate) struct Deferred<'a> {
pub(crate) scopes: Vec<ScopeId>,
pub(crate) string_type_definitions: Vec<(TextRange, &'a str, Snapshot)>,
pub(crate) future_type_definitions: Vec<(&'a Expr, Snapshot)>,
pub(crate) functions: Vec<Snapshot>,

View file

@ -2038,10 +2038,12 @@ where
// Post-visit.
match stmt {
Stmt::FunctionDef(_) | Stmt::AsyncFunctionDef(_) => {
self.deferred.scopes.push(self.semantic.scope_id);
self.semantic.pop_scope();
self.semantic.pop_definition();
}
Stmt::ClassDef(ast::StmtClassDef { name, .. }) => {
self.deferred.scopes.push(self.semantic.scope_id);
self.semantic.pop_scope();
self.semantic.pop_definition();
self.add_binding(
@ -3785,6 +3787,7 @@ where
| Expr::ListComp(_)
| Expr::DictComp(_)
| Expr::SetComp(_) => {
self.deferred.scopes.push(self.semantic.scope_id);
self.semantic.pop_scope();
}
_ => {}
@ -4692,7 +4695,7 @@ impl<'a> Checker<'a> {
}
}
fn check_dead_scopes(&mut self) {
fn check_deferred_scopes(&mut self) {
if !self.any_enabled(&[
Rule::UnusedImport,
Rule::GlobalVariableNotAssigned,
@ -4771,7 +4774,7 @@ impl<'a> Checker<'a> {
};
let mut diagnostics: Vec<Diagnostic> = vec![];
for scope_id in self.semantic.dead_scopes.iter().rev() {
for scope_id in self.deferred.scopes.iter().rev() {
let scope = &self.semantic.scopes[*scope_id];
if scope.kind.is_module() {
@ -5256,8 +5259,8 @@ pub(crate) fn check_ast(
// Reset the scope to module-level, and check all consumed scopes.
checker.semantic.scope_id = ScopeId::global();
checker.semantic.dead_scopes.push(ScopeId::global());
checker.check_dead_scopes();
checker.deferred.scopes.push(ScopeId::global());
checker.check_deferred_scopes();
checker.diagnostics
}

View file

@ -40,7 +40,6 @@ pub struct SemanticModel<'a> {
/// Stack of all scopes, along with the identifier of the current scope.
pub scopes: Scopes<'a>,
pub scope_id: ScopeId,
pub dead_scopes: Vec<ScopeId>,
/// Stack of all definitions created in any scope, at any point in execution.
pub definitions: Definitions<'a>,
@ -130,7 +129,6 @@ impl<'a> SemanticModel<'a> {
exprs: Vec::default(),
scopes: Scopes::default(),
scope_id: ScopeId::global(),
dead_scopes: Vec::default(),
definitions: Definitions::for_module(module),
definition_id: DefinitionId::module(),
bindings: Bindings::default(),
@ -596,7 +594,6 @@ impl<'a> SemanticModel<'a> {
/// Pop the current [`Scope`] off the stack.
pub fn pop_scope(&mut self) {
self.dead_scopes.push(self.scope_id);
self.scope_id = self.scopes[self.scope_id]
.parent
.expect("Attempted to pop without scope");