mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-09 21:28:21 +00:00
Rename some methods on SemanticModel
(#4990)
This commit is contained in:
parent
5c502a3320
commit
e86f12a1ec
6 changed files with 40 additions and 42 deletions
|
@ -29,7 +29,7 @@ use ruff_python_semantic::binding::{
|
||||||
use ruff_python_semantic::context::ExecutionContext;
|
use ruff_python_semantic::context::ExecutionContext;
|
||||||
use ruff_python_semantic::definition::{ContextualizedDefinition, Module, ModuleKind};
|
use ruff_python_semantic::definition::{ContextualizedDefinition, Module, ModuleKind};
|
||||||
use ruff_python_semantic::globals::Globals;
|
use ruff_python_semantic::globals::Globals;
|
||||||
use ruff_python_semantic::model::{ResolvedReference, SemanticModel, SemanticModelFlags};
|
use ruff_python_semantic::model::{ResolvedRead, SemanticModel, SemanticModelFlags};
|
||||||
use ruff_python_semantic::scope::{Scope, ScopeId, ScopeKind};
|
use ruff_python_semantic::scope::{Scope, ScopeId, ScopeKind};
|
||||||
use ruff_python_stdlib::builtins::{BUILTINS, MAGIC_GLOBALS};
|
use ruff_python_stdlib::builtins::{BUILTINS, MAGIC_GLOBALS};
|
||||||
use ruff_python_stdlib::path::is_python_stub_file;
|
use ruff_python_stdlib::path::is_python_stub_file;
|
||||||
|
@ -4506,11 +4506,11 @@ impl<'a> Checker<'a> {
|
||||||
let Expr::Name(ast::ExprName { id, .. } )= expr else {
|
let Expr::Name(ast::ExprName { id, .. } )= expr else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
match self.semantic_model.resolve_reference(id, expr.range()) {
|
match self.semantic_model.resolve_read(id, expr.range()) {
|
||||||
ResolvedReference::Resolved(..) | ResolvedReference::ImplicitGlobal => {
|
ResolvedRead::Resolved(..) | ResolvedRead::ImplicitGlobal => {
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
}
|
}
|
||||||
ResolvedReference::StarImport => {
|
ResolvedRead::StarImport => {
|
||||||
// F405
|
// F405
|
||||||
if self.enabled(Rule::UndefinedLocalWithImportStarUsage) {
|
if self.enabled(Rule::UndefinedLocalWithImportStarUsage) {
|
||||||
let sources: Vec<String> = self
|
let sources: Vec<String> = self
|
||||||
|
@ -4533,7 +4533,7 @@ impl<'a> Checker<'a> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ResolvedReference::NotFound => {
|
ResolvedRead::NotFound => {
|
||||||
// F821
|
// F821
|
||||||
if self.enabled(Rule::UndefinedName) {
|
if self.enabled(Rule::UndefinedName) {
|
||||||
// Allow __path__.
|
// Allow __path__.
|
||||||
|
@ -5040,13 +5040,12 @@ impl<'a> Checker<'a> {
|
||||||
// the bindings are in different scopes.
|
// the bindings are in different scopes.
|
||||||
if self.enabled(Rule::RedefinedWhileUnused) {
|
if self.enabled(Rule::RedefinedWhileUnused) {
|
||||||
for (name, binding_id) in scope.bindings() {
|
for (name, binding_id) in scope.bindings() {
|
||||||
if let Some(shadowed) = self.semantic_model.shadowed_binding(binding_id) {
|
if let Some(shadowed_id) = self.semantic_model.shadowed_binding(binding_id) {
|
||||||
|
let shadowed = &self.semantic_model.bindings[shadowed_id];
|
||||||
if shadowed.is_used() {
|
if shadowed.is_used() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let binding = &self.semantic_model.bindings[binding_id];
|
|
||||||
|
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
let line = self.locator.compute_line_index(
|
let line = self.locator.compute_line_index(
|
||||||
shadowed
|
shadowed
|
||||||
|
@ -5054,6 +5053,7 @@ impl<'a> Checker<'a> {
|
||||||
.start(),
|
.start(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let binding = &self.semantic_model.bindings[binding_id];
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
pyflakes::rules::RedefinedWhileUnused {
|
pyflakes::rules::RedefinedWhileUnused {
|
||||||
name: (*name).to_string(),
|
name: (*name).to_string(),
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
|
use rustpython_parser::ast;
|
||||||
|
|
||||||
use ruff_python_ast::call_path::from_qualified_name;
|
use ruff_python_ast::call_path::from_qualified_name;
|
||||||
use ruff_python_ast::helpers::map_callable;
|
use ruff_python_ast::helpers::map_callable;
|
||||||
use ruff_python_semantic::binding::{Binding, BindingKind};
|
use ruff_python_semantic::binding::{Binding, BindingKind};
|
||||||
use ruff_python_semantic::model::SemanticModel;
|
use ruff_python_semantic::model::SemanticModel;
|
||||||
use ruff_python_semantic::scope::ScopeKind;
|
use ruff_python_semantic::scope::ScopeKind;
|
||||||
use rustpython_parser::ast;
|
|
||||||
|
|
||||||
pub(crate) fn is_valid_runtime_import(semantic_model: &SemanticModel, binding: &Binding) -> bool {
|
pub(crate) fn is_valid_runtime_import(semantic_model: &SemanticModel, binding: &Binding) -> bool {
|
||||||
if matches!(
|
if matches!(
|
||||||
|
@ -15,8 +16,7 @@ pub(crate) fn is_valid_runtime_import(semantic_model: &SemanticModel, binding: &
|
||||||
binding.context.is_runtime()
|
binding.context.is_runtime()
|
||||||
&& binding.references().any(|reference_id| {
|
&& binding.references().any(|reference_id| {
|
||||||
semantic_model
|
semantic_model
|
||||||
.references
|
.reference(reference_id)
|
||||||
.resolve(reference_id)
|
|
||||||
.context()
|
.context()
|
||||||
.is_runtime()
|
.is_runtime()
|
||||||
})
|
})
|
||||||
|
|
|
@ -89,8 +89,7 @@ pub(crate) fn runtime_import_in_type_checking_block(
|
||||||
&& binding.references().any(|reference_id| {
|
&& binding.references().any(|reference_id| {
|
||||||
checker
|
checker
|
||||||
.semantic_model()
|
.semantic_model()
|
||||||
.references
|
.reference(reference_id)
|
||||||
.resolve(reference_id)
|
|
||||||
.context()
|
.context()
|
||||||
.is_runtime()
|
.is_runtime()
|
||||||
})
|
})
|
||||||
|
@ -204,8 +203,7 @@ fn fix_imports(checker: &Checker, stmt_id: NodeId, imports: &[Import]) -> Result
|
||||||
.map(|Import { reference_id, .. }| {
|
.map(|Import { reference_id, .. }| {
|
||||||
checker
|
checker
|
||||||
.semantic_model()
|
.semantic_model()
|
||||||
.references
|
.reference(*reference_id)
|
||||||
.resolve(*reference_id)
|
|
||||||
.range()
|
.range()
|
||||||
.start()
|
.start()
|
||||||
})
|
})
|
||||||
|
|
|
@ -234,8 +234,7 @@ pub(crate) fn typing_only_runtime_import(
|
||||||
&& binding.references().all(|reference_id| {
|
&& binding.references().all(|reference_id| {
|
||||||
checker
|
checker
|
||||||
.semantic_model()
|
.semantic_model()
|
||||||
.references
|
.reference(reference_id)
|
||||||
.resolve(reference_id)
|
|
||||||
.context()
|
.context()
|
||||||
.is_typing()
|
.is_typing()
|
||||||
})
|
})
|
||||||
|
@ -430,8 +429,7 @@ fn fix_imports(checker: &Checker, stmt_id: NodeId, imports: &[Import]) -> Result
|
||||||
.map(|Import { reference_id, .. }| {
|
.map(|Import { reference_id, .. }| {
|
||||||
checker
|
checker
|
||||||
.semantic_model()
|
.semantic_model()
|
||||||
.references
|
.reference(*reference_id)
|
||||||
.resolve(*reference_id)
|
|
||||||
.range()
|
.range()
|
||||||
.start()
|
.start()
|
||||||
})
|
})
|
||||||
|
|
|
@ -72,7 +72,7 @@ pub(crate) fn undefined_local(checker: &mut Checker, name: &str) {
|
||||||
{
|
{
|
||||||
// And has already been accessed in the current scope...
|
// And has already been accessed in the current scope...
|
||||||
if let Some(range) = binding.references().find_map(|reference_id| {
|
if let Some(range) = binding.references().find_map(|reference_id| {
|
||||||
let reference = checker.semantic_model().references.resolve(reference_id);
|
let reference = checker.semantic_model().reference(reference_id);
|
||||||
if checker
|
if checker
|
||||||
.semantic_model()
|
.semantic_model()
|
||||||
.is_current_scope(reference.scope_id())
|
.is_current_scope(reference.scope_id())
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::context::ExecutionContext;
|
||||||
use crate::definition::{Definition, DefinitionId, Definitions, Member, Module};
|
use crate::definition::{Definition, DefinitionId, Definitions, Member, Module};
|
||||||
use crate::globals::{Globals, GlobalsArena};
|
use crate::globals::{Globals, GlobalsArena};
|
||||||
use crate::node::{NodeId, Nodes};
|
use crate::node::{NodeId, Nodes};
|
||||||
use crate::reference::References;
|
use crate::reference::{Reference, ReferenceId, References};
|
||||||
use crate::scope::{Scope, ScopeId, ScopeKind, Scopes};
|
use crate::scope::{Scope, ScopeId, ScopeKind, Scopes};
|
||||||
|
|
||||||
/// A semantic model for a Python module, to enable querying the module's semantic information.
|
/// A semantic model for a Python module, to enable querying the module's semantic information.
|
||||||
|
@ -43,7 +43,7 @@ pub struct SemanticModel<'a> {
|
||||||
// A stack of all bindings created in any scope, at any point in execution.
|
// A stack of all bindings created in any scope, at any point in execution.
|
||||||
pub bindings: Bindings<'a>,
|
pub bindings: Bindings<'a>,
|
||||||
// Stack of all references created in any scope, at any point in execution.
|
// Stack of all references created in any scope, at any point in execution.
|
||||||
pub references: References,
|
references: References,
|
||||||
// Arena of global bindings.
|
// Arena of global bindings.
|
||||||
globals: GlobalsArena<'a>,
|
globals: GlobalsArena<'a>,
|
||||||
// Map from binding index to indexes of bindings that shadow it in other scopes.
|
// Map from binding index to indexes of bindings that shadow it in other scopes.
|
||||||
|
@ -152,14 +152,11 @@ impl<'a> SemanticModel<'a> {
|
||||||
.map(|binding_id| &self.bindings[binding_id])
|
.map(|binding_id| &self.bindings[binding_id])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the [`Binding`] that the given [`BindingId`] shadows, if any.
|
/// Return the [`BindingId`] that the given [`BindingId`] shadows, if any.
|
||||||
///
|
///
|
||||||
/// Note that this will only return bindings that are shadowed by a binding in a parent scope.
|
/// Note that this will only return bindings that are shadowed by a binding in a parent scope.
|
||||||
pub fn shadowed_binding(&self, binding_id: BindingId) -> Option<&Binding> {
|
pub fn shadowed_binding(&self, binding_id: BindingId) -> Option<BindingId> {
|
||||||
self.shadowed_bindings
|
self.shadowed_bindings.get(&binding_id).copied()
|
||||||
.get(&binding_id)
|
|
||||||
.copied()
|
|
||||||
.map(|id| &self.bindings[id])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return `true` if `member` is bound as a builtin.
|
/// Return `true` if `member` is bound as a builtin.
|
||||||
|
@ -174,8 +171,8 @@ impl<'a> SemanticModel<'a> {
|
||||||
.map_or(true, |binding| binding.kind.is_builtin())
|
.map_or(true, |binding| binding.kind.is_builtin())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve a reference to the given symbol.
|
/// Resolve a read reference to `symbol` at `range`.
|
||||||
pub fn resolve_reference(&mut self, symbol: &str, range: TextRange) -> ResolvedReference {
|
pub fn resolve_read(&mut self, symbol: &str, range: TextRange) -> ResolvedRead {
|
||||||
// PEP 563 indicates that if a forward reference can be resolved in the module scope, we
|
// PEP 563 indicates that if a forward reference can be resolved in the module scope, we
|
||||||
// should prefer it over local resolutions.
|
// should prefer it over local resolutions.
|
||||||
if self.in_forward_reference() {
|
if self.in_forward_reference() {
|
||||||
|
@ -193,7 +190,7 @@ impl<'a> SemanticModel<'a> {
|
||||||
self.bindings[binding_id].references.push(reference_id);
|
self.bindings[binding_id].references.push(reference_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResolvedReference::Resolved(binding_id);
|
return ResolvedRead::Resolved(binding_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +207,7 @@ impl<'a> SemanticModel<'a> {
|
||||||
// print(__class__)
|
// print(__class__)
|
||||||
// ```
|
// ```
|
||||||
if seen_function && matches!(symbol, "__class__") {
|
if seen_function && matches!(symbol, "__class__") {
|
||||||
return ResolvedReference::ImplicitGlobal;
|
return ResolvedRead::ImplicitGlobal;
|
||||||
}
|
}
|
||||||
if index > 0 {
|
if index > 0 {
|
||||||
continue;
|
continue;
|
||||||
|
@ -243,7 +240,7 @@ impl<'a> SemanticModel<'a> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResolvedReference::Resolved(binding_id);
|
return ResolvedRead::Resolved(binding_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow usages of `__module__` and `__qualname__` within class scopes, e.g.:
|
// Allow usages of `__module__` and `__qualname__` within class scopes, e.g.:
|
||||||
|
@ -263,7 +260,7 @@ impl<'a> SemanticModel<'a> {
|
||||||
// ```
|
// ```
|
||||||
if index == 0 && scope.kind.is_class() {
|
if index == 0 && scope.kind.is_class() {
|
||||||
if matches!(symbol, "__module__" | "__qualname__") {
|
if matches!(symbol, "__module__" | "__qualname__") {
|
||||||
return ResolvedReference::ImplicitGlobal;
|
return ResolvedRead::ImplicitGlobal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,9 +269,9 @@ impl<'a> SemanticModel<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if import_starred {
|
if import_starred {
|
||||||
ResolvedReference::StarImport
|
ResolvedRead::StarImport
|
||||||
} else {
|
} else {
|
||||||
ResolvedReference::NotFound
|
ResolvedRead::NotFound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -673,6 +670,11 @@ impl<'a> SemanticModel<'a> {
|
||||||
self.bindings[binding_id].references.push(reference_id);
|
self.bindings[binding_id].references.push(reference_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resolve a [`ReferenceId`].
|
||||||
|
pub fn reference(&self, reference_id: ReferenceId) -> &Reference {
|
||||||
|
self.references.resolve(reference_id)
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the [`ExecutionContext`] of the current scope.
|
/// Return the [`ExecutionContext`] of the current scope.
|
||||||
pub const fn execution_context(&self) -> ExecutionContext {
|
pub const fn execution_context(&self) -> ExecutionContext {
|
||||||
if self.in_type_checking_block()
|
if self.in_type_checking_block()
|
||||||
|
@ -1019,16 +1021,16 @@ pub struct Snapshot {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ResolvedReference {
|
pub enum ResolvedRead {
|
||||||
/// The reference is resolved to a specific binding.
|
/// The read reference is resolved to a specific binding.
|
||||||
Resolved(BindingId),
|
Resolved(BindingId),
|
||||||
/// The reference is resolved to a context-specific, implicit global (e.g., `__class__` within
|
/// The read reference is resolved to a context-specific, implicit global (e.g., `__class__`
|
||||||
/// a class scope).
|
/// within a class scope).
|
||||||
ImplicitGlobal,
|
ImplicitGlobal,
|
||||||
/// The reference is unresolved, but at least one of the containing scopes contains a star
|
/// The read reference is unresolved, but at least one of the containing scopes contains a star
|
||||||
/// import.
|
/// import.
|
||||||
StarImport,
|
StarImport,
|
||||||
/// The reference is definitively unresolved.
|
/// The read reference is definitively unresolved.
|
||||||
NotFound,
|
NotFound,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue