mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:39:12 +00:00
Allow Locator#slice
to take Ranged
(#6922)
## Summary As a small quality-of-life improvement, the locator can now slice like `locator.slice(stmt)` instead of requiring `locator.slice(stmt.range())`. ## Test Plan `cargo test`
This commit is contained in:
parent
58f5f27dc3
commit
aea7500c1e
42 changed files with 89 additions and 96 deletions
|
@ -8,7 +8,6 @@ use libcst_native::{
|
|||
use ruff_python_ast::Stmt;
|
||||
use ruff_python_codegen::Stylist;
|
||||
use ruff_source_file::Locator;
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::cst::helpers::compose_module_path;
|
||||
use crate::cst::matchers::match_statement;
|
||||
|
@ -39,7 +38,7 @@ pub(crate) fn remove_imports<'a>(
|
|||
locator: &Locator,
|
||||
stylist: &Stylist,
|
||||
) -> Result<Option<String>> {
|
||||
let module_text = locator.slice(stmt.range());
|
||||
let module_text = locator.slice(stmt);
|
||||
let mut tree = match_statement(module_text)?;
|
||||
|
||||
let Statement::Simple(body) = &mut tree else {
|
||||
|
@ -118,7 +117,7 @@ pub(crate) fn retain_imports(
|
|||
locator: &Locator,
|
||||
stylist: &Stylist,
|
||||
) -> Result<String> {
|
||||
let module_text = locator.slice(stmt.range());
|
||||
let module_text = locator.slice(stmt);
|
||||
let mut tree = match_statement(module_text)?;
|
||||
|
||||
let Statement::Simple(body) = &mut tree else {
|
||||
|
|
|
@ -163,9 +163,9 @@ pub(crate) fn definitions(checker: &mut Checker) {
|
|||
continue;
|
||||
};
|
||||
|
||||
let contents = checker.locator.slice(expr.range());
|
||||
let contents = checker.locator().slice(expr);
|
||||
|
||||
let indentation = checker.locator.slice(TextRange::new(
|
||||
let indentation = checker.locator().slice(TextRange::new(
|
||||
checker.locator.line_start(expr.start()),
|
||||
expr.start(),
|
||||
));
|
||||
|
|
|
@ -76,7 +76,7 @@ impl StatementVisitor<'_> for StringLinesVisitor<'_> {
|
|||
}) = value.as_ref()
|
||||
{
|
||||
for line in UniversalNewlineIterator::with_offset(
|
||||
self.locator.slice(value.range()),
|
||||
self.locator.slice(value.as_ref()),
|
||||
value.start(),
|
||||
) {
|
||||
self.string_lines.push(line.start());
|
||||
|
|
|
@ -319,7 +319,7 @@ impl<'a> Importer<'a> {
|
|||
|
||||
/// Add the given member to an existing `Stmt::ImportFrom` statement.
|
||||
fn add_member(&self, stmt: &Stmt, member: &str) -> Result<Edit> {
|
||||
let mut statement = match_statement(self.locator.slice(stmt.range()))?;
|
||||
let mut statement = match_statement(self.locator.slice(stmt))?;
|
||||
let import_from = match_import_from(&mut statement)?;
|
||||
let aliases = match_aliases(import_from)?;
|
||||
aliases.push(ImportAlias {
|
||||
|
|
|
@ -81,7 +81,7 @@ pub(crate) fn getattr_with_constant(
|
|||
let mut diagnostic = Diagnostic::new(GetAttrWithConstant, expr.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
diagnostic.set_fix(Fix::suggested(Edit::range_replacement(
|
||||
format!("{}.{}", checker.locator().slice(obj.range()), value),
|
||||
format!("{}.{}", checker.locator().slice(obj), value),
|
||||
expr.range(),
|
||||
)));
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ pub(crate) fn unreliable_callable_check(
|
|||
if id == "hasattr" {
|
||||
if checker.semantic().is_builtin("callable") {
|
||||
diagnostic.set_fix(Fix::automatic(Edit::range_replacement(
|
||||
format!("callable({})", checker.locator().slice(obj.range())),
|
||||
format!("callable({})", checker.locator().slice(obj)),
|
||||
expr.range(),
|
||||
)));
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ pub(crate) fn fix_unnecessary_generator_list(
|
|||
expr: &Expr,
|
||||
) -> Result<Edit> {
|
||||
// Expr(Call(GeneratorExp)))) -> Expr(ListComp)))
|
||||
let module_text = locator.slice(expr.range());
|
||||
let module_text = locator.slice(expr);
|
||||
let mut tree = match_expression(module_text)?;
|
||||
let call = match_call_mut(&mut tree)?;
|
||||
let arg = match_arg(call)?;
|
||||
|
@ -63,7 +63,7 @@ pub(crate) fn fix_unnecessary_generator_set(checker: &Checker, expr: &Expr) -> R
|
|||
let stylist = checker.stylist();
|
||||
|
||||
// Expr(Call(GeneratorExp)))) -> Expr(SetComp)))
|
||||
let module_text = locator.slice(expr.range());
|
||||
let module_text = locator.slice(expr);
|
||||
let mut tree = match_expression(module_text)?;
|
||||
let call = match_call_mut(&mut tree)?;
|
||||
let arg = match_arg(call)?;
|
||||
|
@ -97,7 +97,7 @@ pub(crate) fn fix_unnecessary_generator_dict(checker: &Checker, expr: &Expr) ->
|
|||
let locator = checker.locator();
|
||||
let stylist = checker.stylist();
|
||||
|
||||
let module_text = locator.slice(expr.range());
|
||||
let module_text = locator.slice(expr);
|
||||
let mut tree = match_expression(module_text)?;
|
||||
let call = match_call_mut(&mut tree)?;
|
||||
let arg = match_arg(call)?;
|
||||
|
@ -141,7 +141,7 @@ pub(crate) fn fix_unnecessary_list_comprehension_set(
|
|||
let stylist = checker.stylist();
|
||||
// Expr(Call(ListComp)))) ->
|
||||
// Expr(SetComp)))
|
||||
let module_text = locator.slice(expr.range());
|
||||
let module_text = locator.slice(expr);
|
||||
let mut tree = match_expression(module_text)?;
|
||||
let call = match_call_mut(&mut tree)?;
|
||||
let arg = match_arg(call)?;
|
||||
|
@ -176,7 +176,7 @@ pub(crate) fn fix_unnecessary_list_comprehension_dict(
|
|||
let locator = checker.locator();
|
||||
let stylist = checker.stylist();
|
||||
|
||||
let module_text = locator.slice(expr.range());
|
||||
let module_text = locator.slice(expr);
|
||||
let mut tree = match_expression(module_text)?;
|
||||
let call = match_call_mut(&mut tree)?;
|
||||
let arg = match_arg(call)?;
|
||||
|
@ -261,7 +261,7 @@ pub(crate) fn fix_unnecessary_literal_set(checker: &Checker, expr: &Expr) -> Res
|
|||
let stylist = checker.stylist();
|
||||
|
||||
// Expr(Call(List|Tuple)))) -> Expr(Set)))
|
||||
let module_text = locator.slice(expr.range());
|
||||
let module_text = locator.slice(expr);
|
||||
let mut tree = match_expression(module_text)?;
|
||||
let call = match_call_mut(&mut tree)?;
|
||||
let arg = match_arg(call)?;
|
||||
|
@ -302,7 +302,7 @@ pub(crate) fn fix_unnecessary_literal_dict(checker: &Checker, expr: &Expr) -> Re
|
|||
let stylist = checker.stylist();
|
||||
|
||||
// Expr(Call(List|Tuple)))) -> Expr(Dict)))
|
||||
let module_text = locator.slice(expr.range());
|
||||
let module_text = locator.slice(expr);
|
||||
let mut tree = match_expression(module_text)?;
|
||||
let call = match_call_mut(&mut tree)?;
|
||||
let arg = match_arg(call)?;
|
||||
|
@ -371,7 +371,7 @@ pub(crate) fn fix_unnecessary_collection_call(checker: &Checker, expr: &Expr) ->
|
|||
let stylist = checker.stylist();
|
||||
|
||||
// Expr(Call("list" | "tuple" | "dict")))) -> Expr(List|Tuple|Dict)
|
||||
let module_text = locator.slice(expr.range());
|
||||
let module_text = locator.slice(expr);
|
||||
let mut tree = match_expression(module_text)?;
|
||||
let call = match_call(&tree)?;
|
||||
let name = match_name(&call.func)?;
|
||||
|
@ -522,7 +522,7 @@ pub(crate) fn fix_unnecessary_literal_within_tuple_call(
|
|||
stylist: &Stylist,
|
||||
expr: &Expr,
|
||||
) -> Result<Edit> {
|
||||
let module_text = locator.slice(expr.range());
|
||||
let module_text = locator.slice(expr);
|
||||
let mut tree = match_expression(module_text)?;
|
||||
let call = match_call_mut(&mut tree)?;
|
||||
let arg = match_arg(call)?;
|
||||
|
@ -572,7 +572,7 @@ pub(crate) fn fix_unnecessary_literal_within_list_call(
|
|||
stylist: &Stylist,
|
||||
expr: &Expr,
|
||||
) -> Result<Edit> {
|
||||
let module_text = locator.slice(expr.range());
|
||||
let module_text = locator.slice(expr);
|
||||
let mut tree = match_expression(module_text)?;
|
||||
let call = match_call_mut(&mut tree)?;
|
||||
let arg = match_arg(call)?;
|
||||
|
@ -625,7 +625,7 @@ pub(crate) fn fix_unnecessary_list_call(
|
|||
expr: &Expr,
|
||||
) -> Result<Edit> {
|
||||
// Expr(Call(List|Tuple)))) -> Expr(List|Tuple)))
|
||||
let module_text = locator.slice(expr.range());
|
||||
let module_text = locator.slice(expr);
|
||||
let mut tree = match_expression(module_text)?;
|
||||
let call = match_call_mut(&mut tree)?;
|
||||
let arg = match_arg(call)?;
|
||||
|
@ -646,7 +646,7 @@ pub(crate) fn fix_unnecessary_call_around_sorted(
|
|||
stylist: &Stylist,
|
||||
expr: &Expr,
|
||||
) -> Result<Edit> {
|
||||
let module_text = locator.slice(expr.range());
|
||||
let module_text = locator.slice(expr);
|
||||
let mut tree = match_expression(module_text)?;
|
||||
let outer_call = match_call_mut(&mut tree)?;
|
||||
let inner_call = match &outer_call.args[..] {
|
||||
|
@ -758,7 +758,7 @@ pub(crate) fn fix_unnecessary_double_cast_or_process(
|
|||
stylist: &Stylist,
|
||||
expr: &Expr,
|
||||
) -> Result<Edit> {
|
||||
let module_text = locator.slice(expr.range());
|
||||
let module_text = locator.slice(expr);
|
||||
let mut tree = match_expression(module_text)?;
|
||||
let outer_call = match_call_mut(&mut tree)?;
|
||||
|
||||
|
@ -789,7 +789,7 @@ pub(crate) fn fix_unnecessary_comprehension(
|
|||
stylist: &Stylist,
|
||||
expr: &Expr,
|
||||
) -> Result<Edit> {
|
||||
let module_text = locator.slice(expr.range());
|
||||
let module_text = locator.slice(expr);
|
||||
let mut tree = match_expression(module_text)?;
|
||||
|
||||
match &tree {
|
||||
|
@ -878,7 +878,7 @@ pub(crate) fn fix_unnecessary_map(
|
|||
parent: Option<&Expr>,
|
||||
object_type: ObjectType,
|
||||
) -> Result<Edit> {
|
||||
let module_text = locator.slice(expr.range());
|
||||
let module_text = locator.slice(expr);
|
||||
let mut tree = match_expression(module_text)?;
|
||||
let call = match_call_mut(&mut tree)?;
|
||||
let arg = match_arg(call)?;
|
||||
|
@ -1021,7 +1021,7 @@ pub(crate) fn fix_unnecessary_literal_within_dict_call(
|
|||
stylist: &Stylist,
|
||||
expr: &Expr,
|
||||
) -> Result<Edit> {
|
||||
let module_text = locator.slice(expr.range());
|
||||
let module_text = locator.slice(expr);
|
||||
let mut tree = match_expression(module_text)?;
|
||||
let call = match_call_mut(&mut tree)?;
|
||||
let arg = match_arg(call)?;
|
||||
|
@ -1041,7 +1041,7 @@ pub(crate) fn fix_unnecessary_comprehension_any_all(
|
|||
expr: &Expr,
|
||||
) -> Result<Fix> {
|
||||
// Expr(ListComp) -> Expr(GeneratorExp)
|
||||
let module_text = locator.slice(expr.range());
|
||||
let module_text = locator.slice(expr);
|
||||
let mut tree = match_expression(module_text)?;
|
||||
let call = match_call_mut(&mut tree)?;
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ pub(crate) fn duplicate_union_member<'a>(checker: &mut Checker, expr: &'a Expr)
|
|||
// Replace the parent with its non-duplicate child.
|
||||
let child = if expr == left.as_ref() { right } else { left };
|
||||
diagnostic.set_fix(Fix::automatic(Edit::range_replacement(
|
||||
checker.locator().slice(child.range()).to_string(),
|
||||
checker.locator().slice(child.as_ref()).to_string(),
|
||||
parent.range(),
|
||||
)));
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ pub(crate) fn redundant_literal_union<'a>(checker: &mut Checker, union: &'a Expr
|
|||
if builtin_types_in_union.contains(&constant_type) {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
RedundantLiteralUnion {
|
||||
literal: checker.locator().slice(literal_expr.range()).to_string(),
|
||||
literal: checker.locator().slice(literal_expr).to_string(),
|
||||
builtin_type: constant_type,
|
||||
},
|
||||
literal_expr.range(),
|
||||
|
|
|
@ -249,7 +249,7 @@ fn is_valid_default_value_with_annotation(
|
|||
..
|
||||
}) = left.as_ref()
|
||||
{
|
||||
return locator.slice(left.range()).len() <= 10;
|
||||
return locator.slice(left.as_ref()).len() <= 10;
|
||||
} else if let Expr::UnaryOp(ast::ExprUnaryOp {
|
||||
op: UnaryOp::USub,
|
||||
operand,
|
||||
|
@ -262,7 +262,7 @@ fn is_valid_default_value_with_annotation(
|
|||
..
|
||||
}) = operand.as_ref()
|
||||
{
|
||||
return locator.slice(operand.range()).len() <= 10;
|
||||
return locator.slice(operand.as_ref()).len() <= 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ pub(crate) fn unnecessary_literal_union<'a>(checker: &mut Checker, expr: &'a Exp
|
|||
UnnecessaryLiteralUnion {
|
||||
members: literal_exprs
|
||||
.into_iter()
|
||||
.map(|literal_expr| checker.locator().slice(literal_expr.range()).to_string())
|
||||
.map(|expr| checker.locator().slice(expr.as_ref()).to_string())
|
||||
.collect(),
|
||||
},
|
||||
expr.range(),
|
||||
|
|
|
@ -78,7 +78,7 @@ pub(crate) fn unnecessary_type_union<'a>(checker: &mut Checker, union: &'a Expr)
|
|||
UnnecessaryTypeUnion {
|
||||
members: type_exprs
|
||||
.into_iter()
|
||||
.map(|type_expr| checker.locator().slice(type_expr.range()).to_string())
|
||||
.map(|type_expr| checker.locator().slice(type_expr.as_ref()).to_string())
|
||||
.collect(),
|
||||
is_pep604_union,
|
||||
},
|
||||
|
|
|
@ -411,7 +411,7 @@ fn to_pytest_raises_args<'a>(
|
|||
"assertRaises" | "failUnlessRaises" => {
|
||||
match (arguments.args.as_slice(), arguments.keywords.as_slice()) {
|
||||
// Ex) `assertRaises(Exception)`
|
||||
([arg], []) => Cow::Borrowed(checker.locator().slice(arg.range())),
|
||||
([arg], []) => Cow::Borrowed(checker.locator().slice(arg)),
|
||||
// Ex) `assertRaises(expected_exception=Exception)`
|
||||
([], [kwarg])
|
||||
if kwarg
|
||||
|
@ -429,8 +429,8 @@ fn to_pytest_raises_args<'a>(
|
|||
// Ex) `assertRaisesRegex(Exception, regex)`
|
||||
([arg1, arg2], []) => Cow::Owned(format!(
|
||||
"{}, match={}",
|
||||
checker.locator().slice(arg1.range()),
|
||||
checker.locator().slice(arg2.range())
|
||||
checker.locator().slice(arg1),
|
||||
checker.locator().slice(arg2)
|
||||
)),
|
||||
// Ex) `assertRaisesRegex(Exception, expected_regex=regex)`
|
||||
([arg], [kwarg])
|
||||
|
@ -441,7 +441,7 @@ fn to_pytest_raises_args<'a>(
|
|||
{
|
||||
Cow::Owned(format!(
|
||||
"{}, match={}",
|
||||
checker.locator().slice(arg.range()),
|
||||
checker.locator().slice(arg),
|
||||
checker.locator().slice(kwarg.value.range())
|
||||
))
|
||||
}
|
||||
|
|
|
@ -537,7 +537,7 @@ fn unnecessary_assign(checker: &mut Checker, stack: &Stack) {
|
|||
edits::delete_stmt(stmt, None, checker.locator(), checker.indexer());
|
||||
|
||||
// Replace the `x = 1` statement with `return 1`.
|
||||
let content = checker.locator().slice(assign.range());
|
||||
let content = checker.locator().slice(assign);
|
||||
let equals_index = content
|
||||
.find('=')
|
||||
.ok_or(anyhow::anyhow!("expected '=' in assignment statement"))?;
|
||||
|
|
|
@ -238,10 +238,10 @@ pub(crate) fn dict_get_with_none_default(checker: &mut Checker, expr: &Expr) {
|
|||
|
||||
let expected = format!(
|
||||
"{}({})",
|
||||
checker.locator().slice(func.range()),
|
||||
checker.locator().slice(key.range())
|
||||
checker.locator().slice(func.as_ref()),
|
||||
checker.locator().slice(key)
|
||||
);
|
||||
let original = checker.locator().slice(expr.range()).to_string();
|
||||
let original = checker.locator().slice(expr).to_string();
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
DictGetWithNoneDefault {
|
||||
|
|
|
@ -155,7 +155,7 @@ pub(crate) fn explicit_true_false_in_ifexpr(
|
|||
if checker.patch(diagnostic.kind.rule()) {
|
||||
if test.is_compare_expr() {
|
||||
diagnostic.set_fix(Fix::suggested(Edit::range_replacement(
|
||||
checker.locator().slice(test.range()).to_string(),
|
||||
checker.locator().slice(test).to_string(),
|
||||
expr.range(),
|
||||
)));
|
||||
} else if checker.semantic().is_builtin("bool") {
|
||||
|
|
|
@ -273,7 +273,7 @@ pub(crate) fn double_negation(checker: &mut Checker, expr: &Expr, op: UnaryOp, o
|
|||
if checker.patch(diagnostic.kind.rule()) {
|
||||
if checker.semantic().in_boolean_test() {
|
||||
diagnostic.set_fix(Fix::suggested(Edit::range_replacement(
|
||||
checker.locator().slice(operand.range()).to_string(),
|
||||
checker.locator().slice(operand.as_ref()).to_string(),
|
||||
expr.range(),
|
||||
)));
|
||||
} else if checker.semantic().is_builtin("bool") {
|
||||
|
|
|
@ -13,7 +13,7 @@ pub(super) fn trailing_comma(
|
|||
locator: &Locator,
|
||||
source_type: PySourceType,
|
||||
) -> TrailingComma {
|
||||
let contents = locator.slice(stmt.range());
|
||||
let contents = locator.slice(stmt);
|
||||
let mut count = 0u32;
|
||||
let mut trailing_comma = TrailingComma::Absent;
|
||||
for (tok, _) in lexer::lex_starts_at(contents, source_type.as_mode(), stmt.start()).flatten() {
|
||||
|
|
|
@ -103,7 +103,7 @@ pub(crate) fn incorrect_dict_iterator(checker: &mut Checker, stmt_for: &ast::Stm
|
|||
if checker.patch(diagnostic.kind.rule()) {
|
||||
let replace_attribute = Edit::range_replacement("values".to_string(), attr.range());
|
||||
let replace_target = Edit::range_replacement(
|
||||
checker.locator().slice(value.range()).to_string(),
|
||||
checker.locator().slice(value).to_string(),
|
||||
stmt_for.target.range(),
|
||||
);
|
||||
diagnostic.set_fix(Fix::suggested_edits(replace_attribute, [replace_target]));
|
||||
|
@ -121,7 +121,7 @@ pub(crate) fn incorrect_dict_iterator(checker: &mut Checker, stmt_for: &ast::Stm
|
|||
if checker.patch(diagnostic.kind.rule()) {
|
||||
let replace_attribute = Edit::range_replacement("keys".to_string(), attr.range());
|
||||
let replace_target = Edit::range_replacement(
|
||||
checker.locator().slice(key.range()).to_string(),
|
||||
checker.locator().slice(key).to_string(),
|
||||
stmt_for.target.range(),
|
||||
);
|
||||
diagnostic.set_fix(Fix::suggested_edits(replace_attribute, [replace_target]));
|
||||
|
|
|
@ -17,7 +17,7 @@ pub(super) fn remove_unused_format_arguments_from_dict(
|
|||
locator: &Locator,
|
||||
stylist: &Stylist,
|
||||
) -> Result<Edit> {
|
||||
let source_code = locator.slice(dict.range());
|
||||
let source_code = locator.slice(dict);
|
||||
transform_expression(source_code, stylist, |mut expression| {
|
||||
let dict = match_dict(&mut expression)?;
|
||||
|
||||
|
@ -41,7 +41,7 @@ pub(super) fn remove_unused_keyword_arguments_from_format_call(
|
|||
locator: &Locator,
|
||||
stylist: &Stylist,
|
||||
) -> Result<Edit> {
|
||||
let source_code = locator.slice(call.range());
|
||||
let source_code = locator.slice(call);
|
||||
transform_expression(source_code, stylist, |mut expression| {
|
||||
let call = match_call_mut(&mut expression)?;
|
||||
|
||||
|
@ -69,7 +69,7 @@ pub(crate) fn remove_unused_positional_arguments_from_format_call(
|
|||
locator: &Locator,
|
||||
stylist: &Stylist,
|
||||
) -> Result<Edit> {
|
||||
let source_code = locator.slice(call.range());
|
||||
let source_code = locator.slice(call);
|
||||
transform_expression(source_code, stylist, |mut expression| {
|
||||
let call = match_call_mut(&mut expression)?;
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ fn find_useless_f_strings<'a>(
|
|||
locator: &'a Locator,
|
||||
source_type: PySourceType,
|
||||
) -> impl Iterator<Item = (TextRange, TextRange)> + 'a {
|
||||
let contents = locator.slice(expr.range());
|
||||
let contents = locator.slice(expr);
|
||||
lexer::lex_starts_at(contents, source_type.as_mode(), expr.start())
|
||||
.flatten()
|
||||
.filter_map(|(tok, range)| match tok {
|
||||
|
|
|
@ -135,7 +135,7 @@ pub(crate) fn repeated_keys(checker: &mut Checker, keys: &[Option<Expr>], values
|
|||
if checker.enabled(Rule::MultiValueRepeatedKeyLiteral) {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
MultiValueRepeatedKeyLiteral {
|
||||
name: checker.locator().slice(key.range()).to_string(),
|
||||
name: checker.locator().slice(key).to_string(),
|
||||
},
|
||||
key.range(),
|
||||
);
|
||||
|
@ -154,7 +154,7 @@ pub(crate) fn repeated_keys(checker: &mut Checker, keys: &[Option<Expr>], values
|
|||
if checker.enabled(Rule::MultiValueRepeatedKeyVariable) {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
MultiValueRepeatedKeyVariable {
|
||||
name: checker.locator().slice(key.range()).to_string(),
|
||||
name: checker.locator().slice(key).to_string(),
|
||||
},
|
||||
key.range(),
|
||||
);
|
||||
|
|
|
@ -94,12 +94,8 @@ pub(crate) fn call(checker: &mut Checker, string: &str, range: TextRange) {
|
|||
pub(crate) fn percent(checker: &mut Checker, expr: &Expr) {
|
||||
// Grab each string segment (in case there's an implicit concatenation).
|
||||
let mut strings: Vec<TextRange> = vec![];
|
||||
for (tok, range) in lexer::lex_starts_at(
|
||||
checker.locator().slice(expr.range()),
|
||||
Mode::Module,
|
||||
expr.start(),
|
||||
)
|
||||
.flatten()
|
||||
for (tok, range) in
|
||||
lexer::lex_starts_at(checker.locator().slice(expr), Mode::Module, expr.start()).flatten()
|
||||
{
|
||||
if tok.is_string() {
|
||||
strings.push(range);
|
||||
|
|
|
@ -211,7 +211,7 @@ fn is_valid_dict(
|
|||
/// PLE1307
|
||||
pub(crate) fn bad_string_format_type(checker: &mut Checker, expr: &Expr, right: &Expr) {
|
||||
// Grab each string segment (in case there's an implicit concatenation).
|
||||
let content = checker.locator().slice(expr.range());
|
||||
let content = checker.locator().slice(expr);
|
||||
let mut strings: Vec<TextRange> = vec![];
|
||||
for (tok, range) in
|
||||
lexer::lex_starts_at(content, checker.source_type.as_mode(), expr.start()).flatten()
|
||||
|
|
|
@ -187,10 +187,10 @@ fn merged_membership_test(
|
|||
BoolOp::Or => "in",
|
||||
BoolOp::And => "not in",
|
||||
};
|
||||
let left = locator.slice(left.range());
|
||||
let left = locator.slice(left);
|
||||
let members = comparators
|
||||
.iter()
|
||||
.map(|comparator| locator.slice(comparator.range()))
|
||||
.map(|comparator| locator.slice(comparator))
|
||||
.join(", ");
|
||||
format!("{left} {op} ({members})",)
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ where
|
|||
{
|
||||
let mut diagnostic = Diagnostic::new(DeprecatedCElementTree, node.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
let contents = checker.locator().slice(node.range());
|
||||
let contents = checker.locator().slice(node);
|
||||
diagnostic.set_fix(Fix::suggested(Edit::range_replacement(
|
||||
contents.replacen("cElementTree", "ElementTree", 1),
|
||||
node.range(),
|
||||
|
|
|
@ -150,7 +150,7 @@ fn format_import(
|
|||
locator: &Locator,
|
||||
stylist: &Stylist,
|
||||
) -> Result<String> {
|
||||
let module_text = locator.slice(stmt.range());
|
||||
let module_text = locator.slice(stmt);
|
||||
let mut tree = match_statement(module_text)?;
|
||||
let import = match_import(&mut tree)?;
|
||||
|
||||
|
@ -177,7 +177,7 @@ fn format_import_from(
|
|||
locator: &Locator,
|
||||
stylist: &Stylist,
|
||||
) -> Result<String> {
|
||||
let module_text = locator.slice(stmt.range());
|
||||
let module_text = locator.slice(stmt);
|
||||
let mut tree = match_statement(module_text).unwrap();
|
||||
let import = match_import_from(&mut tree)?;
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ impl<'a> FormatSummaryValues<'a> {
|
|||
|
||||
for arg in &call.arguments.args {
|
||||
if matches!(arg, Expr::Starred(..))
|
||||
|| contains_quotes(locator.slice(arg.range()))
|
||||
|| contains_quotes(locator.slice(arg))
|
||||
|| locator.contains_line_break(arg.range())
|
||||
{
|
||||
return None;
|
||||
|
@ -90,9 +90,7 @@ impl<'a> FormatSummaryValues<'a> {
|
|||
let Some(key) = arg else {
|
||||
return None;
|
||||
};
|
||||
if contains_quotes(locator.slice(value.range()))
|
||||
|| locator.contains_line_break(value.range())
|
||||
{
|
||||
if contains_quotes(locator.slice(value)) || locator.contains_line_break(value.range()) {
|
||||
return None;
|
||||
}
|
||||
extracted_kwargs.insert(key, value);
|
||||
|
@ -142,7 +140,7 @@ enum FormatContext {
|
|||
|
||||
/// Given an [`Expr`], format it for use in a formatted expression within an f-string.
|
||||
fn formatted_expr<'a>(expr: &Expr, context: FormatContext, locator: &Locator<'a>) -> Cow<'a, str> {
|
||||
let text = locator.slice(expr.range());
|
||||
let text = locator.slice(expr);
|
||||
let parenthesize = match (context, expr) {
|
||||
// E.g., `x + y` should be parenthesized in `f"{(x + y)[0]}"`.
|
||||
(
|
||||
|
@ -373,7 +371,7 @@ pub(crate) fn f_strings(
|
|||
return;
|
||||
}
|
||||
|
||||
let mut contents = String::with_capacity(checker.locator().slice(call.range()).len());
|
||||
let mut contents = String::with_capacity(checker.locator().slice(call).len());
|
||||
let mut prev_end = call.start();
|
||||
for (range, fstring) in patches {
|
||||
contents.push_str(
|
||||
|
|
|
@ -206,7 +206,7 @@ fn generate_call(
|
|||
locator: &Locator,
|
||||
stylist: &Stylist,
|
||||
) -> Result<String> {
|
||||
let source_code = locator.slice(call.range());
|
||||
let source_code = locator.slice(call);
|
||||
|
||||
let output = transform_expression_text(source_code, |source_code| {
|
||||
let mut expression = match_expression(&source_code)?;
|
||||
|
|
|
@ -211,7 +211,7 @@ pub(crate) fn native_literals(
|
|||
return;
|
||||
}
|
||||
|
||||
let arg_code = checker.locator().slice(arg.range());
|
||||
let arg_code = checker.locator().slice(arg);
|
||||
|
||||
// Attribute access on an integer requires the integer to be parenthesized to disambiguate from a float
|
||||
// Ex) `(7).denominator` is valid but `7.denominator` is not
|
||||
|
|
|
@ -163,7 +163,7 @@ fn percent_to_format(format_string: &CFormatString) -> String {
|
|||
|
||||
/// If a tuple has one argument, remove the comma; otherwise, return it as-is.
|
||||
fn clean_params_tuple(checker: &mut Checker, right: &Expr, locator: &Locator) -> String {
|
||||
let mut contents = checker.locator().slice(right.range()).to_string();
|
||||
let mut contents = checker.locator().slice(right).to_string();
|
||||
if let Expr::Tuple(ast::ExprTuple { elts, .. }) = &right {
|
||||
if elts.len() == 1 {
|
||||
if !locator.contains_line_break(right.range()) {
|
||||
|
@ -224,7 +224,7 @@ fn clean_params_dictionary(
|
|||
}
|
||||
}
|
||||
|
||||
let value_string = checker.locator().slice(value.range());
|
||||
let value_string = checker.locator().slice(value);
|
||||
arguments.push(format!("{key_string}={value_string}"));
|
||||
} else {
|
||||
// If there are any non-string keys, abort.
|
||||
|
@ -232,7 +232,7 @@ fn clean_params_dictionary(
|
|||
}
|
||||
}
|
||||
None => {
|
||||
let value_string = checker.locator().slice(value.range());
|
||||
let value_string = checker.locator().slice(value);
|
||||
arguments.push(format!("**{value_string}"));
|
||||
}
|
||||
}
|
||||
|
@ -343,7 +343,7 @@ pub(crate) fn printf_string_formatting(
|
|||
let mut strings: Vec<TextRange> = vec![];
|
||||
let mut extension = None;
|
||||
for (tok, range) in lexer::lex_starts_at(
|
||||
checker.locator().slice(expr.range()),
|
||||
checker.locator().slice(expr),
|
||||
checker.source_type.as_mode(),
|
||||
expr.start(),
|
||||
)
|
||||
|
@ -404,16 +404,16 @@ pub(crate) fn printf_string_formatting(
|
|||
// Parse the parameters.
|
||||
let params_string = match right {
|
||||
Expr::Constant(_) | Expr::FString(_) => {
|
||||
format!("({})", checker.locator().slice(right.range()))
|
||||
format!("({})", checker.locator().slice(right))
|
||||
}
|
||||
Expr::Name(_) | Expr::Attribute(_) | Expr::Subscript(_) | Expr::Call(_) => {
|
||||
if num_keyword_arguments > 0 {
|
||||
// If we have _any_ named fields, assume the right-hand side is a mapping.
|
||||
format!("(**{})", checker.locator().slice(right.range()))
|
||||
format!("(**{})", checker.locator().slice(right))
|
||||
} else if num_positional_arguments > 1 {
|
||||
// If we have multiple fields, but no named fields, assume the right-hand side is a
|
||||
// tuple.
|
||||
format!("(*{})", checker.locator().slice(right.range()))
|
||||
format!("(*{})", checker.locator().slice(right))
|
||||
} else {
|
||||
// Otherwise, if we have a single field, we can't make any assumptions about the
|
||||
// right-hand side. It _could_ be a tuple, but it could also be a single value,
|
||||
|
|
|
@ -204,7 +204,7 @@ fn create_remove_param_fix<T: Ranged>(
|
|||
mode_param: &Expr,
|
||||
source_type: PySourceType,
|
||||
) -> Result<Edit> {
|
||||
let content = locator.slice(expr.range());
|
||||
let content = locator.slice(expr);
|
||||
// Find the last comma before mode_param and create a deletion fix
|
||||
// starting from the comma and ending after mode_param.
|
||||
let mut fix_start: Option<TextSize> = None;
|
||||
|
|
|
@ -125,7 +125,7 @@ fn replace_with_bytes_literal(
|
|||
source_type: PySourceType,
|
||||
) -> Fix {
|
||||
// Build up a replacement string by prefixing all string tokens with `b`.
|
||||
let contents = locator.slice(call.range());
|
||||
let contents = locator.slice(call);
|
||||
let mut replacement = String::with_capacity(contents.len() + 1);
|
||||
let mut prev = call.start();
|
||||
for (tok, range) in
|
||||
|
|
|
@ -68,7 +68,7 @@ pub(crate) fn unpacked_list_comprehension(checker: &mut Checker, targets: &[Expr
|
|||
|
||||
let mut diagnostic = Diagnostic::new(UnpackedListComprehension, value.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
let existing = checker.locator().slice(value.range());
|
||||
let existing = checker.locator().slice(value);
|
||||
|
||||
let mut content = String::with_capacity(existing.len());
|
||||
content.push('(');
|
||||
|
|
|
@ -100,7 +100,7 @@ pub(crate) fn use_pep604_annotation(
|
|||
_ => {
|
||||
// Single argument.
|
||||
diagnostic.set_fix(Fix::suggested(Edit::range_replacement(
|
||||
checker.locator().slice(slice.range()).to_string(),
|
||||
checker.locator().slice(slice).to_string(),
|
||||
expr.range(),
|
||||
)));
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ pub(crate) fn use_pep604_annotation(
|
|||
|
||||
/// Format the expression as a PEP 604-style optional.
|
||||
fn optional(expr: &Expr, locator: &Locator) -> String {
|
||||
format!("{} | None", locator.slice(expr.range()))
|
||||
format!("{} | None", locator.slice(expr))
|
||||
}
|
||||
|
||||
/// Format the expressions as a PEP 604-style union.
|
||||
|
@ -128,7 +128,7 @@ fn union(elts: &[Expr], locator: &Locator) -> String {
|
|||
if elts.peek().is_none() {
|
||||
"()".to_string()
|
||||
} else {
|
||||
elts.map(|expr| locator.slice(expr.range())).join(" | ")
|
||||
elts.map(|expr| locator.slice(expr)).join(" | ")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ pub(crate) fn yield_in_for_loop(checker: &mut Checker, stmt_for: &ast::StmtFor)
|
|||
|
||||
let mut diagnostic = Diagnostic::new(YieldInForLoop, stmt_for.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
let contents = checker.locator().slice(iter.range());
|
||||
let contents = checker.locator().slice(iter.as_ref());
|
||||
let contents = format!("yield from {contents}");
|
||||
diagnostic.set_fix(Fix::suggested(Edit::range_replacement(
|
||||
contents,
|
||||
|
|
|
@ -139,7 +139,7 @@ fn convert_call_to_conversion_flag(
|
|||
locator: &Locator,
|
||||
stylist: &Stylist,
|
||||
) -> Result<Fix> {
|
||||
let source_code = locator.slice(expr.range());
|
||||
let source_code = locator.slice(expr);
|
||||
transform_expression(source_code, stylist, |mut expression| {
|
||||
// Replace the formatted call expression at `index` with a conversion flag.
|
||||
let formatted_string_expression = match_part(index, &mut expression)?;
|
||||
|
|
|
@ -99,7 +99,7 @@ fn convert_to_reduce(iterable: &Expr, call: &ast::ExprCall, checker: &Checker) -
|
|||
checker.semantic(),
|
||||
)?;
|
||||
|
||||
let iterable = checker.locator().slice(iterable.range());
|
||||
let iterable = checker.locator().slice(iterable);
|
||||
|
||||
Ok(Fix::suggested_edits(
|
||||
Edit::range_replacement(
|
||||
|
|
|
@ -45,7 +45,7 @@ pub(crate) fn static_key_dict_comprehension(checker: &mut Checker, key: &Expr) {
|
|||
if is_constant(key) {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
StaticKeyDictComprehension {
|
||||
key: checker.locator().slice(key.range()).to_string(),
|
||||
key: checker.locator().slice(key).to_string(),
|
||||
},
|
||||
key.range(),
|
||||
));
|
||||
|
|
|
@ -788,12 +788,12 @@ fn format_docstring(string_part: &FormatStringPart, f: &mut PyFormatter) -> Form
|
|||
let locator = f.context().locator();
|
||||
|
||||
// Black doesn't change the indentation of docstrings that contain an escaped newline
|
||||
if locator.slice(string_part.range()).contains("\\\n") {
|
||||
if locator.slice(string_part).contains("\\\n") {
|
||||
return string_part.fmt(f);
|
||||
}
|
||||
|
||||
let (normalized, _) = normalize_string(
|
||||
locator.slice(string_part.range()),
|
||||
locator.slice(string_part),
|
||||
string_part.preferred_quotes,
|
||||
string_part.is_raw_string,
|
||||
);
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::cmp::Ordering;
|
|||
use std::fmt::{Debug, Formatter};
|
||||
use std::sync::Arc;
|
||||
|
||||
use ruff_text_size::{TextRange, TextSize};
|
||||
use ruff_text_size::{Ranged, TextRange, TextSize};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -56,8 +56,8 @@ impl<'src, 'index> SourceCode<'src, 'index> {
|
|||
}
|
||||
|
||||
/// Take the source code between the given [`TextRange`].
|
||||
pub fn slice(&self, range: TextRange) -> &'src str {
|
||||
&self.text[range]
|
||||
pub fn slice<T: Ranged>(&self, ranged: T) -> &'src str {
|
||||
&self.text[ranged.range()]
|
||||
}
|
||||
|
||||
pub fn line_start(&self, line: OneIndexed) -> TextSize {
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::ops::Add;
|
|||
|
||||
use memchr::{memchr2, memrchr2};
|
||||
use once_cell::unsync::OnceCell;
|
||||
use ruff_text_size::{TextLen, TextRange, TextSize};
|
||||
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
|
||||
|
||||
use crate::newlines::find_newline;
|
||||
use crate::{LineIndex, OneIndexed, SourceCode, SourceLocation};
|
||||
|
@ -390,8 +390,8 @@ impl<'a> Locator<'a> {
|
|||
|
||||
/// Take the source code between the given [`TextRange`].
|
||||
#[inline]
|
||||
pub fn slice(&self, range: TextRange) -> &'a str {
|
||||
&self.contents[range]
|
||||
pub fn slice<T: Ranged>(&self, ranged: T) -> &'a str {
|
||||
&self.contents[ranged.range()]
|
||||
}
|
||||
|
||||
/// Return the underlying source code.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue