mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 13:25:17 +00:00
Replace row/column based Location
with byte-offsets. (#3931)
This commit is contained in:
parent
ee91598835
commit
cab65b25da
418 changed files with 6203 additions and 7040 deletions
|
@ -1,49 +1,58 @@
|
|||
use rustpython_parser::ast::Location;
|
||||
use ruff_text_size::{TextRange, TextSize};
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cmp::Ordering;
|
||||
|
||||
/// A text edit to be applied to a source file. Inserts, deletes, or replaces
|
||||
/// content at a given location.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Edit {
|
||||
/// The start location of the edit.
|
||||
location: Location,
|
||||
/// The end location of the edit.
|
||||
end_location: Location,
|
||||
range: TextRange,
|
||||
/// The replacement content to insert between the start and end locations.
|
||||
content: Option<Box<str>>,
|
||||
}
|
||||
|
||||
impl Edit {
|
||||
/// Creates an edit that deletes the content in the `start` to `end` range.
|
||||
pub const fn deletion(start: Location, end: Location) -> Self {
|
||||
#[inline]
|
||||
pub const fn deletion(start: TextSize, end: TextSize) -> Self {
|
||||
Self::range_deletion(TextRange::new(start, end))
|
||||
}
|
||||
|
||||
/// Creates an edit that deletes the content in `range`.
|
||||
pub const fn range_deletion(range: TextRange) -> Self {
|
||||
Self {
|
||||
content: None,
|
||||
location: start,
|
||||
end_location: end,
|
||||
range,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates an edit that replaces the content in the `start` to `end` range with `content`.
|
||||
pub fn replacement(content: String, start: Location, end: Location) -> Self {
|
||||
#[inline]
|
||||
pub fn replacement(content: String, start: TextSize, end: TextSize) -> Self {
|
||||
Self::range_replacement(content, TextRange::new(start, end))
|
||||
}
|
||||
|
||||
/// Creates an edit that replaces the content in `range` with `content`.
|
||||
pub fn range_replacement(content: String, range: TextRange) -> Self {
|
||||
debug_assert!(!content.is_empty(), "Prefer `Fix::deletion`");
|
||||
|
||||
Self {
|
||||
content: Some(Box::from(content)),
|
||||
location: start,
|
||||
end_location: end,
|
||||
range,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates an edit that inserts `content` at the [`Location`] `at`.
|
||||
pub fn insertion(content: String, at: Location) -> Self {
|
||||
/// Creates an edit that inserts `content` at the [`TextSize`] `at`.
|
||||
pub fn insertion(content: String, at: TextSize) -> Self {
|
||||
debug_assert!(!content.is_empty(), "Insert content is empty");
|
||||
|
||||
Self {
|
||||
content: Some(Box::from(content)),
|
||||
location: at,
|
||||
end_location: at,
|
||||
range: TextRange::new(at, at),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,19 +62,23 @@ impl Edit {
|
|||
}
|
||||
|
||||
/// Returns the start location of the edit in the source document.
|
||||
pub const fn location(&self) -> Location {
|
||||
self.location
|
||||
pub const fn start(&self) -> TextSize {
|
||||
self.range.start()
|
||||
}
|
||||
|
||||
pub const fn range(&self) -> TextRange {
|
||||
self.range
|
||||
}
|
||||
|
||||
/// Returns the edit's end location in the source document.
|
||||
pub const fn end_location(&self) -> Location {
|
||||
self.end_location
|
||||
pub const fn end(&self) -> TextSize {
|
||||
self.range.end()
|
||||
}
|
||||
|
||||
fn kind(&self) -> EditOperationKind {
|
||||
if self.content.is_none() {
|
||||
EditOperationKind::Deletion
|
||||
} else if self.location == self.end_location {
|
||||
} else if self.range.is_empty() {
|
||||
EditOperationKind::Insertion
|
||||
} else {
|
||||
EditOperationKind::Replacement
|
||||
|
@ -91,6 +104,21 @@ impl Edit {
|
|||
}
|
||||
}
|
||||
|
||||
impl Ord for Edit {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.start()
|
||||
.cmp(&other.start())
|
||||
.then_with(|| self.end().cmp(&other.end()))
|
||||
.then_with(|| self.content.cmp(&other.content))
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Edit {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||
enum EditOperationKind {
|
||||
/// Edit that inserts new content into the source document.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue