mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 05:14:52 +00:00
[ruff] Remove Locator
from Importer
It seems like we'd like to remove `Locator` since it's a bit awkward in how it works: https://github.com/astral-sh/ruff/pull/20439#discussion_r2354683797 It looked pretty easy to rip it out of the `Importer`, so that's one less thing using it.
This commit is contained in:
parent
b6a29592e7
commit
5816985ecd
6 changed files with 24 additions and 22 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -4234,6 +4234,7 @@ dependencies = [
|
||||||
"rayon",
|
"rayon",
|
||||||
"regex",
|
"regex",
|
||||||
"ruff_db",
|
"ruff_db",
|
||||||
|
"ruff_diagnostics",
|
||||||
"ruff_index",
|
"ruff_index",
|
||||||
"ruff_memory_usage",
|
"ruff_memory_usage",
|
||||||
"ruff_python_ast",
|
"ruff_python_ast",
|
||||||
|
|
|
@ -277,7 +277,7 @@ impl<'a> Checker<'a> {
|
||||||
locator,
|
locator,
|
||||||
stylist,
|
stylist,
|
||||||
indexer,
|
indexer,
|
||||||
importer: Importer::new(parsed, locator, stylist),
|
importer: Importer::new(parsed, locator.contents(), stylist),
|
||||||
semantic,
|
semantic,
|
||||||
visit: deferred::Visit::default(),
|
visit: deferred::Visit::default(),
|
||||||
analyze: deferred::Analyze::default(),
|
analyze: deferred::Analyze::default(),
|
||||||
|
|
|
@ -14,6 +14,7 @@ use unicode_normalization::UnicodeNormalization;
|
||||||
use ruff_python_ast::Stmt;
|
use ruff_python_ast::Stmt;
|
||||||
use ruff_python_ast::name::UnqualifiedName;
|
use ruff_python_ast::name::UnqualifiedName;
|
||||||
use ruff_python_codegen::Stylist;
|
use ruff_python_codegen::Stylist;
|
||||||
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
use crate::Locator;
|
use crate::Locator;
|
||||||
use crate::cst::matchers::match_statement;
|
use crate::cst::matchers::match_statement;
|
||||||
|
@ -127,10 +128,10 @@ pub(crate) fn remove_imports<'a>(
|
||||||
pub(crate) fn retain_imports(
|
pub(crate) fn retain_imports(
|
||||||
member_names: &[&str],
|
member_names: &[&str],
|
||||||
stmt: &Stmt,
|
stmt: &Stmt,
|
||||||
locator: &Locator,
|
contents: &str,
|
||||||
stylist: &Stylist,
|
stylist: &Stylist,
|
||||||
) -> Result<String> {
|
) -> Result<String> {
|
||||||
let module_text = locator.slice(stmt);
|
let module_text = &contents[stmt.range()];
|
||||||
let mut tree = match_statement(module_text)?;
|
let mut tree = match_statement(module_text)?;
|
||||||
|
|
||||||
let Statement::Simple(body) = &mut tree else {
|
let Statement::Simple(body) = &mut tree else {
|
||||||
|
|
|
@ -19,7 +19,6 @@ use ruff_python_semantic::{
|
||||||
use ruff_python_trivia::textwrap::indent;
|
use ruff_python_trivia::textwrap::indent;
|
||||||
use ruff_text_size::{Ranged, TextSize};
|
use ruff_text_size::{Ranged, TextSize};
|
||||||
|
|
||||||
use crate::Locator;
|
|
||||||
use crate::cst::matchers::{match_aliases, match_import_from, match_statement};
|
use crate::cst::matchers::{match_aliases, match_import_from, match_statement};
|
||||||
use crate::fix;
|
use crate::fix;
|
||||||
use crate::fix::codemods::CodegenStylist;
|
use crate::fix::codemods::CodegenStylist;
|
||||||
|
@ -29,8 +28,8 @@ pub(crate) struct Importer<'a> {
|
||||||
python_ast: &'a [Stmt],
|
python_ast: &'a [Stmt],
|
||||||
/// The tokens representing the Python AST.
|
/// The tokens representing the Python AST.
|
||||||
tokens: &'a Tokens,
|
tokens: &'a Tokens,
|
||||||
/// The [`Locator`] for the Python AST.
|
/// The source code text for `python_ast`.
|
||||||
locator: &'a Locator<'a>,
|
source: &'a str,
|
||||||
/// The [`Stylist`] for the Python AST.
|
/// The [`Stylist`] for the Python AST.
|
||||||
stylist: &'a Stylist<'a>,
|
stylist: &'a Stylist<'a>,
|
||||||
/// The list of visited, top-level runtime imports in the Python AST.
|
/// The list of visited, top-level runtime imports in the Python AST.
|
||||||
|
@ -42,13 +41,13 @@ pub(crate) struct Importer<'a> {
|
||||||
impl<'a> Importer<'a> {
|
impl<'a> Importer<'a> {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
parsed: &'a Parsed<ModModule>,
|
parsed: &'a Parsed<ModModule>,
|
||||||
locator: &'a Locator<'a>,
|
source: &'a str,
|
||||||
stylist: &'a Stylist<'a>,
|
stylist: &'a Stylist<'a>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
python_ast: parsed.suite(),
|
python_ast: parsed.suite(),
|
||||||
tokens: parsed.tokens(),
|
tokens: parsed.tokens(),
|
||||||
locator,
|
source,
|
||||||
stylist,
|
stylist,
|
||||||
runtime_imports: Vec::default(),
|
runtime_imports: Vec::default(),
|
||||||
type_checking_blocks: Vec::default(),
|
type_checking_blocks: Vec::default(),
|
||||||
|
@ -74,11 +73,10 @@ impl<'a> Importer<'a> {
|
||||||
let required_import = import.to_string();
|
let required_import = import.to_string();
|
||||||
if let Some(stmt) = self.preceding_import(at) {
|
if let Some(stmt) = self.preceding_import(at) {
|
||||||
// Insert after the last top-level import.
|
// Insert after the last top-level import.
|
||||||
Insertion::end_of_statement(stmt, self.locator, self.stylist)
|
Insertion::end_of_statement(stmt, self.source, self.stylist).into_edit(&required_import)
|
||||||
.into_edit(&required_import)
|
|
||||||
} else {
|
} else {
|
||||||
// Insert at the start of the file.
|
// Insert at the start of the file.
|
||||||
Insertion::start_of_file(self.python_ast, self.locator, self.stylist)
|
Insertion::start_of_file(self.python_ast, self.source, self.stylist)
|
||||||
.into_edit(&required_import)
|
.into_edit(&required_import)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,17 +95,17 @@ impl<'a> Importer<'a> {
|
||||||
let content = fix::codemods::retain_imports(
|
let content = fix::codemods::retain_imports(
|
||||||
&import.names,
|
&import.names,
|
||||||
import.statement,
|
import.statement,
|
||||||
self.locator,
|
self.source,
|
||||||
self.stylist,
|
self.stylist,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Add the import to the top-level.
|
// Add the import to the top-level.
|
||||||
let insertion = if let Some(stmt) = self.preceding_import(at) {
|
let insertion = if let Some(stmt) = self.preceding_import(at) {
|
||||||
// Insert after the last top-level import.
|
// Insert after the last top-level import.
|
||||||
Insertion::end_of_statement(stmt, self.locator, self.stylist)
|
Insertion::end_of_statement(stmt, self.source, self.stylist)
|
||||||
} else {
|
} else {
|
||||||
// Insert at the start of the file.
|
// Insert at the start of the file.
|
||||||
Insertion::start_of_file(self.python_ast, self.locator, self.stylist)
|
Insertion::start_of_file(self.python_ast, self.source, self.stylist)
|
||||||
};
|
};
|
||||||
let add_import_edit = insertion.into_edit(&content);
|
let add_import_edit = insertion.into_edit(&content);
|
||||||
|
|
||||||
|
@ -129,7 +127,7 @@ impl<'a> Importer<'a> {
|
||||||
let content = fix::codemods::retain_imports(
|
let content = fix::codemods::retain_imports(
|
||||||
&import.names,
|
&import.names,
|
||||||
import.statement,
|
import.statement,
|
||||||
self.locator,
|
self.source,
|
||||||
self.stylist,
|
self.stylist,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -153,7 +151,7 @@ impl<'a> Importer<'a> {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(Edit::range_replacement(
|
Some(Edit::range_replacement(
|
||||||
self.locator.slice(statement.range()).to_string(),
|
self.source[statement.range()].to_string(),
|
||||||
statement.range(),
|
statement.range(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -184,7 +182,7 @@ impl<'a> Importer<'a> {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(Edit::range_replacement(
|
Some(Edit::range_replacement(
|
||||||
self.locator.slice(type_checking.range()).to_string(),
|
self.source[type_checking.range()].to_string(),
|
||||||
type_checking.range(),
|
type_checking.range(),
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
@ -360,7 +358,7 @@ impl<'a> Importer<'a> {
|
||||||
// By adding this no-op edit, we force the `unused-imports` fix to conflict with the
|
// By adding this no-op edit, we force the `unused-imports` fix to conflict with the
|
||||||
// `sys-exit-alias` fix, and thus will avoid applying both fixes in the same pass.
|
// `sys-exit-alias` fix, and thus will avoid applying both fixes in the same pass.
|
||||||
let import_edit = Edit::range_replacement(
|
let import_edit = Edit::range_replacement(
|
||||||
self.locator.slice(imported_name.range()).to_string(),
|
self.source[imported_name.range()].to_string(),
|
||||||
imported_name.range(),
|
imported_name.range(),
|
||||||
);
|
);
|
||||||
Ok(Some((import_edit, imported_name.into_name())))
|
Ok(Some((import_edit, imported_name.into_name())))
|
||||||
|
@ -467,7 +465,7 @@ impl<'a> Importer<'a> {
|
||||||
|
|
||||||
/// Add the given member to an existing `Stmt::ImportFrom` statement.
|
/// Add the given member to an existing `Stmt::ImportFrom` statement.
|
||||||
fn add_member(&self, stmt: &Stmt, member: &str) -> Result<Edit> {
|
fn add_member(&self, stmt: &Stmt, member: &str) -> Result<Edit> {
|
||||||
let mut statement = match_statement(self.locator.slice(stmt))?;
|
let mut statement = match_statement(&self.source[stmt.range()])?;
|
||||||
let import_from = match_import_from(&mut statement)?;
|
let import_from = match_import_from(&mut statement)?;
|
||||||
let aliases = match_aliases(import_from)?;
|
let aliases = match_aliases(import_from)?;
|
||||||
aliases.push(cst::ImportAlias {
|
aliases.push(cst::ImportAlias {
|
||||||
|
@ -489,10 +487,10 @@ impl<'a> Importer<'a> {
|
||||||
fn add_type_checking_block(&self, content: &str, at: TextSize) -> Result<Edit> {
|
fn add_type_checking_block(&self, content: &str, at: TextSize) -> Result<Edit> {
|
||||||
let insertion = if let Some(stmt) = self.preceding_import(at) {
|
let insertion = if let Some(stmt) = self.preceding_import(at) {
|
||||||
// Insert after the last top-level import.
|
// Insert after the last top-level import.
|
||||||
Insertion::end_of_statement(stmt, self.locator, self.stylist)
|
Insertion::end_of_statement(stmt, self.source, self.stylist)
|
||||||
} else {
|
} else {
|
||||||
// Insert at the start of the file.
|
// Insert at the start of the file.
|
||||||
Insertion::start_of_file(self.python_ast, self.locator, self.stylist)
|
Insertion::start_of_file(self.python_ast, self.source, self.stylist)
|
||||||
};
|
};
|
||||||
if insertion.is_inline() {
|
if insertion.is_inline() {
|
||||||
Err(anyhow::anyhow!(
|
Err(anyhow::anyhow!(
|
||||||
|
|
|
@ -125,7 +125,8 @@ fn add_required_import(
|
||||||
TextRange::default(),
|
TextRange::default(),
|
||||||
);
|
);
|
||||||
diagnostic.set_fix(Fix::safe_edit(
|
diagnostic.set_fix(Fix::safe_edit(
|
||||||
Importer::new(parsed, locator, stylist).add_import(required_import, TextSize::default()),
|
Importer::new(parsed, locator.contents(), stylist)
|
||||||
|
.add_import(required_import, TextSize::default()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ license = { workspace = true }
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = { workspace = true }
|
bitflags = { workspace = true }
|
||||||
ruff_db = { workspace = true }
|
ruff_db = { workspace = true }
|
||||||
|
ruff_diagnostics = { workspace = true }
|
||||||
ruff_index = { workspace = true }
|
ruff_index = { workspace = true }
|
||||||
ruff_memory_usage = { workspace = true }
|
ruff_memory_usage = { workspace = true }
|
||||||
ruff_python_ast = { workspace = true }
|
ruff_python_ast = { workspace = true }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue