mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-28 12:55:05 +00:00
Optional source map generation (#6894)
This commit is contained in:
parent
15b73bdb8a
commit
eae59cf088
7 changed files with 117 additions and 73 deletions
|
@ -1,16 +1,17 @@
|
|||
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};
|
||||
|
||||
use ruff_text_size::TextRange;
|
||||
use std::cell::Cell;
|
||||
use std::marker::PhantomData;
|
||||
use std::num::NonZeroU8;
|
||||
#[allow(clippy::enum_glob_use)]
|
||||
use Tag::*;
|
||||
|
||||
/// 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`.
|
||||
|
@ -283,7 +284,6 @@ impl std::fmt::Debug for StaticText {
|
|||
/// ## Examples
|
||||
///
|
||||
/// ```
|
||||
/// /// ```
|
||||
/// use ruff_formatter::format;
|
||||
/// use ruff_formatter::prelude::*;
|
||||
///
|
||||
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)]
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
|
|
@ -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,
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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
|
||||
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue