mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-23 13:05:06 +00:00
Introduce SourceCodeSlice
to reduce the size of FormatElement
(#4622)
Introduce `SourceCodeSlice` to reduce the size of `FormatElement`
This commit is contained in:
parent
6943beee66
commit
86ced3516b
26 changed files with 408 additions and 171 deletions
|
@ -1,14 +1,13 @@
|
||||||
use crate::format_element::tag::{Condition, Tag};
|
use crate::format_element::tag::{Condition, Tag};
|
||||||
use crate::prelude::tag::{DedentMode, GroupMode, LabelId};
|
use crate::prelude::tag::{DedentMode, GroupMode, LabelId};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::{format_element, write, Argument, Arguments, GroupId, TextSize};
|
use crate::{format_element, write, Argument, Arguments, FormatContext, GroupId, TextSize};
|
||||||
use crate::{Buffer, VecBuffer};
|
use crate::{Buffer, VecBuffer};
|
||||||
|
|
||||||
use ruff_text_size::TextRange;
|
use ruff_text_size::TextRange;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::num::NonZeroU8;
|
use std::num::NonZeroU8;
|
||||||
use std::rc::Rc;
|
|
||||||
use Tag::*;
|
use Tag::*;
|
||||||
|
|
||||||
/// A line break that only gets printed if the enclosing `Group` doesn't fit on a single line.
|
/// A line break that only gets printed if the enclosing `Group` doesn't fit on a single line.
|
||||||
|
@ -361,31 +360,65 @@ impl std::fmt::Debug for DynamicText<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a text from a dynamic string and a range of the input source
|
/// Emits a text as it is written in the source document. Optimized to avoid allocations.
|
||||||
pub fn static_text_slice(text: Rc<str>, range: TextRange) -> StaticTextSlice {
|
pub const fn source_text_slice(
|
||||||
debug_assert_no_newlines(&text[range]);
|
|
||||||
|
|
||||||
StaticTextSlice { text, range }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Eq, PartialEq)]
|
|
||||||
pub struct StaticTextSlice {
|
|
||||||
text: Rc<str>,
|
|
||||||
range: TextRange,
|
range: TextRange,
|
||||||
}
|
newlines: ContainsNewlines,
|
||||||
|
) -> SourceTextSliceBuilder {
|
||||||
impl<Context> Format<Context> for StaticTextSlice {
|
SourceTextSliceBuilder {
|
||||||
fn fmt(&self, f: &mut Formatter<Context>) -> FormatResult<()> {
|
range,
|
||||||
f.write_element(FormatElement::StaticTextSlice {
|
new_lines: newlines,
|
||||||
text: self.text.clone(),
|
|
||||||
range: self.range,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for StaticTextSlice {
|
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
pub enum ContainsNewlines {
|
||||||
std::write!(f, "StaticTextSlice({})", &self.text[self.range])
|
/// The string contains newline characters
|
||||||
|
Yes,
|
||||||
|
/// The string contains no newline characters
|
||||||
|
No,
|
||||||
|
|
||||||
|
/// The string may contain newline characters, search the string to determine if there are any newlines.
|
||||||
|
Detect,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Debug)]
|
||||||
|
pub struct SourceTextSliceBuilder {
|
||||||
|
range: TextRange,
|
||||||
|
new_lines: ContainsNewlines,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Context> Format<Context> for SourceTextSliceBuilder
|
||||||
|
where
|
||||||
|
Context: FormatContext,
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut Formatter<Context>) -> FormatResult<()> {
|
||||||
|
let source_code = f.context().source_code();
|
||||||
|
let slice = source_code.slice(self.range);
|
||||||
|
debug_assert_no_newlines(slice.text(source_code));
|
||||||
|
|
||||||
|
let contains_newlines = match self.new_lines {
|
||||||
|
ContainsNewlines::Yes => {
|
||||||
|
debug_assert!(
|
||||||
|
slice.text(source_code).contains('\n'),
|
||||||
|
"Text contains no new line characters but the caller specified that it does."
|
||||||
|
);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
ContainsNewlines::No => {
|
||||||
|
debug_assert!(
|
||||||
|
!slice.text(source_code).contains('\n'),
|
||||||
|
"Text contains new line characters but the caller specified that it does not."
|
||||||
|
);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
ContainsNewlines::Detect => slice.text(source_code).contains('\n'),
|
||||||
|
};
|
||||||
|
|
||||||
|
f.write_element(FormatElement::SourceCodeSlice {
|
||||||
|
slice,
|
||||||
|
contains_newlines,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,9 @@ use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::format_element::tag::{LabelId, Tag};
|
use crate::format_element::tag::{LabelId, Tag};
|
||||||
|
use crate::source_code::SourceCodeSlice;
|
||||||
use crate::TagKind;
|
use crate::TagKind;
|
||||||
use ruff_text_size::{TextRange, TextSize};
|
use ruff_text_size::TextSize;
|
||||||
|
|
||||||
/// Language agnostic IR for formatting source code.
|
/// Language agnostic IR for formatting source code.
|
||||||
///
|
///
|
||||||
|
@ -39,8 +40,12 @@ pub enum FormatElement {
|
||||||
text: Box<str>,
|
text: Box<str>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Token constructed by slicing a defined range from a static string.
|
/// Text that gets emitted as it is in the source code. Optimized to avoid any allocations.
|
||||||
StaticTextSlice { text: Rc<str>, range: TextRange },
|
SourceCodeSlice {
|
||||||
|
slice: SourceCodeSlice,
|
||||||
|
/// Whether the string contains any new line characters
|
||||||
|
contains_newlines: bool,
|
||||||
|
},
|
||||||
|
|
||||||
/// Prevents that line suffixes move past this boundary. Forces the printer to print any pending
|
/// Prevents that line suffixes move past this boundary. Forces the printer to print any pending
|
||||||
/// line suffixes, potentially by inserting a hard line break.
|
/// line suffixes, potentially by inserting a hard line break.
|
||||||
|
@ -70,9 +75,14 @@ impl std::fmt::Debug for FormatElement {
|
||||||
FormatElement::DynamicText { text, .. } => {
|
FormatElement::DynamicText { text, .. } => {
|
||||||
fmt.debug_tuple("DynamicText").field(text).finish()
|
fmt.debug_tuple("DynamicText").field(text).finish()
|
||||||
}
|
}
|
||||||
FormatElement::StaticTextSlice { text, .. } => {
|
FormatElement::SourceCodeSlice {
|
||||||
fmt.debug_tuple("Text").field(text).finish()
|
slice,
|
||||||
}
|
contains_newlines,
|
||||||
|
} => fmt
|
||||||
|
.debug_tuple("Text")
|
||||||
|
.field(slice)
|
||||||
|
.field(contains_newlines)
|
||||||
|
.finish(),
|
||||||
FormatElement::LineSuffixBoundary => write!(fmt, "LineSuffixBoundary"),
|
FormatElement::LineSuffixBoundary => write!(fmt, "LineSuffixBoundary"),
|
||||||
FormatElement::BestFitting(best_fitting) => {
|
FormatElement::BestFitting(best_fitting) => {
|
||||||
fmt.debug_tuple("BestFitting").field(&best_fitting).finish()
|
fmt.debug_tuple("BestFitting").field(&best_fitting).finish()
|
||||||
|
@ -221,7 +231,7 @@ impl FormatElement {
|
||||||
pub const fn is_text(&self) -> bool {
|
pub const fn is_text(&self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
self,
|
self,
|
||||||
FormatElement::StaticTextSlice { .. }
|
FormatElement::SourceCodeSlice { .. }
|
||||||
| FormatElement::DynamicText { .. }
|
| FormatElement::DynamicText { .. }
|
||||||
| FormatElement::StaticText { .. }
|
| FormatElement::StaticText { .. }
|
||||||
)
|
)
|
||||||
|
@ -240,7 +250,9 @@ impl FormatElements for FormatElement {
|
||||||
FormatElement::Line(line_mode) => matches!(line_mode, LineMode::Hard | LineMode::Empty),
|
FormatElement::Line(line_mode) => matches!(line_mode, LineMode::Hard | LineMode::Empty),
|
||||||
FormatElement::StaticText { text } => text.contains('\n'),
|
FormatElement::StaticText { text } => text.contains('\n'),
|
||||||
FormatElement::DynamicText { text, .. } => text.contains('\n'),
|
FormatElement::DynamicText { text, .. } => text.contains('\n'),
|
||||||
FormatElement::StaticTextSlice { text, range } => text[*range].contains('\n'),
|
FormatElement::SourceCodeSlice {
|
||||||
|
contains_newlines, ..
|
||||||
|
} => *contains_newlines,
|
||||||
FormatElement::Interned(interned) => interned.will_break(),
|
FormatElement::Interned(interned) => interned.will_break(),
|
||||||
// Traverse into the most flat version because the content is guaranteed to expand when even
|
// Traverse into the most flat version because the content is guaranteed to expand when even
|
||||||
// the most flat version contains some content that forces a break.
|
// the most flat version contains some content that forces a break.
|
||||||
|
@ -380,20 +392,19 @@ mod sizes {
|
||||||
// be recomputed at a later point in time?
|
// be recomputed at a later point in time?
|
||||||
// You reduced the size of a format element? Excellent work!
|
// You reduced the size of a format element? Excellent work!
|
||||||
|
|
||||||
use crate::format_element::BestFitting;
|
|
||||||
use crate::prelude::tag::VerbatimKind;
|
|
||||||
use crate::prelude::Interned;
|
|
||||||
use ruff_text_size::TextRange;
|
|
||||||
use static_assertions::assert_eq_size;
|
use static_assertions::assert_eq_size;
|
||||||
|
|
||||||
assert_eq_size!(TextRange, [u8; 8]);
|
assert_eq_size!(ruff_text_size::TextRange, [u8; 8]);
|
||||||
assert_eq_size!(VerbatimKind, [u8; 8]);
|
assert_eq_size!(crate::prelude::tag::VerbatimKind, [u8; 8]);
|
||||||
assert_eq_size!(Interned, [u8; 16]);
|
assert_eq_size!(crate::prelude::Interned, [u8; 16]);
|
||||||
assert_eq_size!(BestFitting, [u8; 16]);
|
assert_eq_size!(crate::format_element::BestFitting, [u8; 16]);
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
assert_eq_size!(crate::SourceCodeSlice, [u8; 8]);
|
||||||
|
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
assert_eq_size!(crate::format_element::Tag, [u8; 16]);
|
assert_eq_size!(crate::format_element::Tag, [u8; 16]);
|
||||||
|
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
assert_eq_size!(crate::FormatElement, [u8; 32]);
|
assert_eq_size!(crate::FormatElement, [u8; 24]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ use crate::format_element::tag::DedentMode;
|
||||||
use crate::prelude::tag::GroupMode;
|
use crate::prelude::tag::GroupMode;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::printer::LineEnding;
|
use crate::printer::LineEnding;
|
||||||
|
use crate::source_code::SourceCode;
|
||||||
use crate::{format, write};
|
use crate::{format, write};
|
||||||
use crate::{
|
use crate::{
|
||||||
BufferExtensions, Format, FormatContext, FormatElement, FormatOptions, FormatResult, Formatter,
|
BufferExtensions, Format, FormatContext, FormatElement, FormatOptions, FormatResult, Formatter,
|
||||||
|
@ -80,7 +81,9 @@ impl Document {
|
||||||
}
|
}
|
||||||
FormatElement::StaticText { text } => text.contains('\n'),
|
FormatElement::StaticText { text } => text.contains('\n'),
|
||||||
FormatElement::DynamicText { text, .. } => text.contains('\n'),
|
FormatElement::DynamicText { text, .. } => text.contains('\n'),
|
||||||
FormatElement::StaticTextSlice { text, range } => text[*range].contains('\n'),
|
FormatElement::SourceCodeSlice {
|
||||||
|
contains_newlines, ..
|
||||||
|
} => *contains_newlines,
|
||||||
FormatElement::ExpandParent
|
FormatElement::ExpandParent
|
||||||
| FormatElement::Line(LineMode::Hard | LineMode::Empty) => true,
|
| FormatElement::Line(LineMode::Hard | LineMode::Empty) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -99,6 +102,13 @@ impl Document {
|
||||||
let mut interned: FxHashMap<&Interned, bool> = FxHashMap::default();
|
let mut interned: FxHashMap<&Interned, bool> = FxHashMap::default();
|
||||||
propagate_expands(self, &mut enclosing, &mut interned);
|
propagate_expands(self, &mut enclosing, &mut interned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn display<'a>(&'a self, source_code: SourceCode<'a>) -> DisplayDocument {
|
||||||
|
DisplayDocument {
|
||||||
|
elements: self.elements.as_slice(),
|
||||||
|
source_code,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec<FormatElement>> for Document {
|
impl From<Vec<FormatElement>> for Document {
|
||||||
|
@ -115,9 +125,14 @@ impl Deref for Document {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for Document {
|
pub struct DisplayDocument<'a> {
|
||||||
|
elements: &'a [FormatElement],
|
||||||
|
source_code: SourceCode<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for DisplayDocument<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let formatted = format!(IrFormatContext::default(), [self.elements.as_slice()])
|
let formatted = format!(IrFormatContext::new(self.source_code), [self.elements])
|
||||||
.expect("Formatting not to throw any FormatErrors");
|
.expect("Formatting not to throw any FormatErrors");
|
||||||
|
|
||||||
f.write_str(
|
f.write_str(
|
||||||
|
@ -129,18 +144,33 @@ impl std::fmt::Display for Document {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct IrFormatContext {
|
struct IrFormatContext<'a> {
|
||||||
/// The interned elements that have been printed to this point
|
/// The interned elements that have been printed to this point
|
||||||
printed_interned_elements: HashMap<Interned, usize>,
|
printed_interned_elements: HashMap<Interned, usize>,
|
||||||
|
|
||||||
|
source_code: SourceCode<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FormatContext for IrFormatContext {
|
impl<'a> IrFormatContext<'a> {
|
||||||
|
fn new(source_code: SourceCode<'a>) -> Self {
|
||||||
|
Self {
|
||||||
|
source_code,
|
||||||
|
printed_interned_elements: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormatContext for IrFormatContext<'_> {
|
||||||
type Options = IrFormatOptions;
|
type Options = IrFormatOptions;
|
||||||
|
|
||||||
fn options(&self) -> &Self::Options {
|
fn options(&self) -> &Self::Options {
|
||||||
&IrFormatOptions
|
&IrFormatOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn source_code(&self) -> SourceCode {
|
||||||
|
self.source_code
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
|
@ -165,7 +195,7 @@ impl FormatOptions for IrFormatOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<IrFormatContext> for &[FormatElement] {
|
impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
||||||
fn fmt(&self, f: &mut Formatter<IrFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<IrFormatContext>) -> FormatResult<()> {
|
||||||
use Tag::*;
|
use Tag::*;
|
||||||
|
|
||||||
|
@ -189,7 +219,7 @@ impl Format<IrFormatContext> for &[FormatElement] {
|
||||||
element @ FormatElement::Space
|
element @ FormatElement::Space
|
||||||
| element @ FormatElement::StaticText { .. }
|
| element @ FormatElement::StaticText { .. }
|
||||||
| element @ FormatElement::DynamicText { .. }
|
| element @ FormatElement::DynamicText { .. }
|
||||||
| element @ FormatElement::StaticTextSlice { .. } => {
|
| element @ FormatElement::SourceCodeSlice { .. } => {
|
||||||
if !in_text {
|
if !in_text {
|
||||||
write!(f, [text("\"")])?;
|
write!(f, [text("\"")])?;
|
||||||
}
|
}
|
||||||
|
@ -489,7 +519,7 @@ impl Format<IrFormatContext> for &[FormatElement] {
|
||||||
|
|
||||||
struct ContentArrayStart;
|
struct ContentArrayStart;
|
||||||
|
|
||||||
impl Format<IrFormatContext> for ContentArrayStart {
|
impl Format<IrFormatContext<'_>> for ContentArrayStart {
|
||||||
fn fmt(&self, f: &mut Formatter<IrFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<IrFormatContext>) -> FormatResult<()> {
|
||||||
use Tag::*;
|
use Tag::*;
|
||||||
|
|
||||||
|
@ -505,7 +535,7 @@ impl Format<IrFormatContext> for ContentArrayStart {
|
||||||
|
|
||||||
struct ContentArrayEnd;
|
struct ContentArrayEnd;
|
||||||
|
|
||||||
impl Format<IrFormatContext> for ContentArrayEnd {
|
impl Format<IrFormatContext<'_>> for ContentArrayEnd {
|
||||||
fn fmt(&self, f: &mut Formatter<IrFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<IrFormatContext>) -> FormatResult<()> {
|
||||||
use Tag::*;
|
use Tag::*;
|
||||||
f.write_elements([
|
f.write_elements([
|
||||||
|
@ -615,8 +645,9 @@ impl FormatElements for [FormatElement] {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::SimpleFormatContext;
|
|
||||||
use crate::{format, format_args, write};
|
use crate::{format, format_args, write};
|
||||||
|
use crate::{SimpleFormatContext, SourceCode};
|
||||||
|
use ruff_text_size::{TextRange, TextSize};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn display_elements() {
|
fn display_elements() {
|
||||||
|
@ -641,7 +672,51 @@ mod tests {
|
||||||
let document = formatted.into_document();
|
let document = formatted.into_document();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&std::format!("{document}"),
|
&std::format!("{}", document.display(SourceCode::default())),
|
||||||
|
r#"[
|
||||||
|
group([
|
||||||
|
"(",
|
||||||
|
indent([
|
||||||
|
soft_line_break,
|
||||||
|
"Some longer content That should ultimately break"
|
||||||
|
]),
|
||||||
|
soft_line_break
|
||||||
|
])
|
||||||
|
]"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn display_elements_with_source_text_slice() {
|
||||||
|
let source_code = "Some longer content\nThat should ultimately break";
|
||||||
|
let formatted = format!(
|
||||||
|
SimpleFormatContext::default().with_source_code(source_code),
|
||||||
|
[format_with(|f| {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
[group(&format_args![
|
||||||
|
text("("),
|
||||||
|
soft_block_indent(&format_args![
|
||||||
|
source_text_slice(
|
||||||
|
TextRange::at(TextSize::new(0), TextSize::new(19)),
|
||||||
|
ContainsNewlines::No
|
||||||
|
),
|
||||||
|
space(),
|
||||||
|
source_text_slice(
|
||||||
|
TextRange::at(TextSize::new(20), TextSize::new(28)),
|
||||||
|
ContainsNewlines::No
|
||||||
|
),
|
||||||
|
])
|
||||||
|
])]
|
||||||
|
)
|
||||||
|
})]
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let document = formatted.into_document();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
&std::format!("{}", document.display(SourceCode::new(source_code))),
|
||||||
r#"[
|
r#"[
|
||||||
group([
|
group([
|
||||||
"(",
|
"(",
|
||||||
|
@ -677,7 +752,7 @@ mod tests {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&std::format!("{document}"),
|
&std::format!("{}", document.display(SourceCode::default())),
|
||||||
r#"[
|
r#"[
|
||||||
"[",
|
"[",
|
||||||
group([
|
group([
|
||||||
|
|
|
@ -33,6 +33,7 @@ pub mod group_id;
|
||||||
pub mod macros;
|
pub mod macros;
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
pub mod printer;
|
pub mod printer;
|
||||||
|
mod source_code;
|
||||||
|
|
||||||
use crate::formatter::Formatter;
|
use crate::formatter::Formatter;
|
||||||
use crate::group_id::UniqueGroupIdBuilder;
|
use crate::group_id::UniqueGroupIdBuilder;
|
||||||
|
@ -47,6 +48,7 @@ pub use buffer::{
|
||||||
VecBuffer,
|
VecBuffer,
|
||||||
};
|
};
|
||||||
pub use builders::BestFitting;
|
pub use builders::BestFitting;
|
||||||
|
pub use source_code::{SourceCode, SourceCodeSlice};
|
||||||
|
|
||||||
pub use crate::diagnostics::{ActualStart, FormatError, InvalidDocumentError, PrintError};
|
pub use crate::diagnostics::{ActualStart, FormatError, InvalidDocumentError, PrintError};
|
||||||
pub use format_element::{normalize_newlines, FormatElement, LINE_TERMINATORS};
|
pub use format_element::{normalize_newlines, FormatElement, LINE_TERMINATORS};
|
||||||
|
@ -202,6 +204,9 @@ pub trait FormatContext {
|
||||||
|
|
||||||
/// Returns the formatting options
|
/// Returns the formatting options
|
||||||
fn options(&self) -> &Self::Options;
|
fn options(&self) -> &Self::Options;
|
||||||
|
|
||||||
|
/// Returns the source code from the document that gets formatted.
|
||||||
|
fn source_code(&self) -> SourceCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Options customizing how the source code should be formatted.
|
/// Options customizing how the source code should be formatted.
|
||||||
|
@ -219,11 +224,20 @@ pub trait FormatOptions {
|
||||||
#[derive(Debug, Default, Eq, PartialEq)]
|
#[derive(Debug, Default, Eq, PartialEq)]
|
||||||
pub struct SimpleFormatContext {
|
pub struct SimpleFormatContext {
|
||||||
options: SimpleFormatOptions,
|
options: SimpleFormatOptions,
|
||||||
|
source_code: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SimpleFormatContext {
|
impl SimpleFormatContext {
|
||||||
pub fn new(options: SimpleFormatOptions) -> Self {
|
pub fn new(options: SimpleFormatOptions) -> Self {
|
||||||
Self { options }
|
Self {
|
||||||
|
options,
|
||||||
|
source_code: String::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_source_code(mut self, code: &str) -> Self {
|
||||||
|
self.source_code = String::from(code);
|
||||||
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,9 +247,13 @@ impl FormatContext for SimpleFormatContext {
|
||||||
fn options(&self) -> &Self::Options {
|
fn options(&self) -> &Self::Options {
|
||||||
&self.options
|
&self.options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn source_code(&self) -> SourceCode {
|
||||||
|
SourceCode::new(&self.source_code)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Eq, PartialEq)]
|
#[derive(Debug, Default, Eq, PartialEq, Clone)]
|
||||||
pub struct SimpleFormatOptions {
|
pub struct SimpleFormatOptions {
|
||||||
pub indent_style: IndentStyle,
|
pub indent_style: IndentStyle,
|
||||||
pub line_width: LineWidth,
|
pub line_width: LineWidth,
|
||||||
|
@ -302,15 +320,18 @@ where
|
||||||
Context: FormatContext,
|
Context: FormatContext,
|
||||||
{
|
{
|
||||||
pub fn print(&self) -> PrintResult<Printed> {
|
pub fn print(&self) -> PrintResult<Printed> {
|
||||||
|
let source_code = self.context.source_code();
|
||||||
let print_options = self.context.options().as_print_options();
|
let print_options = self.context.options().as_print_options();
|
||||||
let printed = Printer::new(print_options).print(&self.document)?;
|
let printed = Printer::new(source_code, print_options).print(&self.document)?;
|
||||||
|
|
||||||
Ok(printed)
|
Ok(printed)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_with_indent(&self, indent: u16) -> PrintResult<Printed> {
|
pub fn print_with_indent(&self, indent: u16) -> PrintResult<Printed> {
|
||||||
|
let source_code = self.context.source_code();
|
||||||
let print_options = self.context.options().as_print_options();
|
let print_options = self.context.options().as_print_options();
|
||||||
let printed = Printer::new(print_options).print_with_indent(&self.document, indent)?;
|
let printed =
|
||||||
|
Printer::new(source_code, print_options).print_with_indent(&self.document, indent)?;
|
||||||
|
|
||||||
Ok(printed)
|
Ok(printed)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ use crate::printer::line_suffixes::{LineSuffixEntry, LineSuffixes};
|
||||||
use crate::printer::queue::{
|
use crate::printer::queue::{
|
||||||
AllPredicate, FitsEndPredicate, FitsQueue, PrintQueue, Queue, SingleEntryPredicate,
|
AllPredicate, FitsEndPredicate, FitsQueue, PrintQueue, Queue, SingleEntryPredicate,
|
||||||
};
|
};
|
||||||
|
use crate::source_code::SourceCode;
|
||||||
use drop_bomb::DebugDropBomb;
|
use drop_bomb::DebugDropBomb;
|
||||||
use ruff_text_size::{TextLen, TextSize};
|
use ruff_text_size::{TextLen, TextSize};
|
||||||
use std::num::NonZeroU8;
|
use std::num::NonZeroU8;
|
||||||
|
@ -32,12 +33,14 @@ use unicode_width::UnicodeWidthChar;
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Printer<'a> {
|
pub struct Printer<'a> {
|
||||||
options: PrinterOptions,
|
options: PrinterOptions,
|
||||||
|
source_code: SourceCode<'a>,
|
||||||
state: PrinterState<'a>,
|
state: PrinterState<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Printer<'a> {
|
impl<'a> Printer<'a> {
|
||||||
pub fn new(options: PrinterOptions) -> Self {
|
pub fn new(source_code: SourceCode<'a>, options: PrinterOptions) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
source_code,
|
||||||
options,
|
options,
|
||||||
state: PrinterState::default(),
|
state: PrinterState::default(),
|
||||||
}
|
}
|
||||||
|
@ -96,7 +99,10 @@ impl<'a> Printer<'a> {
|
||||||
|
|
||||||
FormatElement::StaticText { text } => self.print_text(text, None),
|
FormatElement::StaticText { text } => self.print_text(text, None),
|
||||||
FormatElement::DynamicText { text } => self.print_text(text, None),
|
FormatElement::DynamicText { text } => self.print_text(text, None),
|
||||||
FormatElement::StaticTextSlice { text, range } => self.print_text(&text[*range], None),
|
FormatElement::SourceCodeSlice { slice, .. } => {
|
||||||
|
let text = slice.text(self.source_code);
|
||||||
|
self.print_text(text, Some(slice.range()))
|
||||||
|
}
|
||||||
FormatElement::Line(line_mode) => {
|
FormatElement::Line(line_mode) => {
|
||||||
if args.mode().is_flat()
|
if args.mode().is_flat()
|
||||||
&& matches!(line_mode, LineMode::Soft | LineMode::SoftOrSpace)
|
&& matches!(line_mode, LineMode::Soft | LineMode::SoftOrSpace)
|
||||||
|
@ -994,8 +1000,9 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> {
|
||||||
|
|
||||||
FormatElement::StaticText { text } => return Ok(self.fits_text(text)),
|
FormatElement::StaticText { text } => return Ok(self.fits_text(text)),
|
||||||
FormatElement::DynamicText { text, .. } => return Ok(self.fits_text(text)),
|
FormatElement::DynamicText { text, .. } => return Ok(self.fits_text(text)),
|
||||||
FormatElement::StaticTextSlice { text, range } => {
|
FormatElement::SourceCodeSlice { slice, .. } => {
|
||||||
return Ok(self.fits_text(&text[*range]))
|
let text = slice.text(self.printer.source_code);
|
||||||
|
return Ok(self.fits_text(text));
|
||||||
}
|
}
|
||||||
FormatElement::LineSuffixBoundary => {
|
FormatElement::LineSuffixBoundary => {
|
||||||
if self.state.has_line_suffix {
|
if self.state.has_line_suffix {
|
||||||
|
@ -1256,6 +1263,7 @@ struct FitsState {
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::printer::{LineEnding, PrintWidth, Printer, PrinterOptions};
|
use crate::printer::{LineEnding, PrintWidth, Printer, PrinterOptions};
|
||||||
|
use crate::source_code::SourceCode;
|
||||||
use crate::{format_args, write, Document, FormatState, IndentStyle, Printed, VecBuffer};
|
use crate::{format_args, write, Document, FormatState, IndentStyle, Printed, VecBuffer};
|
||||||
|
|
||||||
fn format(root: &dyn Format<SimpleFormatContext>) -> Printed {
|
fn format(root: &dyn Format<SimpleFormatContext>) -> Printed {
|
||||||
|
@ -1274,7 +1282,7 @@ mod tests {
|
||||||
) -> Printed {
|
) -> Printed {
|
||||||
let formatted = crate::format!(SimpleFormatContext::default(), [root]).unwrap();
|
let formatted = crate::format!(SimpleFormatContext::default(), [root]).unwrap();
|
||||||
|
|
||||||
Printer::new(options)
|
Printer::new(SourceCode::default(), options)
|
||||||
.print(formatted.document())
|
.print(formatted.document())
|
||||||
.expect("Document to be valid")
|
.expect("Document to be valid")
|
||||||
}
|
}
|
||||||
|
@ -1510,9 +1518,12 @@ two lines`,
|
||||||
|
|
||||||
let document = Document::from(buffer.into_vec());
|
let document = Document::from(buffer.into_vec());
|
||||||
|
|
||||||
let printed = Printer::new(PrinterOptions::default().with_print_width(PrintWidth::new(10)))
|
let printed = Printer::new(
|
||||||
.print(&document)
|
SourceCode::default(),
|
||||||
.unwrap();
|
PrinterOptions::default().with_print_width(PrintWidth::new(10)),
|
||||||
|
)
|
||||||
|
.print(&document)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
printed.as_code(),
|
printed.as_code(),
|
||||||
|
|
81
crates/ruff_formatter/src/source_code.rs
Normal file
81
crates/ruff_formatter/src/source_code.rs
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
use ruff_text_size::TextRange;
|
||||||
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
|
/// The source code of a document that gets formatted
|
||||||
|
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Default)]
|
||||||
|
pub struct SourceCode<'a> {
|
||||||
|
text: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> SourceCode<'a> {
|
||||||
|
pub fn new(text: &'a str) -> Self {
|
||||||
|
Self { text }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn slice(self, range: TextRange) -> SourceCodeSlice {
|
||||||
|
assert!(
|
||||||
|
usize::from(range.end()) <= self.text.len(),
|
||||||
|
"Range end {:?} out of bounds {}.",
|
||||||
|
range.end(),
|
||||||
|
self.text.len()
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
self.text.is_char_boundary(usize::from(range.start())),
|
||||||
|
"The range start position {:?} is not a char boundary.",
|
||||||
|
range.start()
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
self.text.is_char_boundary(usize::from(range.end())),
|
||||||
|
"The range end position {:?} is not a char boundary.",
|
||||||
|
range.end()
|
||||||
|
);
|
||||||
|
|
||||||
|
SourceCodeSlice {
|
||||||
|
range,
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
text: String::from(&self.text[range]).into_boxed_str(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for SourceCode<'_> {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_tuple("SourceCode").field(&self.text).finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A slice into the source text of a document.
|
||||||
|
///
|
||||||
|
/// It only stores the range in production builds for a more compact representation, but it
|
||||||
|
/// keeps the original text in debug builds for better developer experience.
|
||||||
|
#[derive(Clone, Eq, PartialEq)]
|
||||||
|
pub struct SourceCodeSlice {
|
||||||
|
range: TextRange,
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
text: Box<str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SourceCodeSlice {
|
||||||
|
/// Returns the slice's text.
|
||||||
|
pub fn text<'a>(&self, code: SourceCode<'a>) -> &'a str {
|
||||||
|
assert!(usize::from(self.range.end()) <= code.text.len(), "The range of this slice is out of bounds. Did you provide the correct source code for this slice?");
|
||||||
|
&code.text[self.range]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn range(&self) -> TextRange {
|
||||||
|
self.range
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for SourceCodeSlice {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let mut tuple = f.debug_tuple("SourceCodeSlice");
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
tuple.field(&self.text);
|
||||||
|
|
||||||
|
tuple.field(&self.range).finish()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,36 +1,34 @@
|
||||||
use std::rc::Rc;
|
use ruff_formatter::{FormatContext, SimpleFormatOptions, SourceCode};
|
||||||
|
|
||||||
use ruff_formatter::{FormatContext, SimpleFormatOptions};
|
|
||||||
use ruff_python_ast::source_code::Locator;
|
use ruff_python_ast::source_code::Locator;
|
||||||
|
|
||||||
pub struct ASTFormatContext {
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct ASTFormatContext<'source> {
|
||||||
options: SimpleFormatOptions,
|
options: SimpleFormatOptions,
|
||||||
contents: Rc<str>,
|
contents: &'source str,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ASTFormatContext {
|
impl<'source> ASTFormatContext<'source> {
|
||||||
pub fn new(options: SimpleFormatOptions, contents: &str) -> Self {
|
pub fn new(options: SimpleFormatOptions, contents: &'source str) -> Self {
|
||||||
Self {
|
Self { options, contents }
|
||||||
options,
|
}
|
||||||
contents: Rc::from(contents),
|
|
||||||
}
|
pub fn contents(&self) -> &'source str {
|
||||||
|
self.contents
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn locator(&self) -> Locator<'source> {
|
||||||
|
Locator::new(self.contents)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FormatContext for ASTFormatContext {
|
impl FormatContext for ASTFormatContext<'_> {
|
||||||
type Options = SimpleFormatOptions;
|
type Options = SimpleFormatOptions;
|
||||||
|
|
||||||
fn options(&self) -> &Self::Options {
|
fn options(&self) -> &Self::Options {
|
||||||
&self.options
|
&self.options
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl ASTFormatContext {
|
fn source_code(&self) -> SourceCode {
|
||||||
pub fn contents(&self) -> Rc<str> {
|
SourceCode::new(self.contents)
|
||||||
self.contents.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn locator(&self) -> Locator {
|
|
||||||
Locator::new(&self.contents)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub struct FormatAlias<'a> {
|
||||||
item: &'a Alias,
|
item: &'a Alias,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsFormat<ASTFormatContext> for Alias {
|
impl AsFormat<ASTFormatContext<'_>> for Alias {
|
||||||
type Format<'a> = FormatAlias<'a>;
|
type Format<'a> = FormatAlias<'a>;
|
||||||
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
@ -18,7 +18,7 @@ impl AsFormat<ASTFormatContext> for Alias {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for FormatAlias<'_> {
|
impl Format<ASTFormatContext<'_>> for FormatAlias<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let alias = self.item;
|
let alias = self.item;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub struct FormatArg<'a> {
|
||||||
item: &'a Arg,
|
item: &'a Arg,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsFormat<ASTFormatContext> for Arg {
|
impl AsFormat<ASTFormatContext<'_>> for Arg {
|
||||||
type Format<'a> = FormatArg<'a>;
|
type Format<'a> = FormatArg<'a>;
|
||||||
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
@ -18,7 +18,7 @@ impl AsFormat<ASTFormatContext> for Arg {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for FormatArg<'_> {
|
impl Format<ASTFormatContext<'_>> for FormatArg<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let arg = self.item;
|
let arg = self.item;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub struct FormatArguments<'a> {
|
||||||
item: &'a Arguments,
|
item: &'a Arguments,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsFormat<ASTFormatContext> for Arguments {
|
impl AsFormat<ASTFormatContext<'_>> for Arguments {
|
||||||
type Format<'a> = FormatArguments<'a>;
|
type Format<'a> = FormatArguments<'a>;
|
||||||
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
@ -17,7 +17,7 @@ impl AsFormat<ASTFormatContext> for Arguments {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for FormatArguments<'_> {
|
impl Format<ASTFormatContext<'_>> for FormatArguments<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let args = self.item;
|
let args = self.item;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub struct FormatBoolOp<'a> {
|
||||||
item: &'a BoolOp,
|
item: &'a BoolOp,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsFormat<ASTFormatContext> for BoolOp {
|
impl AsFormat<ASTFormatContext<'_>> for BoolOp {
|
||||||
type Format<'a> = FormatBoolOp<'a>;
|
type Format<'a> = FormatBoolOp<'a>;
|
||||||
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
@ -18,7 +18,7 @@ impl AsFormat<ASTFormatContext> for BoolOp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for FormatBoolOp<'_> {
|
impl Format<ASTFormatContext<'_>> for FormatBoolOp<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let bool_op = self.item;
|
let bool_op = self.item;
|
||||||
write!(f, [leading_comments(bool_op)])?;
|
write!(f, [leading_comments(bool_op)])?;
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub(crate) struct Block<'a> {
|
||||||
body: &'a Body,
|
body: &'a Body,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for Block<'_> {
|
impl Format<ASTFormatContext<'_>> for Block<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
for (i, stmt) in self.body.iter().enumerate() {
|
for (i, stmt) in self.body.iter().enumerate() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
|
@ -28,7 +28,7 @@ impl Format<ASTFormatContext> for Block<'_> {
|
||||||
write!(f, [empty_line()])?;
|
write!(f, [empty_line()])?;
|
||||||
}
|
}
|
||||||
TriviaKind::OwnLineComment(range) => {
|
TriviaKind::OwnLineComment(range) => {
|
||||||
write!(f, [literal(range), hard_line_break()])?;
|
write!(f, [literal(range, ContainsNewlines::No), hard_line_break()])?;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ pub(crate) struct Statements<'a> {
|
||||||
suite: &'a [Stmt],
|
suite: &'a [Stmt],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for Statements<'_> {
|
impl Format<ASTFormatContext<'_>> for Statements<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
for (i, stmt) in self.suite.iter().enumerate() {
|
for (i, stmt) in self.suite.iter().enumerate() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
|
@ -70,20 +70,18 @@ pub(crate) struct Literal {
|
||||||
range: TextRange,
|
range: TextRange,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for Literal {
|
impl Format<ASTFormatContext<'_>> for Literal {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let text = f.context().contents();
|
source_text_slice(self.range, ContainsNewlines::Detect).fmt(f)
|
||||||
|
|
||||||
f.write_element(FormatElement::StaticTextSlice {
|
|
||||||
text,
|
|
||||||
range: self.range,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) const fn literal(range: TextRange) -> Literal {
|
pub(crate) const fn literal(
|
||||||
Literal { range }
|
range: TextRange,
|
||||||
|
newlines: ContainsNewlines,
|
||||||
|
) -> SourceTextSliceBuilder {
|
||||||
|
source_text_slice(range, newlines)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) const fn join_names(names: &[String]) -> JoinNames {
|
pub(crate) const fn join_names(names: &[String]) -> JoinNames {
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub struct FormatCmpOp<'a> {
|
||||||
item: &'a CmpOp,
|
item: &'a CmpOp,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsFormat<ASTFormatContext> for CmpOp {
|
impl AsFormat<ASTFormatContext<'_>> for CmpOp {
|
||||||
type Format<'a> = FormatCmpOp<'a>;
|
type Format<'a> = FormatCmpOp<'a>;
|
||||||
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
@ -18,7 +18,7 @@ impl AsFormat<ASTFormatContext> for CmpOp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for FormatCmpOp<'_> {
|
impl Format<ASTFormatContext<'_>> for FormatCmpOp<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let cmp_op = self.item;
|
let cmp_op = self.item;
|
||||||
write!(f, [leading_comments(cmp_op)])?;
|
write!(f, [leading_comments(cmp_op)])?;
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub(crate) struct LeadingComments<'a, T> {
|
||||||
item: &'a Attributed<T>,
|
item: &'a Attributed<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Format<ASTFormatContext> for LeadingComments<'_, T> {
|
impl<T> Format<ASTFormatContext<'_>> for LeadingComments<'_, T> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
for trivia in &self.item.trivia {
|
for trivia in &self.item.trivia {
|
||||||
if trivia.relationship.is_leading() {
|
if trivia.relationship.is_leading() {
|
||||||
|
@ -20,7 +20,7 @@ impl<T> Format<ASTFormatContext> for LeadingComments<'_, T> {
|
||||||
write!(f, [empty_line()])?;
|
write!(f, [empty_line()])?;
|
||||||
}
|
}
|
||||||
TriviaKind::OwnLineComment(range) => {
|
TriviaKind::OwnLineComment(range) => {
|
||||||
write!(f, [literal(range), hard_line_break()])?;
|
write!(f, [literal(range, ContainsNewlines::No), hard_line_break()])?;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ pub(crate) struct TrailingComments<'a, T> {
|
||||||
item: &'a Attributed<T>,
|
item: &'a Attributed<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Format<ASTFormatContext> for TrailingComments<'_, T> {
|
impl<T> Format<ASTFormatContext<'_>> for TrailingComments<'_, T> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
for trivia in &self.item.trivia {
|
for trivia in &self.item.trivia {
|
||||||
if trivia.relationship.is_trailing() {
|
if trivia.relationship.is_trailing() {
|
||||||
|
@ -49,7 +49,7 @@ impl<T> Format<ASTFormatContext> for TrailingComments<'_, T> {
|
||||||
write!(f, [empty_line()])?;
|
write!(f, [empty_line()])?;
|
||||||
}
|
}
|
||||||
TriviaKind::OwnLineComment(range) => {
|
TriviaKind::OwnLineComment(range) => {
|
||||||
write!(f, [literal(range), hard_line_break()])?;
|
write!(f, [literal(range, ContainsNewlines::No), hard_line_break()])?;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ pub(crate) struct EndOfLineComments<'a, T> {
|
||||||
item: &'a Attributed<T>,
|
item: &'a Attributed<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Format<ASTFormatContext> for EndOfLineComments<'_, T> {
|
impl<T> Format<ASTFormatContext<'_>> for EndOfLineComments<'_, T> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
for range in self
|
for range in self
|
||||||
|
@ -81,7 +81,7 @@ impl<T> Format<ASTFormatContext> for EndOfLineComments<'_, T> {
|
||||||
if std::mem::take(&mut first) {
|
if std::mem::take(&mut first) {
|
||||||
write!(f, [line_suffix(&text(" "))])?;
|
write!(f, [line_suffix(&text(" "))])?;
|
||||||
}
|
}
|
||||||
write!(f, [line_suffix(&literal(range))])?;
|
write!(f, [line_suffix(&literal(range, ContainsNewlines::No))])?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -97,13 +97,13 @@ pub(crate) struct DanglingComments<'a, T> {
|
||||||
item: &'a Attributed<T>,
|
item: &'a Attributed<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Format<ASTFormatContext> for DanglingComments<'_, T> {
|
impl<T> Format<ASTFormatContext<'_>> for DanglingComments<'_, T> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
for trivia in &self.item.trivia {
|
for trivia in &self.item.trivia {
|
||||||
if trivia.relationship.is_dangling() {
|
if trivia.relationship.is_dangling() {
|
||||||
if let TriviaKind::OwnLineComment(range) = trivia.kind {
|
if let TriviaKind::OwnLineComment(range) = trivia.kind {
|
||||||
write!(f, [hard_line_break()])?;
|
write!(f, [hard_line_break()])?;
|
||||||
write!(f, [literal(range)])?;
|
write!(f, [literal(range, ContainsNewlines::No)])?;
|
||||||
write!(f, [hard_line_break()])?;
|
write!(f, [hard_line_break()])?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub struct FormatComprehension<'a> {
|
||||||
item: &'a Comprehension,
|
item: &'a Comprehension,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsFormat<ASTFormatContext> for Comprehension {
|
impl AsFormat<ASTFormatContext<'_>> for Comprehension {
|
||||||
type Format<'a> = FormatComprehension<'a>;
|
type Format<'a> = FormatComprehension<'a>;
|
||||||
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
@ -17,7 +17,7 @@ impl AsFormat<ASTFormatContext> for Comprehension {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for FormatComprehension<'_> {
|
impl Format<ASTFormatContext<'_>> for FormatComprehension<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let comprehension = self.item;
|
let comprehension = self.item;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub struct FormatExcepthandler<'a> {
|
||||||
item: &'a Excepthandler,
|
item: &'a Excepthandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsFormat<ASTFormatContext> for Excepthandler {
|
impl AsFormat<ASTFormatContext<'_>> for Excepthandler {
|
||||||
type Format<'a> = FormatExcepthandler<'a>;
|
type Format<'a> = FormatExcepthandler<'a>;
|
||||||
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
@ -19,7 +19,7 @@ impl AsFormat<ASTFormatContext> for Excepthandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for FormatExcepthandler<'_> {
|
impl Format<ASTFormatContext<'_>> for FormatExcepthandler<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let excepthandler = self.item;
|
let excepthandler = self.item;
|
||||||
let ExcepthandlerKind::ExceptHandler { type_, name, body } = &excepthandler.node;
|
let ExcepthandlerKind::ExceptHandler { type_, name, body } = &excepthandler.node;
|
||||||
|
|
|
@ -33,7 +33,7 @@ fn format_starred(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format_name(f: &mut Formatter<ASTFormatContext>, expr: &Expr, _id: &str) -> FormatResult<()> {
|
fn format_name(f: &mut Formatter<ASTFormatContext>, expr: &Expr, _id: &str) -> FormatResult<()> {
|
||||||
write!(f, [literal(expr.range())])?;
|
write!(f, [literal(expr.range(), ContainsNewlines::No)])?;
|
||||||
write!(f, [end_of_line_comments(expr)])?;
|
write!(f, [end_of_line_comments(expr)])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ fn format_subscript(
|
||||||
if let TriviaKind::OwnLineComment(range) = trivia.kind {
|
if let TriviaKind::OwnLineComment(range) = trivia.kind {
|
||||||
write!(f, [expand_parent()])?;
|
write!(f, [expand_parent()])?;
|
||||||
write!(f, [hard_line_break()])?;
|
write!(f, [hard_line_break()])?;
|
||||||
write!(f, [literal(range)])?;
|
write!(f, [literal(range, ContainsNewlines::No)])?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -573,7 +573,7 @@ fn format_joined_str(
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
_values: &[Expr],
|
_values: &[Expr],
|
||||||
) -> FormatResult<()> {
|
) -> FormatResult<()> {
|
||||||
write!(f, [literal(expr.range())])?;
|
write!(f, [literal(expr.range(), ContainsNewlines::Detect)])?;
|
||||||
write!(f, [end_of_line_comments(expr)])?;
|
write!(f, [end_of_line_comments(expr)])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -800,7 +800,7 @@ fn format_if_exp(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for FormatExpr<'_> {
|
impl Format<ASTFormatContext<'_>> for FormatExpr<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
if self.item.parentheses.is_always() {
|
if self.item.parentheses.is_always() {
|
||||||
write!(f, [text("(")])?;
|
write!(f, [text("(")])?;
|
||||||
|
@ -871,7 +871,7 @@ impl Format<ASTFormatContext> for FormatExpr<'_> {
|
||||||
if trivia.relationship.is_trailing() {
|
if trivia.relationship.is_trailing() {
|
||||||
if let TriviaKind::OwnLineComment(range) = trivia.kind {
|
if let TriviaKind::OwnLineComment(range) = trivia.kind {
|
||||||
write!(f, [expand_parent()])?;
|
write!(f, [expand_parent()])?;
|
||||||
write!(f, [literal(range)])?;
|
write!(f, [literal(range, ContainsNewlines::No)])?;
|
||||||
write!(f, [hard_line_break()])?;
|
write!(f, [hard_line_break()])?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -885,7 +885,7 @@ impl Format<ASTFormatContext> for FormatExpr<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsFormat<ASTFormatContext> for Expr {
|
impl AsFormat<ASTFormatContext<'_>> for Expr {
|
||||||
type Format<'a> = FormatExpr<'a>;
|
type Format<'a> = FormatExpr<'a>;
|
||||||
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub struct FormatKeyword<'a> {
|
||||||
item: &'a Keyword,
|
item: &'a Keyword,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsFormat<ASTFormatContext> for Keyword {
|
impl AsFormat<ASTFormatContext<'_>> for Keyword {
|
||||||
type Format<'a> = FormatKeyword<'a>;
|
type Format<'a> = FormatKeyword<'a>;
|
||||||
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
@ -18,7 +18,7 @@ impl AsFormat<ASTFormatContext> for Keyword {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for FormatKeyword<'_> {
|
impl Format<ASTFormatContext<'_>> for FormatKeyword<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let keyword = self.item;
|
let keyword = self.item;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub struct FormatMatchCase<'a> {
|
||||||
item: &'a MatchCase,
|
item: &'a MatchCase,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsFormat<ASTFormatContext> for MatchCase {
|
impl AsFormat<ASTFormatContext<'_>> for MatchCase {
|
||||||
type Format<'a> = FormatMatchCase<'a>;
|
type Format<'a> = FormatMatchCase<'a>;
|
||||||
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
@ -19,7 +19,7 @@ impl AsFormat<ASTFormatContext> for MatchCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for FormatMatchCase<'_> {
|
impl Format<ASTFormatContext<'_>> for FormatMatchCase<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let MatchCase {
|
let MatchCase {
|
||||||
pattern,
|
pattern,
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct FloatAtom {
|
||||||
range: TextRange,
|
range: TextRange,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for FloatAtom {
|
impl Format<ASTFormatContext<'_>> for FloatAtom {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let contents = f.context().contents();
|
let contents = f.context().contents();
|
||||||
|
|
||||||
|
@ -26,12 +26,15 @@ impl Format<ASTFormatContext> for FloatAtom {
|
||||||
} else {
|
} else {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
[literal(TextRange::new(
|
[literal(
|
||||||
self.range.start(),
|
TextRange::new(
|
||||||
self.range
|
self.range.start(),
|
||||||
.start()
|
self.range
|
||||||
.add(TextSize::try_from(dot_index).unwrap())
|
.start()
|
||||||
))]
|
.add(TextSize::try_from(dot_index).unwrap())
|
||||||
|
),
|
||||||
|
ContainsNewlines::No
|
||||||
|
)]
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,16 +45,19 @@ impl Format<ASTFormatContext> for FloatAtom {
|
||||||
} else {
|
} else {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
[literal(TextRange::new(
|
[literal(
|
||||||
self.range
|
TextRange::new(
|
||||||
.start()
|
self.range
|
||||||
.add(TextSize::try_from(dot_index + 1).unwrap()),
|
.start()
|
||||||
self.range.end()
|
.add(TextSize::try_from(dot_index + 1).unwrap()),
|
||||||
))]
|
self.range.end()
|
||||||
|
),
|
||||||
|
ContainsNewlines::No
|
||||||
|
)]
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
write!(f, [literal(self.range)])?;
|
write!(f, [literal(self.range, ContainsNewlines::No)])?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -68,7 +74,7 @@ pub(crate) struct FloatLiteral {
|
||||||
range: TextRange,
|
range: TextRange,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for FloatLiteral {
|
impl Format<ASTFormatContext<'_>> for FloatLiteral {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let contents = f.context().contents();
|
let contents = f.context().contents();
|
||||||
|
|
||||||
|
@ -93,12 +99,15 @@ impl Format<ASTFormatContext> for FloatLiteral {
|
||||||
let plus = content[exponent_index + 1..].starts_with('+');
|
let plus = content[exponent_index + 1..].starts_with('+');
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
[literal(TextRange::new(
|
[literal(
|
||||||
self.range
|
TextRange::new(
|
||||||
.start()
|
self.range.start().add(
|
||||||
.add(TextSize::try_from(exponent_index + 1 + usize::from(plus)).unwrap()),
|
TextSize::try_from(exponent_index + 1 + usize::from(plus)).unwrap()
|
||||||
self.range.end()
|
),
|
||||||
))]
|
self.range.end()
|
||||||
|
),
|
||||||
|
ContainsNewlines::No
|
||||||
|
)]
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
write!(f, [float_atom(self.range)])?;
|
write!(f, [float_atom(self.range)])?;
|
||||||
|
@ -118,7 +127,7 @@ pub(crate) struct IntLiteral {
|
||||||
range: TextRange,
|
range: TextRange,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for IntLiteral {
|
impl Format<ASTFormatContext<'_>> for IntLiteral {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let contents = f.context().contents();
|
let contents = f.context().contents();
|
||||||
|
|
||||||
|
@ -142,14 +151,14 @@ impl Format<ASTFormatContext> for IntLiteral {
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
// Use the existing source.
|
// Use the existing source.
|
||||||
write!(f, [literal(self.range)])?;
|
write!(f, [literal(self.range, ContainsNewlines::No)])?;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(f, [literal(self.range)])?;
|
write!(f, [literal(self.range, ContainsNewlines::No)])?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -165,20 +174,20 @@ pub(crate) struct ComplexLiteral {
|
||||||
range: TextRange,
|
range: TextRange,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for ComplexLiteral {
|
impl Format<ASTFormatContext<'_>> for ComplexLiteral {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let contents = f.context().contents();
|
let contents = f.context().contents();
|
||||||
let content = &contents[self.range];
|
let content = &contents[self.range];
|
||||||
|
|
||||||
if content.ends_with('j') {
|
if content.ends_with('j') {
|
||||||
write!(f, [literal(self.range)])?;
|
write!(f, [literal(self.range, ContainsNewlines::No)])?;
|
||||||
} else if content.ends_with('J') {
|
} else if content.ends_with('J') {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
[literal(TextRange::new(
|
[literal(
|
||||||
self.range.start(),
|
TextRange::new(self.range.start(), self.range.end().sub(TextSize::from(1))),
|
||||||
self.range.end().sub(TextSize::from(1))
|
ContainsNewlines::No
|
||||||
))]
|
)]
|
||||||
)?;
|
)?;
|
||||||
write!(f, [text("j")])?;
|
write!(f, [text("j")])?;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub struct FormatOperator<'a> {
|
||||||
item: &'a Operator,
|
item: &'a Operator,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsFormat<ASTFormatContext> for Operator {
|
impl AsFormat<ASTFormatContext<'_>> for Operator {
|
||||||
type Format<'a> = FormatOperator<'a>;
|
type Format<'a> = FormatOperator<'a>;
|
||||||
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
@ -18,7 +18,7 @@ impl AsFormat<ASTFormatContext> for Operator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for FormatOperator<'_> {
|
impl Format<ASTFormatContext<'_>> for FormatOperator<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let operator = self.item;
|
let operator = self.item;
|
||||||
write!(f, [leading_comments(operator)])?;
|
write!(f, [leading_comments(operator)])?;
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub struct FormatPattern<'a> {
|
||||||
item: &'a Pattern,
|
item: &'a Pattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsFormat<ASTFormatContext> for Pattern {
|
impl AsFormat<ASTFormatContext<'_>> for Pattern {
|
||||||
type Format<'a> = FormatPattern<'a>;
|
type Format<'a> = FormatPattern<'a>;
|
||||||
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
@ -19,7 +19,7 @@ impl AsFormat<ASTFormatContext> for Pattern {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for FormatPattern<'_> {
|
impl Format<ASTFormatContext<'_>> for FormatPattern<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let pattern = self.item;
|
let pattern = self.item;
|
||||||
|
|
||||||
|
|
|
@ -756,7 +756,7 @@ pub struct FormatStmt<'a> {
|
||||||
item: &'a Stmt,
|
item: &'a Stmt,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for FormatStmt<'_> {
|
impl Format<ASTFormatContext<'_>> for FormatStmt<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
write!(f, [leading_comments(self.item)])?;
|
write!(f, [leading_comments(self.item)])?;
|
||||||
|
|
||||||
|
@ -939,7 +939,7 @@ impl Format<ASTFormatContext> for FormatStmt<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsFormat<ASTFormatContext> for Stmt {
|
impl AsFormat<ASTFormatContext<'_>> for Stmt {
|
||||||
type Format<'a> = FormatStmt<'a>;
|
type Format<'a> = FormatStmt<'a>;
|
||||||
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub(crate) struct StringLiteralPart {
|
||||||
range: TextRange,
|
range: TextRange,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for StringLiteralPart {
|
impl Format<ASTFormatContext<'_>> for StringLiteralPart {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let contents = f.context().contents();
|
let contents = f.context().contents();
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ pub(crate) struct StringLiteral<'a> {
|
||||||
expr: &'a Expr,
|
expr: &'a Expr,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for StringLiteral<'_> {
|
impl Format<ASTFormatContext<'_>> for StringLiteral<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let expr = self.expr;
|
let expr = self.expr;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub struct FormatUnaryOp<'a> {
|
||||||
item: &'a UnaryOp,
|
item: &'a UnaryOp,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsFormat<ASTFormatContext> for UnaryOp {
|
impl AsFormat<ASTFormatContext<'_>> for UnaryOp {
|
||||||
type Format<'a> = FormatUnaryOp<'a>;
|
type Format<'a> = FormatUnaryOp<'a>;
|
||||||
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
@ -17,7 +17,7 @@ impl AsFormat<ASTFormatContext> for UnaryOp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for FormatUnaryOp<'_> {
|
impl Format<ASTFormatContext<'_>> for FormatUnaryOp<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let unary_op = self.item;
|
let unary_op = self.item;
|
||||||
write!(
|
write!(
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub struct FormatWithitem<'a> {
|
||||||
item: &'a Withitem,
|
item: &'a Withitem,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsFormat<ASTFormatContext> for Withitem {
|
impl AsFormat<ASTFormatContext<'_>> for Withitem {
|
||||||
type Format<'a> = FormatWithitem<'a>;
|
type Format<'a> = FormatWithitem<'a>;
|
||||||
|
|
||||||
fn format(&self) -> Self::Format<'_> {
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
@ -17,7 +17,7 @@ impl AsFormat<ASTFormatContext> for Withitem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<ASTFormatContext> for FormatWithitem<'_> {
|
impl Format<ASTFormatContext<'_>> for FormatWithitem<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<ASTFormatContext>) -> FormatResult<()> {
|
||||||
let withitem = self.item;
|
let withitem = self.item;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue