Extract LineIndex independent methods from Locator (#13938)

This commit is contained in:
Micha Reiser 2024-10-28 08:53:41 +01:00 committed by GitHub
parent f8eb547fb4
commit 9f3a38d408
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
171 changed files with 1348 additions and 1284 deletions

View file

@ -2,23 +2,22 @@
// "reStructuredText."
#![allow(clippy::doc_markdown)]
use itertools::Itertools;
use std::cmp::Ordering;
use std::sync::LazyLock;
use std::{borrow::Cow, collections::VecDeque};
use itertools::Itertools;
use regex::Regex;
use ruff_formatter::printer::SourceMapGeneration;
use ruff_python_ast::{str::Quote, AnyStringFlags, StringFlags};
use ruff_python_trivia::CommentRanges;
use {
ruff_formatter::{write, FormatOptions, IndentStyle, LineWidth, Printed},
ruff_python_trivia::{is_python_whitespace, PythonWhitespace},
ruff_source_file::Locator,
ruff_text_size::{Ranged, TextLen, TextRange, TextSize},
};
use super::NormalizedString;
use crate::preview::{
is_docstring_code_block_in_docstring_indent_enabled,
is_join_implicit_concatenated_string_enabled,
@ -26,6 +25,8 @@ use crate::preview::{
use crate::string::StringQuotes;
use crate::{prelude::*, DocstringCodeLineWidth, FormatModuleError};
use super::NormalizedString;
/// Format a docstring by trimming whitespace and adjusting the indentation.
///
/// Summary of changes we make:
@ -1592,9 +1593,8 @@ fn docstring_format_source(
let comment_ranges = CommentRanges::from(parsed.tokens());
let source_code = ruff_formatter::SourceCode::new(source);
let comments = crate::Comments::from_ast(parsed.syntax(), source_code, &comment_ranges);
let locator = Locator::new(source);
let ctx = PyFormatContext::new(options, locator.contents(), comments, parsed.tokens())
let ctx = PyFormatContext::new(options, source, comments, parsed.tokens())
.in_docstring(docstring_quote_style);
let formatted = crate::format!(ctx, [parsed.syntax().format()])?;
formatted

View file

@ -6,6 +6,7 @@ use ruff_python_ast::str_prefix::{
AnyStringPrefix, ByteStringPrefix, FStringPrefix, StringLiteralPrefix,
};
use ruff_python_ast::{AnyStringFlags, FStringElement, StringFlags, StringLike, StringLikePart};
use ruff_source_file::LineRanges;
use ruff_text_size::{Ranged, TextRange};
use crate::comments::{leading_comments, trailing_comments};
@ -72,7 +73,7 @@ impl<'a> FormatImplicitConcatenatedStringExpanded<'a> {
impl Format<PyFormatContext<'_>> for FormatImplicitConcatenatedStringExpanded<'_> {
fn fmt(&self, f: &mut Formatter<PyFormatContext<'_>>) -> FormatResult<()> {
let comments = f.context().comments().clone();
let quoting = self.string.quoting(&f.context().locator());
let quoting = self.string.quoting(f.context().source());
let join_implicit_concatenated_string_enabled =
is_join_implicit_concatenated_string_enabled(f.context());
@ -158,10 +159,9 @@ impl<'a> FormatImplicitConcatenatedStringFlat<'a> {
if let StringLikePart::FString(fstring) = part {
if fstring.elements.iter().any(|element| match element {
// Same as for other literals. Multiline literals can't fit on a single line.
FStringElement::Literal(literal) => context
.locator()
.slice(literal.range())
.contains(['\n', '\r']),
FStringElement::Literal(literal) => {
context.source().contains_line_break(literal.range())
}
FStringElement::Expression(expression) => {
if is_f_string_formatting_enabled(context) {
// Expressions containing comments can't be joined.
@ -169,7 +169,7 @@ impl<'a> FormatImplicitConcatenatedStringFlat<'a> {
} else {
// Multiline f-string expressions can't be joined if the f-string formatting is disabled because
// the string gets inserted in verbatim preserving the newlines.
context.locator().slice(expression).contains(['\n', '\r'])
context.source().contains_line_break(expression.range())
}
}
}) {
@ -269,12 +269,7 @@ impl Format<PyFormatContext<'_>> for FormatImplicitConcatenatedStringFlat<'_> {
for part in self.string.parts().rev() {
assert!(part.is_string_literal());
if f.context()
.locator()
.slice(part.content_range())
.trim()
.is_empty()
{
if f.context().source()[part.content_range()].trim().is_empty() {
// Don't format the part.
parts.next_back();
} else {
@ -298,10 +293,7 @@ impl Format<PyFormatContext<'_>> for FormatImplicitConcatenatedStringFlat<'_> {
.fmt(f)?;
if first_non_empty {
first_non_empty = f
.context()
.locator()
.slice(part.content_range())
first_non_empty = f.context().source()[part.content_range()]
.trim_start()
.is_empty();
}
@ -328,7 +320,7 @@ impl Format<PyFormatContext<'_>> for FormatImplicitConcatenatedStringFlat<'_> {
self.flags,
FStringLayout::from_f_string(
f_string,
&f.context().locator(),
f.context().source(),
),
);
@ -365,7 +357,7 @@ struct FormatLiteralContent {
impl Format<PyFormatContext<'_>> for FormatLiteralContent {
fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> {
let content = f.context().locator().slice(self.range);
let content = &f.context().source()[self.range];
let mut normalized = normalize_string(
content,
0,

View file

@ -7,7 +7,6 @@ use ruff_python_ast::{
str_prefix::{AnyStringPrefix, StringLiteralPrefix},
AnyStringFlags, StringFlags,
};
use ruff_source_file::Locator;
use ruff_text_size::Ranged;
use crate::expression::expr_f_string::f_string_quoting;
@ -89,16 +88,16 @@ impl From<Quote> for QuoteStyle {
// Extension trait that adds formatter specific helper methods to `StringLike`.
pub(crate) trait StringLikeExtensions {
fn quoting(&self, locator: &Locator<'_>) -> Quoting;
fn quoting(&self, source: &str) -> Quoting;
fn is_multiline(&self, source: &str) -> bool;
}
impl StringLikeExtensions for ast::StringLike<'_> {
fn quoting(&self, locator: &Locator<'_>) -> Quoting {
fn quoting(&self, source: &str) -> Quoting {
match self {
Self::String(_) | Self::Bytes(_) => Quoting::CanChange,
Self::FString(f_string) => f_string_quoting(f_string, locator),
Self::FString(f_string) => f_string_quoting(f_string, source),
}
}

View file

@ -7,7 +7,7 @@ use ruff_python_ast::visitor::source_order::SourceOrderVisitor;
use ruff_python_ast::{
str::Quote, AnyStringFlags, BytesLiteral, FString, StringFlags, StringLikePart, StringLiteral,
};
use ruff_text_size::{Ranged, TextRange};
use ruff_text_size::{Ranged, TextRange, TextSlice};
use crate::context::FStringState;
use crate::prelude::*;
@ -152,7 +152,7 @@ impl<'a, 'src> StringNormalizer<'a, 'src> {
/// Computes the strings preferred quotes.
pub(crate) fn choose_quotes(&self, string: StringLikePart) -> QuoteSelection {
let raw_content = self.context.locator().slice(string.content_range());
let raw_content = &self.context.source()[string.content_range()];
let first_quote_or_normalized_char_offset = raw_content
.bytes()
.position(|b| matches!(b, b'\\' | b'"' | b'\'' | b'\r' | b'{'));
@ -196,7 +196,7 @@ impl<'a, 'src> StringNormalizer<'a, 'src> {
/// Computes the strings preferred quotes and normalizes its content.
pub(crate) fn normalize(&self, string: StringLikePart) -> NormalizedString<'src> {
let raw_content = self.context.locator().slice(string.content_range());
let raw_content = &self.context.source()[string.content_range()];
let quote_selection = self.choose_quotes(string);
let normalized = if let Some(first_quote_or_escape_offset) =
@ -256,7 +256,7 @@ impl QuoteMetadata {
) -> Self {
match part {
StringLikePart::String(_) | StringLikePart::Bytes(_) => {
let text = context.locator().slice(part.content_range());
let text = &context.source()[part.content_range()];
Self::from_str(text, part.flags(), preferred_quote)
}
@ -277,7 +277,7 @@ impl QuoteMetadata {
};
let mut metadata = QuoteMetadata::from_str(
context.locator().slice(first.range()),
context.source().slice(first),
fstring.flags.into(),
preferred_quote,
);
@ -285,7 +285,7 @@ impl QuoteMetadata {
for literal in literals {
metadata = metadata
.merge(&QuoteMetadata::from_str(
context.locator().slice(literal.range()),
context.source().slice(literal),
fstring.flags.into(),
preferred_quote,
))
@ -294,7 +294,7 @@ impl QuoteMetadata {
metadata
} else {
let text = context.locator().slice(part.content_range());
let text = &context.source()[part.content_range()];
Self::from_str(text, part.flags(), preferred_quote)
}
@ -893,7 +893,7 @@ pub(super) fn is_fstring_with_quoted_debug_expression(
) -> bool {
if fstring.elements.expressions().any(|expression| {
if expression.debug_text.is_some() {
let content = context.locator().slice(expression.range());
let content = context.source().slice(expression);
match fstring.flags.quote_style() {
Quote::Single => {
if fstring.flags.is_triple_quoted() {
@ -969,10 +969,7 @@ pub(super) fn is_fstring_with_triple_quoted_literal_expression_containing_quotes
}
fn contains_quote(&self, range: TextRange, flags: AnyStringFlags) -> bool {
self.context
.locator()
.slice(range)
.contains(flags.quote_style().as_char())
self.context.source()[range].contains(flags.quote_style().as_char())
}
}