mirror of
https://github.com/oxc-project/oxc.git
synced 2026-09-14 19:36:11 +08:00
d09ccc9a7b
Simplified redo of #22295. Calling this a chore because I don't think it warrants mention in the changelog for now as this is just basic scaffolding changes, but we can mark it as a feature if preferred. AI Disclosure: generated with Claude Code, reviewed by me. The `short_description` field will be a one-sentence summary of the rule that can be used in documentation, and especially the rules list on the website. The idea would be to enable the rules list to include the short description as a subtitle under each rule, similar to this: <img width="1120" height="618" alt="image" src="https://github.com/user-attachments/assets/ff9e4d63-b61f-474e-9455-d3567c96d51c" /> The rule macros will now look like this: ```rs declare_oxc_lint!( /// Longer rule description here. MyRule, eslint, nursery, pending, config = MyRule, version = "next", info { short_description = "FIXME: One-sentence description of the rule.", }, ); ``` We could do `info = {` here instead of `info {`, up to the reviewers. I'll move `version` into the `info` field in a subsequent PR. I didn't do it here because I wanted to keep this simple and avoid problems of merge conflicts with the release tomorrow. The `info` field was suggested by camchenry to avoid continuing to bloat the size of the rule meta struct / rules enum file. In a subsequent PR I'll add the short_description to most rules using the same script as I used in #22295. Again, just keeping this simple / avoiding merge conflicts. --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Cameron Clark <cameron.clark@hey.com>
108 lines
3.2 KiB
Plaintext
108 lines
3.2 KiB
Plaintext
{{#if has_hash_map}}
|
|
use rustc_hash::FxHashMap;
|
|
{{/if}}
|
|
{{#if has_hash_set}}
|
|
use rustc_hash::FxHashSet;
|
|
{{/if}}
|
|
{{#if rule_config}}
|
|
use schemars::JsonSchema;
|
|
use serde::{Deserialize, Serialize};
|
|
{{/if}}
|
|
|
|
use oxc_diagnostics::OxcDiagnostic;
|
|
use oxc_macros::declare_oxc_lint;
|
|
use oxc_span::Span;
|
|
|
|
use crate::{
|
|
context::LintContext,
|
|
fixer::{RuleFix, RuleFixer},
|
|
{{#if rule_config}}rule::{DefaultRuleConfig, Rule},{{else}}rule::Rule,{{/if}}
|
|
AstNode,
|
|
};
|
|
|
|
fn {{snake_rule_name}}_diagnostic(span: Span) -> OxcDiagnostic {
|
|
// See <https://oxc.rs/docs/contribute/linter/adding-rules.html#diagnostics> for details
|
|
OxcDiagnostic::warn("Should be an imperative statement about what is wrong.")
|
|
.with_help("Should be a command-like statement that tells the user how to fix the issue.")
|
|
.with_label(span)
|
|
}
|
|
|
|
{{rule_config}}
|
|
|
|
#[derive(Debug, Default, Clone{{#if rule_config_tuple}}, Deserialize, Serialize, JsonSchema{{/if}})]
|
|
pub struct {{pascal_rule_name}}{{#if rule_config_tuple}}{{rule_config_tuple}}{{/if}};
|
|
|
|
// See <https://github.com/oxc-project/oxc/issues/6050> for documentation details.
|
|
declare_oxc_lint!(
|
|
/// ### What it does
|
|
///
|
|
/// FIXME: Briefly describe the rule's purpose.
|
|
///
|
|
/// ### Why is this bad?
|
|
///
|
|
/// FIXME: Explain why violating this rule is problematic.
|
|
///
|
|
/// ### Examples
|
|
///
|
|
/// Examples of **incorrect** code for this rule:
|
|
/// ```{{language}}
|
|
/// FIXME: Add at least one example of code that violates the rule.
|
|
/// ```
|
|
///
|
|
/// Examples of **correct** code for this rule:
|
|
/// ```{{language}}
|
|
/// FIXME: Add at least one example of code that is allowed with the rule.
|
|
/// ```
|
|
{{pascal_rule_name}},
|
|
{{mod_name}},
|
|
nursery, // TODO: change category to `correctness`, `suspicious`, `pedantic`, `perf`, `restriction`, or `style`
|
|
// See <https://oxc.rs/docs/contribute/linter.html#rule-category> for details
|
|
pending, // TODO: describe fix capabilities. Remove or set to `none` if no fix can be done,
|
|
// keep at 'pending' if you think one could be added but don't know how.
|
|
// Options are 'fix', 'fix_dangerous', 'suggestion', and 'conditional_fix_suggestion'
|
|
{{#if rule_config}}
|
|
config = {{pascal_rule_name}},
|
|
{{/if}}
|
|
version = "next",
|
|
short_description = "FIXME: One-sentence description of the rule.",
|
|
);
|
|
|
|
impl Rule for {{pascal_rule_name}} {
|
|
{{#if rule_config}}
|
|
fn from_configuration(value: serde_json::Value) -> Result<Self, serde_json::error::Error> {
|
|
serde_json::from_value::<DefaultRuleConfig<Self>>(value).map(DefaultRuleConfig::into_inner)
|
|
}
|
|
|
|
{{/if}}
|
|
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
|
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test() {
|
|
{{#if has_filename}}
|
|
use std::path::PathBuf;
|
|
|
|
{{/if}}
|
|
use crate::tester::Tester;
|
|
|
|
let pass = vec![
|
|
{{pass_cases}}
|
|
];
|
|
|
|
let fail = vec![
|
|
{{fail_cases}}
|
|
];
|
|
|
|
{{#if fix_cases}}
|
|
let fix = vec![
|
|
{{fix_cases}}
|
|
];
|
|
|
|
Tester::new({{pascal_rule_name}}::NAME, {{pascal_rule_name}}::PLUGIN, pass, fail).expect_fix(fix).test_and_snapshot();
|
|
{{else}}
|
|
Tester::new({{pascal_rule_name}}::NAME, {{pascal_rule_name}}::PLUGIN, pass, fail).test_and_snapshot();
|
|
{{/if}}
|
|
}
|