Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional source map generation #6894

Merged
merged 1 commit into from
Aug 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions crates/ruff_formatter/src/builders.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
use crate::format_element::tag::{Condition, Tag};
use crate::prelude::tag::{DedentMode, GroupMode, LabelId};
use crate::prelude::*;
use crate::{format_element, write, Argument, Arguments, FormatContext, GroupId, TextSize};
use crate::{Buffer, VecBuffer};

use ruff_text_size::TextRange;
use std::cell::Cell;
use std::marker::PhantomData;
use std::num::NonZeroU8;

use ruff_text_size::TextRange;
#[allow(clippy::enum_glob_use)]
use Tag::*;

use crate::format_element::tag::{Condition, Tag};
use crate::prelude::tag::{DedentMode, GroupMode, LabelId};
use crate::prelude::*;
use crate::{format_element, write, Argument, Arguments, FormatContext, GroupId, TextSize};
use crate::{Buffer, VecBuffer};

/// A line break that only gets printed if the enclosing `Group` doesn't fit on a single line.
/// It's omitted if the enclosing `Group` fits on a single line.
/// A soft line break is identical to a hard line break when not enclosed inside of a `Group`.
Expand Down Expand Up @@ -283,7 +284,6 @@ impl std::fmt::Debug for StaticText {
/// ## Examples
///
/// ```
/// /// ```
/// use ruff_formatter::format;
/// use ruff_formatter::prelude::*;
///
Expand Down Expand Up @@ -329,6 +329,7 @@ pub struct SourcePosition(TextSize);
impl<Context> Format<Context> for SourcePosition {
fn fmt(&self, f: &mut Formatter<Context>) -> FormatResult<()> {
f.write_element(FormatElement::SourcePosition(self.0));

Ok(())
}
}
Expand Down
18 changes: 10 additions & 8 deletions crates/ruff_formatter/src/format_element/document.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
use super::tag::Tag;
use std::collections::HashMap;
use std::ops::Deref;

use rustc_hash::FxHashMap;

use crate::format_element::tag::{Condition, DedentMode};
use crate::prelude::tag::GroupMode;
use crate::prelude::*;
use crate::printer::LineEnding;
use crate::source_code::SourceCode;
use crate::{format, write, TabWidth};
use crate::{
BufferExtensions, Format, FormatContext, FormatElement, FormatOptions, FormatResult, Formatter,
IndentStyle, LineWidth, PrinterOptions,
};
use rustc_hash::FxHashMap;
use std::collections::HashMap;
use std::ops::Deref;

use super::tag::Tag;

/// A formatted document.
#[derive(Debug, Clone, Eq, PartialEq, Default)]
Expand Down Expand Up @@ -225,10 +227,9 @@ impl FormatOptions for IrFormatOptions {

fn as_print_options(&self) -> PrinterOptions {
PrinterOptions {
tab_width: TabWidth::default(),
print_width: self.line_width().into(),
line_ending: LineEnding::LineFeed,
indent_style: IndentStyle::Space(2),
..PrinterOptions::default()
}
}
}
Expand Down Expand Up @@ -781,10 +782,11 @@ impl Format<IrFormatContext<'_>> for Condition {

#[cfg(test)]
mod tests {
use ruff_text_size::{TextRange, TextSize};

use crate::prelude::*;
use crate::{format, format_args, write};
use crate::{SimpleFormatContext, SourceCode};
use ruff_text_size::{TextRange, TextSize};

#[test]
fn display_elements() {
Expand Down
12 changes: 7 additions & 5 deletions crates/ruff_formatter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use std::fmt::{Debug, Display};
use std::marker::PhantomData;

use crate::format_element::document::Document;
use crate::printer::{Printer, PrinterOptions};
use crate::printer::{Printer, PrinterOptions, SourceMapGeneration};
pub use arguments::{Argument, Arguments};
pub use buffer::{
Buffer, BufferExtensions, BufferSnapshot, Inspect, RemoveSoftLinesBuffer, VecBuffer,
Expand Down Expand Up @@ -311,10 +311,12 @@ impl FormatOptions for SimpleFormatOptions {
}

fn as_print_options(&self) -> PrinterOptions {
PrinterOptions::default()
.with_indent(self.indent_style)
.with_tab_width(self.tab_width())
.with_print_width(self.line_width.into())
PrinterOptions {
print_width: self.line_width.into(),
indent_style: self.indent_style,
source_map_generation: SourceMapGeneration::Enabled,
..PrinterOptions::default()
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions crates/ruff_formatter/src/printer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,10 @@ impl<'a> Printer<'a> {
}

fn push_marker(&mut self) {
if self.options.source_map_generation.is_disabled() {
return;
}

let marker = SourceMarker {
source: self.state.source_position,
dest: self.state.buffer.text_len(),
Expand Down
93 changes: 61 additions & 32 deletions crates/ruff_formatter/src/printer/printer_options/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,10 @@ pub struct PrinterOptions {

/// Whether the printer should use tabs or spaces to indent code and if spaces, by how many.
pub indent_style: IndentStyle,
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct PrintWidth(u32);

impl PrintWidth {
pub fn new(width: u32) -> Self {
Self(width)
}
}

impl Default for PrintWidth {
fn default() -> Self {
LineWidth::default().into()
}
}

impl From<LineWidth> for PrintWidth {
fn from(width: LineWidth) -> Self {
Self(u32::from(u16::from(width)))
}
}

impl From<PrintWidth> for usize {
fn from(width: PrintWidth) -> Self {
width.0 as usize
}
}

impl From<PrintWidth> for u32 {
fn from(width: PrintWidth) -> Self {
width.0
}
/// Whether the printer should build a source map that allows mapping positions in the source document
/// to positions in the formatted document.
pub source_map_generation: SourceMapGeneration,
}

impl<'a, O> From<&'a O> for PrinterOptions
Expand Down Expand Up @@ -94,6 +65,64 @@ impl PrinterOptions {
}
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct PrintWidth(u32);

impl PrintWidth {
pub fn new(width: u32) -> Self {
Self(width)
}
}

impl Default for PrintWidth {
fn default() -> Self {
LineWidth::default().into()
}
}

impl From<LineWidth> for PrintWidth {
fn from(width: LineWidth) -> Self {
Self(u32::from(u16::from(width)))
}
}

impl From<PrintWidth> for usize {
fn from(width: PrintWidth) -> Self {
width.0 as usize
}
}

impl From<PrintWidth> for u32 {
fn from(width: PrintWidth) -> Self {
width.0
}
}

/// Configures whether the formatter and printer generate a source map that allows mapping
/// positions in the source document to positions in the formatted code.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum SourceMapGeneration {
/// The formatter generates no source map.
#[default]
Disabled,

/// The formatter generates a source map that allows mapping positions in the source document
/// to positions in the formatted document. The ability to map positions is useful for range formatting
/// or when trying to identify where to move the cursor so that it matches its position in the source document.
Enabled,
}

impl SourceMapGeneration {
pub const fn is_enabled(self) -> bool {
matches!(self, SourceMapGeneration::Enabled)
}

pub const fn is_disabled(self) -> bool {
matches!(self, SourceMapGeneration::Disabled)
}
}

#[allow(dead_code)]
#[derive(Clone, Debug, Eq, PartialEq, Default)]
pub enum LineEnding {
Expand Down
34 changes: 15 additions & 19 deletions crates/ruff_python_formatter/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
use thiserror::Error;

use ruff_formatter::format_element::tag;
use ruff_formatter::prelude::{source_position, text, Formatter, Tag};
use ruff_formatter::{
format, write, Buffer, Format, FormatElement, FormatError, FormatResult, PrintError,
};
use ruff_formatter::{Formatted, Printed, SourceCode};
use ruff_formatter::prelude::*;
use ruff_formatter::{format, FormatError, Formatted, PrintError, Printed, SourceCode};
use ruff_python_ast::node::{AnyNodeRef, AstNode};
use ruff_python_ast::Mod;
use ruff_python_index::{CommentRanges, CommentRangesBuilder};
Expand Down Expand Up @@ -54,23 +51,22 @@ where
if self.is_suppressed(node_comments.trailing, f.context()) {
suppressed_node(node.as_any_node_ref()).fmt(f)
} else {
write!(
f,
[
leading_comments(node_comments.leading),
source_position(node.start())
]
)?;
leading_comments(node_comments.leading).fmt(f)?;

let is_source_map_enabled = f.options().source_map_generation().is_enabled();

if is_source_map_enabled {
source_position(node.start()).fmt(f)?;
}

self.fmt_fields(node, f)?;
self.fmt_dangling_comments(node_comments.dangling, f)?;

write!(
f,
[
source_position(node.end()),
trailing_comments(node_comments.trailing)
]
)
if is_source_map_enabled {
source_position(node.end()).fmt(f)?;
}

trailing_comments(node_comments.trailing).fmt(f)
}
}

Expand Down
12 changes: 11 additions & 1 deletion crates/ruff_python_formatter/src/options.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use ruff_formatter::printer::{LineEnding, PrinterOptions};
use ruff_formatter::printer::{LineEnding, PrinterOptions, SourceMapGeneration};
use ruff_formatter::{FormatOptions, IndentStyle, LineWidth, TabWidth};
use ruff_python_ast::PySourceType;
use std::path::Path;
Expand Down Expand Up @@ -33,6 +33,10 @@ pub struct PyFormatOptions {

/// Whether to expand lists or elements if they have a trailing comma such as `(a, b,)`.
magic_trailing_comma: MagicTrailingComma,

/// Should the formatter generate a source map that allows mapping source positions to positions
/// in the formatted document.
source_map_generation: SourceMapGeneration,
}

fn default_line_width() -> LineWidth {
Expand All @@ -56,6 +60,7 @@ impl Default for PyFormatOptions {
tab_width: default_tab_width(),
quote_style: QuoteStyle::default(),
magic_trailing_comma: MagicTrailingComma::default(),
source_map_generation: SourceMapGeneration::default(),
}
}
}
Expand Down Expand Up @@ -85,6 +90,10 @@ impl PyFormatOptions {
self.source_type
}

pub fn source_map_generation(&self) -> SourceMapGeneration {
self.source_map_generation
}

#[must_use]
pub fn with_quote_style(mut self, style: QuoteStyle) -> Self {
self.quote_style = style;
Expand Down Expand Up @@ -129,6 +138,7 @@ impl FormatOptions for PyFormatOptions {
print_width: self.line_width.into(),
line_ending: LineEnding::LineFeed,
indent_style: self.indent_style,
source_map_generation: self.source_map_generation,
}
}
}
Expand Down
Loading