Skip to content

Commit

Permalink
feat(linter) add fixer to jsx-props-no-spread-multi
Browse files Browse the repository at this point in the history
  • Loading branch information
camc314 committed Aug 23, 2024
1 parent 7961de5 commit c0bb241
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 10 deletions.
48 changes: 38 additions & 10 deletions crates/oxc_linter/src/rules/react/jsx_props_no_spread_multi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ use oxc_span::{Atom, Span};

use itertools::Itertools;

use crate::{context::LintContext, rule::Rule, utils::is_same_member_expression, AstNode};
use crate::{
context::LintContext,
fixer::{Fix, RuleFix},
rule::Rule,
utils::is_same_member_expression,
AstNode,
};

fn jsx_props_no_spread_multiple_identifiers_diagnostic(
spans: Vec<Span>,
Expand All @@ -20,6 +26,7 @@ fn jsx_props_no_spread_multiple_identifiers_diagnostic(

fn jsx_props_no_spread_multiple_member_expressions_diagnostic(spans: Vec<Span>) -> OxcDiagnostic {
OxcDiagnostic::warn("Disallow JSX prop spreading the same member expression multiple times.")
.with_help("Remove the first spread.")
.with_labels(spans)
}

Expand All @@ -45,7 +52,7 @@ declare_oxc_lint!(
/// ```
JsxPropsNoSpreadMulti,
correctness,
pending // TODO: add auto-fix to remove the first spread. Removing the second one would change program behavior.
fix
);

impl Rule for JsxPropsNoSpreadMulti {
Expand Down Expand Up @@ -82,18 +89,32 @@ impl Rule for JsxPropsNoSpreadMulti {
}

for (identifier_name, spans) in duplicate_spreads {
ctx.diagnostic(jsx_props_no_spread_multiple_identifiers_diagnostic(
spans,
identifier_name,
));
ctx.diagnostic_with_fix(
jsx_props_no_spread_multiple_identifiers_diagnostic(
spans.clone(),
identifier_name,
),
|_fixer| {
spans
.iter()
.rev()
.skip(1)
.map(|span| Fix::delete(*span))
.collect::<RuleFix<'a>>()
},
);
}

member_expressions.iter().tuple_combinations().for_each(
|((left, left_span), (right, right_span))| {
if is_same_member_expression(left, right, ctx) {
ctx.diagnostic(jsx_props_no_spread_multiple_member_expressions_diagnostic(
vec![*left_span, *right_span],
));
ctx.diagnostic_with_fix(
jsx_props_no_spread_multiple_member_expressions_diagnostic(vec![
*left_span,
*right_span,
]),
|fixer| fixer.delete_range(*left_span),
);
}
},
);
Expand Down Expand Up @@ -147,6 +168,13 @@ fn test() {
<div {...props} {...props} {...props} />
",
];
let fix = vec![
("<App {...props} {...props} />", "<App {...props} />"),
("<App {...props.foo} {...props.foo} />", "<App {...props.foo} />"),
("<App {...(props.foo.baz)} {...(props.foo.baz)} />", "<App {...(props.foo.baz)} />"),
(r#"<div {...props} a="a" {...props} />"#, r#"<div a="a" {...props} />"#),
("<div {...props} {...props} {...props} />", "<div {...props} />"),
];

Tester::new(JsxPropsNoSpreadMulti::NAME, pass, fail).test_and_snapshot();
Tester::new(JsxPropsNoSpreadMulti::NAME, pass, fail).expect_fix(fix).test_and_snapshot();
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ source: crates/oxc_linter/src/tester.rs
· ────────────── ──────────────
4
╰────
help: Remove the first spread.

eslint-plugin-react(jsx-props-no-spread-multi): Disallow JSX prop spreading the same member expression multiple times.
╭─[jsx_props_no_spread_multi.tsx:3:16]
Expand All @@ -25,6 +26,7 @@ source: crates/oxc_linter/src/tester.rs
· ──────────────────── ────────────────────
4
╰────
help: Remove the first spread.

eslint-plugin-react(jsx-props-no-spread-multi): Disallow JSX prop spreading the same identifier multiple times.
╭─[jsx_props_no_spread_multi.tsx:3:16]
Expand Down

0 comments on commit c0bb241

Please sign in to comment.