Rename some methods on SemanticModel (#4990)

This commit is contained in:
Charlie Marsh 2023-06-09 15:36:59 -04:00 committed by GitHub
parent 5c502a3320
commit e86f12a1ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 40 additions and 42 deletions

View file

@ -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(),

View file

@ -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()
}) })

View file

@ -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()
}) })

View file

@ -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()
}) })

View file

@ -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())

View file

@ -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,
} }