Skip to content

Commit

Permalink
refactor(analyzer): use rule name for quick fix (#4469)
Browse files Browse the repository at this point in the history
  • Loading branch information
ematipico authored Nov 6, 2024
1 parent ff02a0b commit 041e825
Show file tree
Hide file tree
Showing 148 changed files with 379 additions and 480 deletions.
6 changes: 3 additions & 3 deletions crates/biome_analyze/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ Let's say we want to create a new **lint** rule called `useMyRuleName`, follow t
fn action(ctx: &RuleContext<Self>, _state: &Self::State) -> Option<JsRuleAction> {
let mut mutation = ctx.root().mutation();
Some(JsRuleAction::new(
ActionCategory::QuickFix,
ctx.action_category(ctx.category(), ctx.group()),
ctx.metadata().applicability(),
markup! { "<MESSAGE>" }.to_owned(),
mutation,
Expand All @@ -120,7 +120,7 @@ Let's say we want to create a new **lint** rule called `useMyRuleName`, follow t
}
```
When returning a code action, you must pass the `category` and the `applicability` fields.
`category` must be `ActionCategory::QuickFix`.
`category` must be `ctx.action_category(ctx.category(), ctx.group())`.
`applicability` is derived from the metadata [`fix_kind`](#code-action).
In other words, the code transformation should always result in code that doesn't change the behavior of the logic.
In the case of `noVar`, it is not always safe to turn `var` to `const` or `let`.
Expand Down Expand Up @@ -509,7 +509,7 @@ impl Rule for ExampleRule {
let mut mutation = ctx.root().begin();

Some(JsRuleAction::new(
ActionCategory::QuickFix,
ctx.action_category(ctx.category(), ctx.group()),
ctx.metadata().applicability(),
markup! { "Remove the '"{name.text_trimmed()}"' element." }.to_owned(),
mutation,
Expand Down
14 changes: 10 additions & 4 deletions crates/biome_analyze/src/categories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub enum ActionCategory {
/// Base kind for quickfix actions: 'quickfix'.
///
/// This action provides a fix to the diagnostic emitted by the same signal
QuickFix,
QuickFix(Cow<'static, str>),
/// Base kind for refactoring actions: 'refactor'.
///
/// This action provides an optional refactor opportunity
Expand All @@ -57,10 +57,10 @@ impl ActionCategory {
/// ## Examples
///
/// ```
/// use std::borrow::Cow;
/// use biome_analyze::{ActionCategory, RefactorKind};
///
/// assert!(ActionCategory::QuickFix.matches("quickfix"));
/// assert!(!ActionCategory::QuickFix.matches("refactor"));
/// assert!(ActionCategory::QuickFix(Cow::from("quickfix")).matches("quickfix"));
///
/// assert!(ActionCategory::Refactor(RefactorKind::None).matches("refactor"));
/// assert!(!ActionCategory::Refactor(RefactorKind::None).matches("refactor.extract"));
Expand All @@ -75,7 +75,13 @@ impl ActionCategory {
/// Returns the representation of this [ActionCategory] as a `CodeActionKind` string
pub fn to_str(&self) -> Cow<'static, str> {
match self {
ActionCategory::QuickFix => Cow::Borrowed("quickfix.biome"),
ActionCategory::QuickFix(tag) => {
if tag.is_empty() {
Cow::Borrowed("quickfix.biome")
} else {
Cow::Owned(format!("quickfix.biome.{tag}"))
}
}

ActionCategory::Refactor(RefactorKind::None) => Cow::Borrowed("refactor.biome"),
ActionCategory::Refactor(RefactorKind::Extract) => {
Expand Down
12 changes: 11 additions & 1 deletion crates/biome_analyze/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::options::{JsxRuntime, PreferredQuote};
use crate::RuleMetadata;
use crate::{registry::RuleRoot, FromServices, Queryable, Rule, RuleKey, ServiceBag};
use crate::{GroupCategory, RuleCategory, RuleGroup, RuleMetadata};
use biome_diagnostics::{Error, Result};
use std::ops::Deref;
use std::path::Path;
Expand Down Expand Up @@ -53,6 +53,16 @@ where
self.query_result
}

/// Returns the group that belongs to the current rule
pub fn group(&self) -> &'static str {
<R::Group as RuleGroup>::NAME
}

/// Returns the category that belongs to the current rule
pub fn category(&self) -> RuleCategory {
<<R::Group as RuleGroup>::Category as GroupCategory>::CATEGORY
}

/// Returns a clone of the AST root
pub fn root(&self) -> RuleRoot<R> {
self.root.clone()
Expand Down
5 changes: 3 additions & 2 deletions crates/biome_analyze/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![deny(rustdoc::broken_intra_doc_links)]

use std::borrow::Cow;
use std::cmp::Ordering;
use std::collections::{BTreeMap, BinaryHeap};
use std::fmt::{Debug, Display, Formatter};
Expand Down Expand Up @@ -677,7 +678,7 @@ fn create_suppression_comment_action<L: Language>(
Some(AnalyzerAction {
mutation,
applicability: Applicability::MaybeIncorrect,
category: ActionCategory::QuickFix,
category: ActionCategory::QuickFix(Cow::Borrowed("")),
message: markup! {
"Use // biome-ignore instead"
}
Expand Down Expand Up @@ -766,7 +767,7 @@ fn update_suppression<L: Language>(

Some(AnalyzerAction {
rule_name: None,
category: ActionCategory::QuickFix,
category: ActionCategory::QuickFix(Cow::Borrowed("")),
applicability: Applicability::Always,
message: markup! {
"Rewrite suppression to use the newer syntax"
Expand Down
17 changes: 16 additions & 1 deletion crates/biome_analyze/src/rule.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::categories::{ActionCategory, RuleCategory};
use crate::context::RuleContext;
use crate::registry::{RegistryVisitor, RuleLanguage, RuleSuppressions};
use crate::{Phase, Phases, Queryable, SuppressionAction, SuppressionCommentEmitterPayload};
use crate::{
Phase, Phases, Queryable, SourceActionKind, SuppressionAction, SuppressionCommentEmitterPayload,
};
use biome_console::fmt::Display;
use biome_console::{markup, MarkupBuf};
use biome_diagnostics::advice::CodeSuggestionAdvice;
Expand All @@ -12,6 +14,7 @@ use biome_diagnostics::{
Visit,
};
use biome_rowan::{AstNode, BatchMutation, BatchMutationExt, Language, TextRange};
use std::borrow::Cow;
use std::cmp::Ordering;
use std::fmt::Debug;

Expand Down Expand Up @@ -366,6 +369,18 @@ impl RuleMetadata {
.try_into()
.expect("Fix kind is not set in the rule metadata")
}

pub fn action_category(&self, category: RuleCategory, group: &'static str) -> ActionCategory {
match category {
RuleCategory::Lint => {
ActionCategory::QuickFix(Cow::Owned(format!("{}.{}", group, self.name)))
}
RuleCategory::Action => {
ActionCategory::Source(SourceActionKind::Other(Cow::Borrowed(self.name)))
}
RuleCategory::Syntax | RuleCategory::Transformation => unimplemented!(""),
}
}
}

pub trait RuleMeta {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use biome_analyze::{
context::RuleContext, declare_lint_rule, ActionCategory, Ast, FixKind, Rule, RuleDiagnostic,
RuleSource, RuleSourceKind,
context::RuleContext, declare_lint_rule, Ast, FixKind, Rule, RuleDiagnostic, RuleSource,
RuleSourceKind,
};
use biome_console::markup;
use biome_graphql_factory::make;
Expand Down Expand Up @@ -86,7 +86,7 @@ impl Rule for UseNamedOperation {
mutation.replace_node(node, new_node);

Some(GraphqlRuleAction::new(
ActionCategory::QuickFix,
ctx.metadata().action_category(ctx.category(), ctx.group()),
ctx.metadata().applicability(),
markup! {
"Rename this "{operation_type}" to "{suggested_name}"."
Expand Down
5 changes: 2 additions & 3 deletions crates/biome_js_analyze/src/lint/a11y/no_access_key.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::JsRuleAction;
use biome_analyze::{
context::RuleContext, declare_lint_rule, ActionCategory, Ast, FixKind, Rule, RuleDiagnostic,
RuleSource,
context::RuleContext, declare_lint_rule, Ast, FixKind, Rule, RuleDiagnostic, RuleSource,
};
use biome_console::markup;
use biome_js_syntax::{jsx_ext::AnyJsxElement, JsxAttribute, JsxAttributeList};
Expand Down Expand Up @@ -100,7 +99,7 @@ impl Rule for NoAccessKey {
let mut mutation = ctx.root().begin();
mutation.remove_node(node.clone());
Some(JsRuleAction::new(
ActionCategory::QuickFix,
ctx.metadata().action_category(ctx.category(), ctx.group()),
ctx.metadata().applicability(),
markup! { "Remove the "<Emphasis>"accessKey"</Emphasis>" attribute." }.to_owned(),
mutation,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::{services::aria::Aria, JsRuleAction};
use biome_analyze::{
context::RuleContext, declare_lint_rule, ActionCategory, FixKind, Rule, RuleDiagnostic,
RuleSource,
context::RuleContext, declare_lint_rule, FixKind, Rule, RuleDiagnostic, RuleSource,
};
use biome_console::markup;
use biome_js_syntax::{jsx_ext::AnyJsxElement, AnyJsxAttributeValue, AnyNumberLikeExpression};
Expand Down Expand Up @@ -141,7 +140,7 @@ impl Rule for NoAriaHiddenOnFocusable {
let aria_hidden_attr = node.find_attribute_by_name("aria-hidden")?;
mutation.remove_node(aria_hidden_attr);
Some(JsRuleAction::new(
ActionCategory::QuickFix,
ctx.metadata().action_category(ctx.category(), ctx.group()),
ctx.metadata().applicability(),
markup! { "Remove the aria-hidden attribute from the element." }.to_owned(),
mutation,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::{services::aria::Aria, JsRuleAction};
use biome_analyze::{
context::RuleContext, declare_lint_rule, ActionCategory, FixKind, Rule, RuleDiagnostic,
RuleSource,
context::RuleContext, declare_lint_rule, FixKind, Rule, RuleDiagnostic, RuleSource,
};
use biome_console::markup;
use biome_js_syntax::jsx_ext::AnyJsxElement;
Expand Down Expand Up @@ -146,7 +145,7 @@ impl Rule for NoAriaUnsupportedElements {
mutation.remove_node(attribute);

Some(JsRuleAction::new(
ActionCategory::QuickFix,
ctx.metadata().action_category(ctx.category(), ctx.group()),
ctx.metadata().applicability(),
markup! { "Remove the "<Emphasis>""{removed_attribute}""</Emphasis>" attribute." }
.to_owned(),
Expand Down
5 changes: 2 additions & 3 deletions crates/biome_js_analyze/src/lint/a11y/no_autofocus.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::JsRuleAction;
use biome_analyze::{
context::RuleContext, declare_lint_rule, ActionCategory, Ast, FixKind, Rule, RuleDiagnostic,
RuleSource,
context::RuleContext, declare_lint_rule, Ast, FixKind, Rule, RuleDiagnostic, RuleSource,
};
use biome_console::markup;
use biome_js_syntax::{jsx_ext::AnyJsxElement, JsxAttribute};
Expand Down Expand Up @@ -100,7 +99,7 @@ impl Rule for NoAutofocus {
}
mutation.remove_node(attr.clone());
Some(JsRuleAction::new(
ActionCategory::QuickFix,
ctx.metadata().action_category(ctx.category(), ctx.group()),
ctx.metadata().applicability(),
markup! { "Remove the "<Emphasis>"autoFocus"</Emphasis>" attribute." }.to_owned(),
mutation,
Expand Down
6 changes: 2 additions & 4 deletions crates/biome_js_analyze/src/lint/a11y/no_blank_target.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use crate::JsRuleAction;
use biome_analyze::context::RuleContext;
use biome_analyze::{
declare_lint_rule, ActionCategory, Ast, FixKind, Rule, RuleDiagnostic, RuleSource,
};
use biome_analyze::{declare_lint_rule, Ast, FixKind, Rule, RuleDiagnostic, RuleSource};
use biome_console::markup;
use biome_deserialize_macros::Deserializable;
use biome_js_factory::make::{
Expand Down Expand Up @@ -193,7 +191,7 @@ impl Rule for NoBlankTarget {
};

Some(JsRuleAction::new(
ActionCategory::QuickFix,
ctx.metadata().action_category(ctx.category(), ctx.group()),
ctx.metadata().applicability(),
message,
mutation,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use biome_analyze::context::RuleContext;
use biome_analyze::{
declare_lint_rule, ActionCategory, Ast, FixKind, Rule, RuleDiagnostic, RuleSource,
};
use biome_analyze::{declare_lint_rule, Ast, FixKind, Rule, RuleDiagnostic, RuleSource};
use biome_console::markup;
use biome_js_syntax::jsx_ext::AnyJsxElement;
use biome_js_syntax::*;
Expand Down Expand Up @@ -83,7 +81,7 @@ impl Rule for NoDistractingElements {
mutation.remove_node(element.clone());

Some(JsRuleAction::new(
ActionCategory::QuickFix,
ctx.metadata().action_category(ctx.category(), ctx.group()),
ctx.metadata().applicability(),
markup! { "Remove the '"{name.text_trimmed()}"' element." }.to_owned(),
mutation,
Expand Down
6 changes: 2 additions & 4 deletions crates/biome_js_analyze/src/lint/a11y/no_header_scope.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use biome_analyze::context::RuleContext;
use biome_analyze::{
declare_lint_rule, ActionCategory, Ast, FixKind, Rule, RuleDiagnostic, RuleSource,
};
use biome_analyze::{declare_lint_rule, Ast, FixKind, Rule, RuleDiagnostic, RuleSource};
use biome_console::markup;
use biome_js_syntax::jsx_ext::AnyJsxElement;
use biome_rowan::{AstNode, BatchMutationExt};
Expand Down Expand Up @@ -96,7 +94,7 @@ impl Rule for NoHeaderScope {
mutation.remove_node(scope_node);

Some(JsRuleAction::new(
ActionCategory::QuickFix,
ctx.metadata().action_category(ctx.category(), ctx.group()),
ctx.metadata().applicability(),
markup! { "Remove the "<Emphasis>"scope"</Emphasis>" attribute." }.to_owned(),
mutation,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::{services::aria::Aria, JsRuleAction};
use biome_analyze::{
context::RuleContext, declare_lint_rule, ActionCategory, FixKind, Rule, RuleDiagnostic,
RuleSource,
context::RuleContext, declare_lint_rule, FixKind, Rule, RuleDiagnostic, RuleSource,
};
use biome_console::markup;
use biome_js_syntax::jsx_ext::AnyJsxElement;
Expand Down Expand Up @@ -123,7 +122,7 @@ impl Rule for NoInteractiveElementToNoninteractiveRole {
let mut mutation = ctx.root().begin();
mutation.remove_node(role_attribute);
Some(JsRuleAction::new(
ActionCategory::QuickFix,
ctx.metadata().action_category(ctx.category(), ctx.group()),
ctx.metadata().applicability(),
markup! { "Remove the "<Emphasis>"role"</Emphasis>" attribute." }.to_owned(),
mutation,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::services::aria::Aria;
use crate::JsRuleAction;
use biome_analyze::context::RuleContext;
use biome_analyze::{declare_lint_rule, ActionCategory, FixKind, Rule, RuleDiagnostic, RuleSource};
use biome_analyze::{declare_lint_rule, FixKind, Rule, RuleDiagnostic, RuleSource};
use biome_console::markup;
use biome_js_syntax::jsx_ext::AnyJsxElement;
use biome_rowan::{AstNode, BatchMutationExt, TextRange};
Expand Down Expand Up @@ -116,7 +116,7 @@ impl Rule for NoNoninteractiveElementToInteractiveRole {
let mut mutation = ctx.root().begin();
mutation.remove_node(role_attribute);
Some(JsRuleAction::new(
ActionCategory::QuickFix,
ctx.metadata().action_category(ctx.category(), ctx.group()),
ctx.metadata().applicability(),
markup! { "Remove the "<Emphasis>"role"</Emphasis>" attribute." }.to_owned(),
mutation,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::{services::aria::Aria, JsRuleAction};
use biome_analyze::{
context::RuleContext, declare_lint_rule, ActionCategory, FixKind, Rule, RuleDiagnostic,
RuleSource,
context::RuleContext, declare_lint_rule, FixKind, Rule, RuleDiagnostic, RuleSource,
};
use biome_aria::AriaRoles;
use biome_console::markup;
Expand Down Expand Up @@ -130,7 +129,7 @@ impl Rule for NoNoninteractiveTabindex {

mutation.remove_node(tabindex_attribute);
Some(JsRuleAction::new(
ActionCategory::QuickFix,
ctx.metadata().action_category(ctx.category(), ctx.group()),
ctx.metadata().applicability(),
markup! { "Remove the "<Emphasis>"tabIndex"</Emphasis>" attribute." }.to_owned(),
mutation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ impl Rule for NoPositiveTabindex {
};

Some(JsRuleAction::new(
biome_analyze::ActionCategory::QuickFix,
ctx.metadata().action_category(ctx.category(), ctx.group()),
ctx.metadata().applicability(),
markup! { "Replace the "<Emphasis>"tableIndex"</Emphasis>" prop value with 0." }
.to_owned(),
Expand Down
5 changes: 2 additions & 3 deletions crates/biome_js_analyze/src/lint/a11y/no_redundant_roles.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::{services::aria::Aria, JsRuleAction};
use biome_analyze::{
context::RuleContext, declare_lint_rule, ActionCategory, FixKind, Rule, RuleDiagnostic,
RuleSource,
context::RuleContext, declare_lint_rule, FixKind, Rule, RuleDiagnostic, RuleSource,
};
use biome_aria::{roles::AriaRoleDefinition, AriaRoles};
use biome_console::markup;
Expand Down Expand Up @@ -107,7 +106,7 @@ impl Rule for NoRedundantRoles {
let mut mutation = ctx.root().begin();
mutation.remove_node(state.redundant_attribute.clone());
Some(JsRuleAction::new(
ActionCategory::QuickFix,
ctx.metadata().action_category(ctx.category(), ctx.group()),
ctx.metadata().applicability(),
markup! { "Remove the "<Emphasis>"role"</Emphasis>" attribute." }.to_owned(),
mutation,
Expand Down
6 changes: 2 additions & 4 deletions crates/biome_js_analyze/src/lint/a11y/use_anchor_content.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use biome_analyze::context::RuleContext;
use biome_analyze::{
declare_lint_rule, ActionCategory, Ast, FixKind, Rule, RuleDiagnostic, RuleSource,
};
use biome_analyze::{declare_lint_rule, Ast, FixKind, Rule, RuleDiagnostic, RuleSource};
use biome_console::markup;
use biome_js_syntax::jsx_ext::AnyJsxElement;
use biome_js_syntax::JsxElement;
Expand Down Expand Up @@ -144,7 +142,7 @@ impl Rule for UseAnchorContent {
mutation.remove_node(aria_hidden);

return Some(JsRuleAction::new(
ActionCategory::QuickFix,
ctx.metadata().action_category(ctx.category(), ctx.group()),
ctx.metadata().applicability(),
markup! { "Remove the "<Emphasis>"aria-hidden"</Emphasis>" attribute to allow the anchor element and its content visible to assistive technologies." }.to_owned(),
mutation,
Expand Down
Loading

0 comments on commit 041e825

Please sign in to comment.