mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-28 04:45:01 +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,11 +1,10 @@
|
|||
use anyhow::Result;
|
||||
use log::error;
|
||||
use rustpython_parser::ast::Location;
|
||||
use ruff_text_size::{TextRange, TextSize};
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use ruff_python_ast::types::Range;
|
||||
|
||||
use crate::Fix;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
|
@ -24,18 +23,16 @@ pub struct DiagnosticKind {
|
|||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Diagnostic {
|
||||
pub kind: DiagnosticKind,
|
||||
pub location: Location,
|
||||
pub end_location: Location,
|
||||
pub range: TextRange,
|
||||
pub fix: Fix,
|
||||
pub parent: Option<Location>,
|
||||
pub parent: Option<TextSize>,
|
||||
}
|
||||
|
||||
impl Diagnostic {
|
||||
pub fn new<T: Into<DiagnosticKind>>(kind: T, range: Range) -> Self {
|
||||
pub fn new<T: Into<DiagnosticKind>>(kind: T, range: TextRange) -> Self {
|
||||
Self {
|
||||
kind: kind.into(),
|
||||
location: range.location,
|
||||
end_location: range.end_location,
|
||||
range,
|
||||
fix: Fix::empty(),
|
||||
parent: None,
|
||||
}
|
||||
|
@ -65,9 +62,21 @@ impl Diagnostic {
|
|||
}
|
||||
}
|
||||
|
||||
pub const fn range(&self) -> TextRange {
|
||||
self.range
|
||||
}
|
||||
|
||||
pub const fn start(&self) -> TextSize {
|
||||
self.range.start()
|
||||
}
|
||||
|
||||
pub const fn end(&self) -> TextSize {
|
||||
self.range.end()
|
||||
}
|
||||
|
||||
/// Set the location of the diagnostic's parent node.
|
||||
#[inline]
|
||||
pub fn set_parent(&mut self, parent: Location) {
|
||||
pub fn set_parent(&mut self, parent: TextSize) {
|
||||
self.parent = Some(parent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::Location;
|
||||
use ruff_text_size::TextSize;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -27,9 +27,9 @@ impl Fix {
|
|||
self.edits.is_empty()
|
||||
}
|
||||
|
||||
/// Return the [`Location`] of the first [`Edit`] in the [`Fix`].
|
||||
pub fn min_location(&self) -> Option<Location> {
|
||||
self.edits.iter().map(Edit::location).min()
|
||||
/// Return the [`TextSize`] of the first [`Edit`] in the [`Fix`].
|
||||
pub fn min_start(&self) -> Option<TextSize> {
|
||||
self.edits.iter().map(Edit::start).min()
|
||||
}
|
||||
|
||||
/// Return a slice of the [`Edit`] elements in the [`Fix`].
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue