mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-17 09:00:26 +00:00
Use NodeId
for Binding
source (#4234)
This commit is contained in:
parent
c1f0661225
commit
a9fc648faf
7 changed files with 97 additions and 96 deletions
|
@ -1,47 +1,41 @@
|
|||
use std::cmp::Ordering;
|
||||
|
||||
use ruff_python_ast::types::RefEquality;
|
||||
use rustpython_parser::ast::ExcepthandlerKind::ExceptHandler;
|
||||
use rustpython_parser::ast::{Stmt, StmtKind};
|
||||
|
||||
use crate::node::Nodes;
|
||||
use crate::node::{NodeId, Nodes};
|
||||
|
||||
/// Return the common ancestor of `left` and `right` below `stop`, or `None`.
|
||||
fn common_ancestor<'a>(
|
||||
left: &'a Stmt,
|
||||
right: &'a Stmt,
|
||||
stop: Option<&'a Stmt>,
|
||||
node_tree: &Nodes<'a>,
|
||||
) -> Option<&'a Stmt> {
|
||||
if stop.map_or(false, |stop| {
|
||||
RefEquality(left) == RefEquality(stop) || RefEquality(right) == RefEquality(stop)
|
||||
}) {
|
||||
fn common_ancestor(
|
||||
left: NodeId,
|
||||
right: NodeId,
|
||||
stop: Option<NodeId>,
|
||||
node_tree: &Nodes,
|
||||
) -> Option<NodeId> {
|
||||
if stop.map_or(false, |stop| left == stop || right == stop) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if RefEquality(left) == RefEquality(right) {
|
||||
if left == right {
|
||||
return Some(left);
|
||||
}
|
||||
|
||||
let left_id = node_tree.node_id(left)?;
|
||||
let right_id = node_tree.node_id(right)?;
|
||||
|
||||
let left_depth = node_tree.depth(left_id);
|
||||
let right_depth = node_tree.depth(right_id);
|
||||
let left_depth = node_tree.depth(left);
|
||||
let right_depth = node_tree.depth(right);
|
||||
|
||||
match left_depth.cmp(&right_depth) {
|
||||
Ordering::Less => {
|
||||
let right_id = node_tree.parent_id(right_id)?;
|
||||
common_ancestor(left, node_tree[right_id], stop, node_tree)
|
||||
let right = node_tree.parent_id(right)?;
|
||||
common_ancestor(left, right, stop, node_tree)
|
||||
}
|
||||
Ordering::Equal => {
|
||||
let left_id = node_tree.parent_id(left_id)?;
|
||||
let right_id = node_tree.parent_id(right_id)?;
|
||||
common_ancestor(node_tree[left_id], node_tree[right_id], stop, node_tree)
|
||||
let left = node_tree.parent_id(left)?;
|
||||
let right = node_tree.parent_id(right)?;
|
||||
common_ancestor(left, right, stop, node_tree)
|
||||
}
|
||||
Ordering::Greater => {
|
||||
let left_id = node_tree.parent_id(left_id)?;
|
||||
common_ancestor(node_tree[left_id], right, stop, node_tree)
|
||||
let left = node_tree.parent_id(left)?;
|
||||
common_ancestor(left, right, stop, node_tree)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,21 +72,23 @@ fn alternatives(stmt: &Stmt) -> Vec<Vec<&Stmt>> {
|
|||
|
||||
/// Return `true` if `stmt` is a descendent of any of the nodes in `ancestors`.
|
||||
fn descendant_of<'a>(
|
||||
stmt: &'a Stmt,
|
||||
stmt: NodeId,
|
||||
ancestors: &[&'a Stmt],
|
||||
stop: &'a Stmt,
|
||||
stop: NodeId,
|
||||
node_tree: &Nodes<'a>,
|
||||
) -> bool {
|
||||
ancestors
|
||||
.iter()
|
||||
.any(|ancestor| common_ancestor(stmt, ancestor, Some(stop), node_tree).is_some())
|
||||
ancestors.iter().any(|ancestor| {
|
||||
node_tree.node_id(ancestor).map_or(false, |ancestor| {
|
||||
common_ancestor(stmt, ancestor, Some(stop), node_tree).is_some()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Return `true` if `left` and `right` are on different branches of an `if` or
|
||||
/// `try` statement.
|
||||
pub fn different_forks<'a>(left: &'a Stmt, right: &'a Stmt, node_tree: &Nodes<'a>) -> bool {
|
||||
pub fn different_forks(left: NodeId, right: NodeId, node_tree: &Nodes) -> bool {
|
||||
if let Some(ancestor) = common_ancestor(left, right, None, node_tree) {
|
||||
for items in alternatives(ancestor) {
|
||||
for items in alternatives(node_tree[ancestor]) {
|
||||
let l = descendant_of(left, &items, ancestor, node_tree);
|
||||
let r = descendant_of(right, &items, ancestor, node_tree);
|
||||
if l ^ r {
|
||||
|
|
|
@ -3,8 +3,8 @@ use std::ops::{Deref, Index, IndexMut};
|
|||
|
||||
use bitflags::bitflags;
|
||||
use ruff_text_size::TextRange;
|
||||
use rustpython_parser::ast::Stmt;
|
||||
|
||||
use crate::node::NodeId;
|
||||
use crate::scope::ScopeId;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -14,7 +14,7 @@ pub struct Binding<'a> {
|
|||
/// The context in which the binding was created.
|
||||
pub context: ExecutionContext,
|
||||
/// The statement in which the [`Binding`] was defined.
|
||||
pub source: Option<&'a Stmt>,
|
||||
pub source: Option<NodeId>,
|
||||
/// Tuple of (scope index, range) indicating the scope and range at which
|
||||
/// the binding was last used in a runtime context.
|
||||
pub runtime_usage: Option<(ScopeId, TextRange)>,
|
||||
|
|
|
@ -252,7 +252,9 @@ impl<'a> Context<'a> {
|
|||
.take(scope_index)
|
||||
.all(|scope| scope.get(name).is_none())
|
||||
{
|
||||
return Some((binding.source.unwrap(), format!("{name}.{member}")));
|
||||
if let Some(source) = binding.source {
|
||||
return Some((self.stmts[source], format!("{name}.{member}")));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -268,7 +270,9 @@ impl<'a> Context<'a> {
|
|||
.take(scope_index)
|
||||
.all(|scope| scope.get(name).is_none())
|
||||
{
|
||||
return Some((binding.source.unwrap(), (*name).to_string()));
|
||||
if let Some(source) = binding.source {
|
||||
return Some((self.stmts[source], (*name).to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -283,7 +287,9 @@ impl<'a> Context<'a> {
|
|||
.take(scope_index)
|
||||
.all(|scope| scope.get(name).is_none())
|
||||
{
|
||||
return Some((binding.source.unwrap(), format!("{name}.{member}")));
|
||||
if let Some(source) = binding.source {
|
||||
return Some((self.stmts[source], format!("{name}.{member}")));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue