mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 14:21:24 +00:00
Allow diagnostics to generate multi-edit fixes (#3709)
This commit is contained in:
parent
32be63fd1e
commit
e603382cf0
731 changed files with 17319 additions and 13447 deletions
|
@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use ruff_python_ast::types::Range;
|
||||
|
||||
use crate::edit::Edit;
|
||||
use crate::Fix;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
|
@ -27,31 +27,31 @@ pub struct Diagnostic {
|
|||
pub kind: DiagnosticKind,
|
||||
pub location: Location,
|
||||
pub end_location: Location,
|
||||
pub fix: Option<Edit>,
|
||||
pub fix: Fix,
|
||||
pub parent: Option<Location>,
|
||||
}
|
||||
|
||||
impl Diagnostic {
|
||||
pub fn new<K: Into<DiagnosticKind>>(kind: K, range: Range) -> Self {
|
||||
pub fn new<T: Into<DiagnosticKind>>(kind: T, range: Range) -> Self {
|
||||
Self {
|
||||
kind: kind.into(),
|
||||
location: range.location,
|
||||
end_location: range.end_location,
|
||||
fix: None,
|
||||
fix: Fix::empty(),
|
||||
parent: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the [`Edit`] used to fix the diagnostic.
|
||||
pub fn set_fix(&mut self, fix: Edit) {
|
||||
self.fix = Some(fix);
|
||||
/// Set the [`Fix`] used to fix the diagnostic.
|
||||
pub fn set_fix<T: Into<Fix>>(&mut self, fix: T) {
|
||||
self.fix = fix.into();
|
||||
}
|
||||
|
||||
/// Set the [`Edit`] used to fix the diagnostic, if the provided function returns `Ok`.
|
||||
/// Set the [`Fix`] used to fix the diagnostic, if the provided function returns `Ok`.
|
||||
/// Otherwise, log the error.
|
||||
pub fn try_set_fix(&mut self, func: impl FnOnce() -> Result<Edit>) {
|
||||
pub fn try_set_fix<T: Into<Fix>>(&mut self, func: impl FnOnce() -> Result<T>) {
|
||||
match func() {
|
||||
Ok(fix) => self.fix = Some(fix),
|
||||
Ok(fix) => self.fix = fix.into(),
|
||||
Err(err) => error!("Failed to create fix: {}", err),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ use rustpython_parser::ast::Location;
|
|||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// 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)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Edit {
|
||||
|
|
58
crates/ruff_diagnostics/src/fix.rs
Normal file
58
crates/ruff_diagnostics/src/fix.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
use rustpython_parser::ast::Location;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::edit::Edit;
|
||||
|
||||
/// A collection of [`Edit`] elements to be applied to a source file.
|
||||
#[derive(Default, Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Fix {
|
||||
edits: Vec<Edit>,
|
||||
}
|
||||
|
||||
impl Fix {
|
||||
/// Create a new [`Fix`] from a vector of [`Edit`] elements.
|
||||
pub fn new(edits: Vec<Edit>) -> Self {
|
||||
Self { edits }
|
||||
}
|
||||
|
||||
/// Create an empty [`Fix`].
|
||||
pub const fn empty() -> Self {
|
||||
Self { edits: Vec::new() }
|
||||
}
|
||||
|
||||
/// Return `true` if the [`Fix`] contains no [`Edit`] elements.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.edits.is_empty()
|
||||
}
|
||||
|
||||
/// Return the [`Location`] of the first [`Edit`] in the [`Fix`].
|
||||
pub fn location(&self) -> Option<Location> {
|
||||
self.edits.iter().map(|edit| edit.location).min()
|
||||
}
|
||||
|
||||
/// Return the [`Location`] of the last [`Edit`] in the [`Fix`].
|
||||
pub fn end_location(&self) -> Option<Location> {
|
||||
self.edits.iter().map(|edit| edit.end_location).max()
|
||||
}
|
||||
|
||||
/// Return a slice of the [`Edit`] elements in the [`Fix`].
|
||||
pub fn edits(&self) -> &[Edit] {
|
||||
&self.edits
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<Edit> for Fix {
|
||||
fn from_iter<T: IntoIterator<Item = Edit>>(iter: T) -> Self {
|
||||
Self {
|
||||
edits: Vec::from_iter(iter),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Edit> for Fix {
|
||||
fn from(edit: Edit) -> Self {
|
||||
Self { edits: vec![edit] }
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
pub use diagnostic::{Diagnostic, DiagnosticKind};
|
||||
pub use edit::Edit;
|
||||
pub use fix::Fix;
|
||||
pub use violation::{AlwaysAutofixableViolation, AutofixKind, Violation};
|
||||
|
||||
mod diagnostic;
|
||||
mod edit;
|
||||
mod fix;
|
||||
mod violation;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue