Add Applicability to Fix (#4303)

Co-authored-by: Micha Reiser <micha@reiser.io>
This commit is contained in:
Zanie Adkins 2023-05-10 01:42:46 -05:00 committed by GitHub
parent d66ce76691
commit cf7aa26aa4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
116 changed files with 296 additions and 8 deletions

View file

@ -47,6 +47,7 @@ impl Diagnostic {
/// Set the [`Fix`] used to fix the diagnostic.
#[inline]
#[deprecated(note = "Use `Diagnostic::set_fix` instead.")]
#[allow(deprecated)]
pub fn set_fix_from_edit(&mut self, edit: Edit) {
self.fix = Some(Fix::unspecified(edit));
}
@ -62,6 +63,7 @@ impl Diagnostic {
/// Set the [`Fix`] used to fix the diagnostic, if the provided function returns `Ok`.
/// Otherwise, log the error.
#[inline]
#[allow(deprecated)]
pub fn try_set_fix(&mut self, func: impl FnOnce() -> Result<Fix>) {
match func() {
Ok(fix) => self.fix = Some(fix),
@ -73,6 +75,7 @@ impl Diagnostic {
/// Otherwise, log the error.
#[inline]
#[deprecated(note = "Use Diagnostic::try_set_fix instead")]
#[allow(deprecated)]
pub fn try_set_fix_from_edit(&mut self, func: impl FnOnce() -> Result<Edit>) {
match func() {
Ok(edit) => self.fix = Some(Fix::unspecified(edit)),

View file

@ -4,23 +4,105 @@ use serde::{Deserialize, Serialize};
use crate::edit::Edit;
/// Indicates confidence in the correctness of a suggested fix.
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Applicability {
/// The fix is definitely what the user intended, or maintains the exact meaning of the code.
/// This fix should be automatically applied.
Automatic,
/// The fix may be what the user intended, but it is uncertain.
/// The fix should result in valid code if it is applied.
/// The fix can be applied with user opt-in.
Suggested,
/// The fix has a good chance of being incorrect or the code be incomplete.
/// The fix may result in invalid code if it is applied.
/// The fix should only be manually applied by the user.
Manual,
/// The applicability of the fix is unknown.
#[default]
Unspecified,
}
/// A collection of [`Edit`] elements to be applied to a source file.
#[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Fix {
edits: Vec<Edit>,
applicability: Applicability,
}
impl Fix {
/// Create a new [`Fix`] with an unspecified applicability from an [`Edit`] element.
#[deprecated(
note = "Use `Fix::automatic`, `Fix::suggested`, or `Fix::manual` instead to specify an applicability."
)]
pub fn unspecified(edit: Edit) -> Self {
Self { edits: vec![edit] }
Self {
edits: vec![edit],
applicability: Applicability::Unspecified,
}
}
/// Create a new [`Fix`] with unspecified applicability from multiple [`Edit`] elements.
/// Create a new [`Fix`] with an unspecified applicability from multiple [`Edit`] elements.
#[deprecated(
note = "Use `Fix::automatic_edits`, `Fix::suggested_edits`, or `Fix::manual_edits` instead to specify an applicability."
)]
pub fn unspecified_edits(edit: Edit, rest: impl IntoIterator<Item = Edit>) -> Self {
Self {
edits: std::iter::once(edit).chain(rest.into_iter()).collect(),
applicability: Applicability::Unspecified,
}
}
/// Create a new [`Fix`] with [automatic applicability](Applicability::Automatic) from an [`Edit`] element.
pub fn automatic(edit: Edit) -> Self {
Self {
edits: vec![edit],
applicability: Applicability::Automatic,
}
}
/// Create a new [`Fix`] with [automatic applicability](Applicability::Automatic) from multiple [`Edit`] elements.
pub fn automatic_edits(edit: Edit, rest: impl IntoIterator<Item = Edit>) -> Self {
Self {
edits: std::iter::once(edit).chain(rest.into_iter()).collect(),
applicability: Applicability::Automatic,
}
}
/// Create a new [`Fix`] with [suggested applicability](Applicability::Suggested) from an [`Edit`] element.
pub fn suggested(edit: Edit) -> Self {
Self {
edits: vec![edit],
applicability: Applicability::Suggested,
}
}
/// Create a new [`Fix`] with [suggested applicability](Applicability::Suggested) from multiple [`Edit`] elements.
pub fn suggested_edits(edit: Edit, rest: impl IntoIterator<Item = Edit>) -> Self {
Self {
edits: std::iter::once(edit).chain(rest.into_iter()).collect(),
applicability: Applicability::Suggested,
}
}
/// Create a new [`Fix`] with [manual applicability](Applicability::Manual) from an [`Edit`] element.
pub fn manual(edit: Edit) -> Self {
Self {
edits: vec![edit],
applicability: Applicability::Manual,
}
}
/// Create a new [`Fix`] with [manual applicability](Applicability::Manual) from multiple [`Edit`] elements.
pub fn manual_edits(edit: Edit, rest: impl IntoIterator<Item = Edit>) -> Self {
Self {
edits: std::iter::once(edit).chain(rest.into_iter()).collect(),
applicability: Applicability::Manual,
}
}
@ -37,4 +119,8 @@ impl Fix {
pub fn into_edits(self) -> Vec<Edit> {
self.edits
}
pub fn applicability(&self) -> Applicability {
self.applicability
}
}

View file

@ -1,6 +1,6 @@
pub use diagnostic::{Diagnostic, DiagnosticKind};
pub use edit::Edit;
pub use fix::Fix;
pub use fix::{Applicability, Fix};
pub use violation::{AlwaysAutofixableViolation, AutofixKind, Violation};
mod diagnostic;