mirror of https://github.com/astral-sh/ruff
Rename all of these structs
This commit is contained in:
parent
ac25bd9596
commit
d8c9500b37
|
|
@ -325,7 +325,7 @@ where
|
|||
self.add_binding(
|
||||
name,
|
||||
alias.identifier(),
|
||||
BindingKind::SubmoduleImport(SubmoduleImport { call_path }),
|
||||
BindingKind::SubmoduleImport(SubmoduleImport { path: call_path }),
|
||||
BindingFlags::EXTERNAL,
|
||||
);
|
||||
} else {
|
||||
|
|
@ -346,7 +346,7 @@ where
|
|||
self.add_binding(
|
||||
name,
|
||||
alias.identifier(),
|
||||
BindingKind::Import(Import { call_path }),
|
||||
BindingKind::Import(Import { path: call_path }),
|
||||
flags,
|
||||
);
|
||||
}
|
||||
|
|
@ -399,7 +399,7 @@ where
|
|||
self.add_binding(
|
||||
name,
|
||||
alias.identifier(),
|
||||
BindingKind::FromImport(FromImport { call_path }),
|
||||
BindingKind::FromImport(FromImport { path: call_path }),
|
||||
flags,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ impl Renamer {
|
|||
}
|
||||
BindingKind::SubmoduleImport(import) => {
|
||||
// Ex) Rename `import pandas.core` to `import pandas as pd`.
|
||||
let module_name = import.call_path.first().unwrap();
|
||||
let module_name = import.path.first().unwrap();
|
||||
Some(Edit::range_replacement(
|
||||
format!("{module_name} as {target}"),
|
||||
binding.range,
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ pub(crate) fn unaliased_collections_abc_set_import(
|
|||
let BindingKind::FromImport(import) = &binding.kind else {
|
||||
return None;
|
||||
};
|
||||
if !matches!(import.call_path(), ["collections", "abc", "Set"]) {
|
||||
if !matches!(import.path(), ["collections", "abc", "Set"]) {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ pub(super) fn test_expression(expr: &Expr, semantic: &SemanticModel) -> Resoluti
|
|||
| BindingKind::LoopVar
|
||||
| BindingKind::Global
|
||||
| BindingKind::Nonlocal(_) => Resolution::RelevantLocal,
|
||||
BindingKind::Import(import) if matches!(import.call_path(), ["pandas"]) => {
|
||||
BindingKind::Import(import) if matches!(import.path(), ["pandas"]) => {
|
||||
Resolution::PandasModule
|
||||
}
|
||||
_ => Resolution::IrrelevantBinding,
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ pub(crate) fn inplace_argument(
|
|||
.and_then(|module| checker.semantic().find_binding(module))
|
||||
.map_or(false, |binding| {
|
||||
if let BindingKind::Import(import) = &binding.kind {
|
||||
matches!(import.call_path(), ["pandas"])
|
||||
matches!(import.path(), ["pandas"])
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,40 @@
|
|||
use smallvec::{smallvec, SmallVec};
|
||||
use std::ops::{Deref, Index};
|
||||
|
||||
use crate::{nodes, Expr};
|
||||
|
||||
/// A representation of a qualified name, like `typing.List`.
|
||||
/// A generic path to a dot-separated symbol.
|
||||
///
|
||||
/// For example:
|
||||
/// - Given `foo.bar.baz()`, the symbol path for the function call would be `["foo", "bar", "baz"]`.
|
||||
/// - Given `foo.bar.baz`, the symbol path for the attribute access would be `["foo", "bar", "baz"]`.
|
||||
/// - Given `import foo.bar.baz`, the symbol path for the import would be `["foo", "bar", "baz"]`.
|
||||
pub struct SymbolPath<'a>(&'a [&'a str]);
|
||||
|
||||
impl<'a> From<CallPath<'a>> for SymbolPath<'a> {
|
||||
fn from(path: CallPath<'a>) -> Self {
|
||||
Self(path.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
// impl Index<usize> for SymbolPath<'_> {
|
||||
// type Output = str;
|
||||
//
|
||||
// fn index(&self, index: usize) -> &Self::Output {
|
||||
// self.0[index]
|
||||
// }
|
||||
// }
|
||||
|
||||
impl<'a> Deref for SymbolPath<'a> {
|
||||
type Target = [&'a str];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// A representation of dot-separated path, like `foo.bar.baz`.
|
||||
/// The owned version of [`SymbolPath`].
|
||||
pub type CallPath<'a> = SmallVec<[&'a str; 8]>;
|
||||
|
||||
/// Convert an `Expr` to its [`CallPath`] segments (like `["typing", "List"]`).
|
||||
|
|
@ -137,15 +169,15 @@ pub fn collect_call_path(expr: &Expr) -> Option<CallPath> {
|
|||
|
||||
/// Convert an `Expr` to its call path (like `List`, or `typing.List`).
|
||||
pub fn compose_call_path(expr: &Expr) -> Option<String> {
|
||||
collect_call_path(expr).map(|call_path| format_call_path(&call_path))
|
||||
collect_call_path(expr).map(|call_path| format_call_path(SymbolPath::from(call_path)))
|
||||
}
|
||||
|
||||
/// Format a call path for display.
|
||||
pub fn format_call_path(call_path: &[&str]) -> String {
|
||||
pub fn format_call_path(call_path: SymbolPath) -> String {
|
||||
if call_path.first().map_or(false, |first| first.is_empty()) {
|
||||
// If the first segment is empty, the `CallPath` is that of a builtin.
|
||||
// Ex) `["", "bool"]` -> `"bool"`
|
||||
call_path[1..].join(".")
|
||||
call_path.iter().skip(1).join(".")
|
||||
} else if call_path
|
||||
.first()
|
||||
.map_or(false, |first| matches!(*first, "."))
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use std::borrow::Cow;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::ops::{Deref, DerefMut, Index, Range};
|
||||
use std::slice::SliceIndex;
|
||||
|
||||
use bitflags::bitflags;
|
||||
|
||||
use ruff_index::{newtype_index, IndexSlice, IndexVec};
|
||||
use ruff_python_ast::call_path::format_call_path;
|
||||
use ruff_python_ast::call_path::{format_call_path, CallPath};
|
||||
use ruff_python_ast::Ranged;
|
||||
use ruff_source_file::Locator;
|
||||
use ruff_text_size::TextRange;
|
||||
|
|
@ -118,44 +119,32 @@ impl<'a> Binding<'a> {
|
|||
// import foo.bar
|
||||
// import foo.baz
|
||||
// ```
|
||||
BindingKind::Import(Import {
|
||||
call_path: redefinition,
|
||||
}) => {
|
||||
if let BindingKind::SubmoduleImport(SubmoduleImport {
|
||||
call_path: definition,
|
||||
}) = &existing.kind
|
||||
BindingKind::Import(Import { path: redefinition }) => {
|
||||
if let BindingKind::SubmoduleImport(SubmoduleImport { path: definition }) =
|
||||
&existing.kind
|
||||
{
|
||||
return redefinition == definition;
|
||||
}
|
||||
}
|
||||
BindingKind::FromImport(FromImport {
|
||||
call_path: redefinition,
|
||||
}) => {
|
||||
if let BindingKind::SubmoduleImport(SubmoduleImport {
|
||||
call_path: definition,
|
||||
}) = &existing.kind
|
||||
BindingKind::FromImport(FromImport { path: redefinition }) => {
|
||||
if let BindingKind::SubmoduleImport(SubmoduleImport { path: definition }) =
|
||||
&existing.kind
|
||||
{
|
||||
return redefinition == definition;
|
||||
}
|
||||
}
|
||||
BindingKind::SubmoduleImport(SubmoduleImport {
|
||||
call_path: redefinition,
|
||||
}) => match &existing.kind {
|
||||
BindingKind::Import(Import {
|
||||
call_path: definition,
|
||||
})
|
||||
| BindingKind::SubmoduleImport(SubmoduleImport {
|
||||
call_path: definition,
|
||||
}) => {
|
||||
return redefinition == definition;
|
||||
BindingKind::SubmoduleImport(SubmoduleImport { path: redefinition }) => {
|
||||
match &existing.kind {
|
||||
BindingKind::Import(Import { path: definition })
|
||||
| BindingKind::SubmoduleImport(SubmoduleImport { path: definition }) => {
|
||||
return redefinition == definition;
|
||||
}
|
||||
BindingKind::FromImport(FromImport { path: definition }) => {
|
||||
return redefinition == definition;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
BindingKind::FromImport(FromImport {
|
||||
call_path: definition,
|
||||
}) => {
|
||||
return redefinition == definition;
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
// Deletions, annotations, `__future__` imports, and builtins are never considered
|
||||
// redefinitions.
|
||||
BindingKind::Deletion
|
||||
|
|
@ -338,7 +327,7 @@ pub struct Import<'a> {
|
|||
/// The full name of the module being imported.
|
||||
/// Ex) Given `import foo`, `qualified_name` would be "foo".
|
||||
/// Ex) Given `import foo as bar`, `qualified_name` would be "foo".
|
||||
pub call_path: Box<[&'a str]>,
|
||||
pub path: Box<[&'a str]>,
|
||||
}
|
||||
|
||||
/// A binding for a member imported from a module, keyed on the name to which the member is bound.
|
||||
|
|
@ -349,7 +338,7 @@ pub struct FromImport<'a> {
|
|||
/// The full name of the member being imported.
|
||||
/// Ex) Given `from foo import bar`, `qualified_name` would be "foo.bar".
|
||||
/// Ex) Given `from foo import bar as baz`, `qualified_name` would be "foo.bar".
|
||||
pub call_path: Box<[&'a str]>,
|
||||
pub path: Box<[&'a str]>,
|
||||
}
|
||||
|
||||
/// A binding for a submodule imported from a module, keyed on the name of the parent module.
|
||||
|
|
@ -358,7 +347,7 @@ pub struct FromImport<'a> {
|
|||
pub struct SubmoduleImport<'a> {
|
||||
/// The full name of the submodule being imported.
|
||||
/// Ex) Given `import foo.bar`, `qualified_name` would be "foo.bar".
|
||||
pub call_path: Box<[&'a str]>,
|
||||
pub path: Box<[&'a str]>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, is_macro::Is)]
|
||||
|
|
@ -515,13 +504,40 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
/// The path to the symbol imported by an import statement.
|
||||
///
|
||||
/// For example:
|
||||
/// - Given `import foo`, the import path would be `["foo"]`.
|
||||
/// - Given `import foo.bar`, the import path would be `["foo", "bar"]`.
|
||||
/// - Given `from foo import bar`, the import path would be `["foo", "bar"]`.
|
||||
/// - Given `from foo.bar import baz`, the import path would be `["foo", "bar", "baz]`.
|
||||
pub struct ImportPath<'a>(SymbolPath<'a>);
|
||||
|
||||
/// The path to the module imported by an import statement.
|
||||
///
|
||||
/// For example:
|
||||
/// - Given `import foo`, the module path would be `["foo"]`.
|
||||
/// - Given `import foo.bar`, the import path would be `["foo"]`.
|
||||
/// - Given `from foo import bar`, the module path would be `["foo"]`.
|
||||
/// - Given `from foo.bar import baz`, the import path would be `["foo", "bar"]`.
|
||||
pub struct ModulePath<'a>(SymbolPath<'a>);
|
||||
|
||||
/// The name of the member imported by an import statement.
|
||||
///
|
||||
/// For example:
|
||||
/// - Given `import foo`, the module path would be `"foo"`.
|
||||
/// - Given `import foo.bar`, the import path would be `"foo.bar"`.
|
||||
/// - Given `from foo import bar`, the module path would be `"bar"`.
|
||||
/// - Given `from foo.bar import baz`, the import path would be `"baz"`.
|
||||
pub struct MemberName<'a>(Cow<'a, str>);
|
||||
|
||||
/// A trait for imported symbols.
|
||||
pub trait Imported<'a> {
|
||||
/// Returns the call path to the imported symbol.
|
||||
fn call_path(&self) -> &[&str];
|
||||
/// Returns the qualified path to the imported symbol.
|
||||
fn path(&self) -> ImportPath<'a>;
|
||||
|
||||
/// Returns the module name of the imported symbol.
|
||||
fn module_name(&self) -> &[&str];
|
||||
fn module_name(&self) -> ModulePath<'a>;
|
||||
|
||||
/// Returns the member name of the imported symbol. For a straight import, this is equivalent
|
||||
/// to [`qualified_name`]; for a `from` import, this is the name of the imported symbol.
|
||||
|
|
@ -529,19 +545,19 @@ pub trait Imported<'a> {
|
|||
|
||||
/// Returns the fully-qualified name of the imported symbol.
|
||||
fn qualified_name(&self) -> String {
|
||||
format_call_path(self.call_path())
|
||||
format_call_path(self.path().0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Imported<'a> for Import<'a> {
|
||||
/// For example, given `import foo`, returns `["foo"]`.
|
||||
fn call_path(&self) -> &[&str] {
|
||||
self.call_path.as_ref()
|
||||
fn path(&self) -> ImportPath<'a> {
|
||||
ImportPath(&self.path)
|
||||
}
|
||||
|
||||
/// For example, given `import foo`, returns `["foo"]`.
|
||||
fn module_name(&self) -> &[&str] {
|
||||
&self.call_path[..1]
|
||||
fn module_name(&self) -> ModulePath<'a> {
|
||||
ModulePath(&self.path[..1])
|
||||
}
|
||||
|
||||
/// For example, given `import foo`, returns `"foo"`.
|
||||
|
|
@ -552,13 +568,13 @@ impl<'a> Imported<'a> for Import<'a> {
|
|||
|
||||
impl<'a> Imported<'a> for SubmoduleImport<'a> {
|
||||
/// For example, given `import foo.bar`, returns `["foo", "bar"]`.
|
||||
fn call_path(&self) -> &[&str] {
|
||||
self.call_path.as_ref()
|
||||
fn path(&self) -> ImportPath<'a> {
|
||||
ImportPath(&self.path)
|
||||
}
|
||||
|
||||
/// For example, given `import foo.bar`, returns `["foo"]`.
|
||||
fn module_name(&self) -> &[&str] {
|
||||
&self.call_path[..1]
|
||||
fn module_name(&self) -> ModulePath<'a> {
|
||||
ModulePath(&self.path[..1])
|
||||
}
|
||||
|
||||
/// For example, given `import foo.bar`, returns `"foo.bar"`.
|
||||
|
|
@ -569,18 +585,18 @@ impl<'a> Imported<'a> for SubmoduleImport<'a> {
|
|||
|
||||
impl<'a> Imported<'a> for FromImport<'a> {
|
||||
/// For example, given `from foo import bar`, returns `["foo", "bar"]`.
|
||||
fn call_path(&self) -> &[&str] {
|
||||
self.call_path.as_ref()
|
||||
fn path(&self) -> ImportPath<'a> {
|
||||
ImportPath(&self.path)
|
||||
}
|
||||
|
||||
/// For example, given `from foo import bar`, returns `["foo"]`.
|
||||
fn module_name(&self) -> &[&str] {
|
||||
&self.call_path[..self.call_path.len() - 1]
|
||||
fn module_name(&self) -> ModulePath<'a> {
|
||||
ModulePath(&self.path[..self.path.len() - 1])
|
||||
}
|
||||
|
||||
/// For example, given `from foo import bar`, returns `"bar"`.
|
||||
fn member_name(&self) -> Cow<'a, str> {
|
||||
Cow::Borrowed(self.call_path[self.call_path.len() - 1])
|
||||
Cow::Borrowed(self.path[self.path.len() - 1])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -593,15 +609,15 @@ pub enum AnyImport<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Imported<'a> for AnyImport<'a> {
|
||||
fn call_path(&self) -> &[&str] {
|
||||
fn path(&self) -> ImportPath<'a> {
|
||||
match self {
|
||||
Self::Import(import) => import.call_path(),
|
||||
Self::SubmoduleImport(import) => import.call_path(),
|
||||
Self::FromImport(import) => import.call_path(),
|
||||
Self::Import(import) => import.path(),
|
||||
Self::SubmoduleImport(import) => import.path(),
|
||||
Self::FromImport(import) => import.path(),
|
||||
}
|
||||
}
|
||||
|
||||
fn module_name(&self) -> &[&str] {
|
||||
fn module_name(&self) -> ModulePath<'a> {
|
||||
match self {
|
||||
Self::Import(import) => import.module_name(),
|
||||
Self::SubmoduleImport(import) => import.module_name(),
|
||||
|
|
|
|||
|
|
@ -585,7 +585,7 @@ impl<'a> SemanticModel<'a> {
|
|||
// print(pa.csv.read_csv("test.csv"))
|
||||
// ```
|
||||
let import = self.bindings[binding_id].as_any_import()?;
|
||||
let call_path = import.call_path();
|
||||
let call_path = import.path();
|
||||
let segment = call_path.last()?;
|
||||
if *segment == symbol {
|
||||
return None;
|
||||
|
|
@ -630,13 +630,13 @@ impl<'a> SemanticModel<'a> {
|
|||
};
|
||||
|
||||
match &binding.kind {
|
||||
BindingKind::Import(Import { call_path }) => {
|
||||
BindingKind::Import(Import { path: call_path }) => {
|
||||
let value_path = collect_call_path(value)?;
|
||||
let (_, tail) = value_path.split_first()?;
|
||||
let resolved: CallPath = call_path.iter().chain(tail.iter()).copied().collect();
|
||||
Some(resolved)
|
||||
}
|
||||
BindingKind::SubmoduleImport(SubmoduleImport { call_path }) => {
|
||||
BindingKind::SubmoduleImport(SubmoduleImport { path: call_path }) => {
|
||||
let value_path = collect_call_path(value)?;
|
||||
let (_, tail) = value_path.split_first()?;
|
||||
let resolved: CallPath = call_path
|
||||
|
|
@ -647,10 +647,9 @@ impl<'a> SemanticModel<'a> {
|
|||
.collect();
|
||||
Some(resolved)
|
||||
}
|
||||
BindingKind::FromImport(FromImport { call_path }) => {
|
||||
BindingKind::FromImport(FromImport { path: call_path }) => {
|
||||
let value_path = collect_call_path(value)?;
|
||||
let (_, tail) = value_path.split_first()?;
|
||||
|
||||
let resolved: CallPath =
|
||||
if call_path.first().map_or(false, |segment| *segment == ".") {
|
||||
from_relative_import(self.module_path?, call_path, tail)?
|
||||
|
|
@ -690,7 +689,7 @@ impl<'a> SemanticModel<'a> {
|
|||
// Ex) Given `module="sys"` and `object="exit"`:
|
||||
// `import sys` -> `sys.exit`
|
||||
// `import sys as sys2` -> `sys2.exit`
|
||||
BindingKind::Import(Import { call_path }) => {
|
||||
BindingKind::Import(Import { path: call_path }) => {
|
||||
if call_path.as_ref() == module_path.as_slice() {
|
||||
if let Some(source) = binding.source {
|
||||
// Verify that `sys` isn't bound in an inner scope.
|
||||
|
|
@ -711,7 +710,7 @@ impl<'a> SemanticModel<'a> {
|
|||
// Ex) Given `module="os.path"` and `object="join"`:
|
||||
// `from os.path import join` -> `join`
|
||||
// `from os.path import join as join2` -> `join2`
|
||||
BindingKind::FromImport(FromImport { call_path }) => {
|
||||
BindingKind::FromImport(FromImport { path: call_path }) => {
|
||||
if let Some((target_member, target_module)) = call_path.split_last() {
|
||||
if target_module == module_path.as_slice() && target_member == &member {
|
||||
if let Some(source) = binding.source {
|
||||
|
|
|
|||
Loading…
Reference in New Issue