diff --git a/crates/ruff/src/checkers/ast/mod.rs b/crates/ruff/src/checkers/ast/mod.rs index 58b67216ebee88..480edc98367ae1 100644 --- a/crates/ruff/src/checkers/ast/mod.rs +++ b/crates/ruff/src/checkers/ast/mod.rs @@ -24,13 +24,13 @@ use ruff_python_semantic::analyze::branch_detection; use ruff_python_semantic::analyze::typing::{Callable, SubscriptKind}; use ruff_python_semantic::analyze::visibility::ModuleSource; use ruff_python_semantic::binding::{ - Binding, BindingFlags, BindingId, BindingKind, Exceptions, ExecutionContext, Export, - FromImportation, Importation, StarImportation, SubmoduleImportation, + Binding, BindingFlags, BindingId, BindingKind, Exceptions, Export, FromImportation, + Importation, StarImportation, SubmoduleImportation, }; +use ruff_python_semantic::context::ExecutionContext; use ruff_python_semantic::definition::{ContextualizedDefinition, Module, ModuleKind}; use ruff_python_semantic::model::{ResolvedReference, SemanticModel, SemanticModelFlags}; use ruff_python_semantic::node::NodeId; -use ruff_python_semantic::reference::ReferenceContext; use ruff_python_semantic::scope::{ClassDef, FunctionDef, Lambda, Scope, ScopeId, ScopeKind}; use ruff_python_stdlib::builtins::{BUILTINS, MAGIC_GLOBALS}; use ruff_python_stdlib::path::is_python_stub_file; @@ -300,7 +300,7 @@ where self.semantic_model.add_local_reference( *binding_id, stmt.range(), - ReferenceContext::Runtime, + ExecutionContext::Runtime, ); } else { // Ensure that every nonlocal has an existing binding from a parent scope. @@ -4955,7 +4955,7 @@ impl<'a> Checker<'a> { self.semantic_model.add_global_reference( binding_id, range, - ReferenceContext::Runtime, + ExecutionContext::Runtime, ); } } diff --git a/crates/ruff/src/rules/flake8_type_checking/helpers.rs b/crates/ruff/src/rules/flake8_type_checking/helpers.rs index c9b54ed3c5c45f..736704766922c4 100644 --- a/crates/ruff/src/rules/flake8_type_checking/helpers.rs +++ b/crates/ruff/src/rules/flake8_type_checking/helpers.rs @@ -3,7 +3,7 @@ use rustpython_parser::ast::{self, Constant, Expr}; use ruff_python_ast::call_path::from_qualified_name; use ruff_python_ast::helpers::map_callable; -use ruff_python_semantic::binding::{Binding, BindingKind, ExecutionContext}; +use ruff_python_semantic::binding::{Binding, BindingKind}; use ruff_python_semantic::model::SemanticModel; use ruff_python_semantic::scope::ScopeKind; @@ -51,7 +51,7 @@ pub(crate) fn is_valid_runtime_import(semantic_model: &SemanticModel, binding: & | BindingKind::FromImportation(..) | BindingKind::SubmoduleImportation(..) ) { - matches!(binding.context, ExecutionContext::Runtime) + binding.context.is_runtime() && binding.references().any(|reference_id| { semantic_model .references diff --git a/crates/ruff_python_semantic/src/binding.rs b/crates/ruff_python_semantic/src/binding.rs index 6530667410b062..740b898eead387 100644 --- a/crates/ruff_python_semantic/src/binding.rs +++ b/crates/ruff_python_semantic/src/binding.rs @@ -7,6 +7,7 @@ use ruff_index::{newtype_index, IndexSlice, IndexVec}; use ruff_python_ast::helpers; use ruff_python_ast::source_code::Locator; +use crate::context::ExecutionContext; use crate::model::SemanticModel; use crate::node::NodeId; use crate::reference::ReferenceId; @@ -272,9 +273,3 @@ bitflags! { const IMPORT_ERROR = 0b0000_0100; } } - -#[derive(Copy, Debug, Clone, is_macro::Is)] -pub enum ExecutionContext { - Runtime, - Typing, -} diff --git a/crates/ruff_python_semantic/src/context.rs b/crates/ruff_python_semantic/src/context.rs new file mode 100644 index 00000000000000..6742b682192296 --- /dev/null +++ b/crates/ruff_python_semantic/src/context.rs @@ -0,0 +1,7 @@ +#[derive(Debug, Copy, Clone, is_macro::Is)] +pub enum ExecutionContext { + /// The reference occurs in a runtime context. + Runtime, + /// The reference occurs in a typing-only context. + Typing, +} diff --git a/crates/ruff_python_semantic/src/lib.rs b/crates/ruff_python_semantic/src/lib.rs index 60fc39f4a8f104..86e26c5481bc38 100644 --- a/crates/ruff_python_semantic/src/lib.rs +++ b/crates/ruff_python_semantic/src/lib.rs @@ -1,5 +1,6 @@ pub mod analyze; pub mod binding; +pub mod context; pub mod definition; pub mod model; pub mod node; diff --git a/crates/ruff_python_semantic/src/model.rs b/crates/ruff_python_semantic/src/model.rs index e70dd9bc373d76..3a63c072e58754 100644 --- a/crates/ruff_python_semantic/src/model.rs +++ b/crates/ruff_python_semantic/src/model.rs @@ -13,12 +13,13 @@ use ruff_python_stdlib::path::is_python_stub_file; use ruff_python_stdlib::typing::TYPING_EXTENSIONS; use crate::binding::{ - Binding, BindingId, BindingKind, Bindings, Exceptions, ExecutionContext, FromImportation, - Importation, SubmoduleImportation, + Binding, BindingId, BindingKind, Bindings, Exceptions, FromImportation, Importation, + SubmoduleImportation, }; +use crate::context::ExecutionContext; use crate::definition::{Definition, DefinitionId, Definitions, Member, Module}; use crate::node::{NodeId, Nodes}; -use crate::reference::{ReferenceContext, References}; +use crate::reference::References; use crate::scope::{Scope, ScopeId, ScopeKind, Scopes}; /// A semantic model for a Python module, to enable querying the module's semantic information. @@ -126,26 +127,12 @@ impl<'a> SemanticModel<'a> { if let Some(binding_id) = self.scopes.global().get(symbol).copied() { // Mark the binding as used. let context = self.execution_context(); - let reference_id = self.references.push( - ScopeId::global(), - range, - match context { - ExecutionContext::Runtime => ReferenceContext::Runtime, - ExecutionContext::Typing => ReferenceContext::Typing, - }, - ); + let reference_id = self.references.push(ScopeId::global(), range, context); self.bindings[binding_id].references.push(reference_id); // Mark any submodule aliases as used. if let Some(binding_id) = self.resolve_submodule(ScopeId::global(), binding_id) { - let reference_id = self.references.push( - ScopeId::global(), - range, - match context { - ExecutionContext::Runtime => ReferenceContext::Runtime, - ExecutionContext::Typing => ReferenceContext::Typing, - }, - ); + let reference_id = self.references.push(ScopeId::global(), range, context); self.bindings[binding_id].references.push(reference_id); } @@ -176,26 +163,12 @@ impl<'a> SemanticModel<'a> { if let Some(binding_id) = scope.get(symbol).copied() { // Mark the binding as used. let context = self.execution_context(); - let reference_id = self.references.push( - self.scope_id, - range, - match context { - ExecutionContext::Runtime => ReferenceContext::Runtime, - ExecutionContext::Typing => ReferenceContext::Typing, - }, - ); + let reference_id = self.references.push(self.scope_id, range, context); self.bindings[binding_id].references.push(reference_id); // Mark any submodule aliases as used. if let Some(binding_id) = self.resolve_submodule(scope_id, binding_id) { - let reference_id = self.references.push( - self.scope_id, - range, - match context { - ExecutionContext::Runtime => ReferenceContext::Runtime, - ExecutionContext::Typing => ReferenceContext::Typing, - }, - ); + let reference_id = self.references.push(self.scope_id, range, context); self.bindings[binding_id].references.push(reference_id); } @@ -585,7 +558,7 @@ impl<'a> SemanticModel<'a> { &mut self, binding_id: BindingId, range: TextRange, - context: ReferenceContext, + context: ExecutionContext, ) { let reference_id = self.references.push(self.scope_id, range, context); self.bindings[binding_id].references.push(reference_id); @@ -596,7 +569,7 @@ impl<'a> SemanticModel<'a> { &mut self, binding_id: BindingId, range: TextRange, - context: ReferenceContext, + context: ExecutionContext, ) { let reference_id = self.references.push(ScopeId::global(), range, context); self.bindings[binding_id].references.push(reference_id); diff --git a/crates/ruff_python_semantic/src/reference.rs b/crates/ruff_python_semantic/src/reference.rs index 33d6de108fcca3..e30d6bb9bac881 100644 --- a/crates/ruff_python_semantic/src/reference.rs +++ b/crates/ruff_python_semantic/src/reference.rs @@ -2,6 +2,7 @@ use ruff_text_size::TextRange; use ruff_index::{newtype_index, IndexVec}; +use crate::context::ExecutionContext; use crate::scope::ScopeId; #[derive(Debug, Clone)] @@ -11,7 +12,7 @@ pub struct Reference { /// The range of the reference in the source code. range: TextRange, /// The context in which the reference occurs. - context: ReferenceContext, + context: ExecutionContext, } impl Reference { @@ -23,19 +24,11 @@ impl Reference { self.range } - pub const fn context(&self) -> &ReferenceContext { + pub const fn context(&self) -> &ExecutionContext { &self.context } } -#[derive(Debug, Clone, is_macro::Is)] -pub enum ReferenceContext { - /// The reference occurs in a runtime context. - Runtime, - /// The reference occurs in a typing-only context. - Typing, -} - /// Id uniquely identifying a read reference in a program. #[newtype_index] pub struct ReferenceId; @@ -50,7 +43,7 @@ impl References { &mut self, scope_id: ScopeId, range: TextRange, - context: ReferenceContext, + context: ExecutionContext, ) -> ReferenceId { self.0.push(Reference { scope_id,