Skip to content

Commit 34bfaf6

Browse files
committedAug 23, 2024·
feat(linter/react): add fixer to jsx-props-no-spread-multi (#5145)
1 parent 5136f01 commit 34bfaf6

File tree

2 files changed

+40
-10
lines changed

2 files changed

+40
-10
lines changed
 

‎crates/oxc_linter/src/rules/react/jsx_props_no_spread_multi.rs

+38-10
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@ use oxc_span::{Atom, Span};
77

88
use itertools::Itertools;
99

10-
use crate::{context::LintContext, rule::Rule, utils::is_same_member_expression, AstNode};
10+
use crate::{
11+
context::LintContext,
12+
fixer::{Fix, RuleFix},
13+
rule::Rule,
14+
utils::is_same_member_expression,
15+
AstNode,
16+
};
1117

1218
fn jsx_props_no_spread_multiple_identifiers_diagnostic(
1319
spans: Vec<Span>,
@@ -20,6 +26,7 @@ fn jsx_props_no_spread_multiple_identifiers_diagnostic(
2026

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

@@ -45,7 +52,7 @@ declare_oxc_lint!(
4552
/// ```
4653
JsxPropsNoSpreadMulti,
4754
correctness,
48-
pending // TODO: add auto-fix to remove the first spread. Removing the second one would change program behavior.
55+
fix
4956
);
5057

5158
impl Rule for JsxPropsNoSpreadMulti {
@@ -82,18 +89,32 @@ impl Rule for JsxPropsNoSpreadMulti {
8289
}
8390

8491
for (identifier_name, spans) in duplicate_spreads {
85-
ctx.diagnostic(jsx_props_no_spread_multiple_identifiers_diagnostic(
86-
spans,
87-
identifier_name,
88-
));
92+
ctx.diagnostic_with_fix(
93+
jsx_props_no_spread_multiple_identifiers_diagnostic(
94+
spans.clone(),
95+
identifier_name,
96+
),
97+
|_fixer| {
98+
spans
99+
.iter()
100+
.rev()
101+
.skip(1)
102+
.map(|span| Fix::delete(*span))
103+
.collect::<RuleFix<'a>>()
104+
},
105+
);
89106
}
90107

91108
member_expressions.iter().tuple_combinations().for_each(
92109
|((left, left_span), (right, right_span))| {
93110
if is_same_member_expression(left, right, ctx) {
94-
ctx.diagnostic(jsx_props_no_spread_multiple_member_expressions_diagnostic(
95-
vec![*left_span, *right_span],
96-
));
111+
ctx.diagnostic_with_fix(
112+
jsx_props_no_spread_multiple_member_expressions_diagnostic(vec![
113+
*left_span,
114+
*right_span,
115+
]),
116+
|fixer| fixer.delete_range(*left_span),
117+
);
97118
}
98119
},
99120
);
@@ -147,6 +168,13 @@ fn test() {
147168
<div {...props} {...props} {...props} />
148169
",
149170
];
171+
let fix = vec![
172+
("<App {...props} {...props} />", "<App {...props} />"),
173+
("<App {...props.foo} {...props.foo} />", "<App {...props.foo} />"),
174+
("<App {...(props.foo.baz)} {...(props.foo.baz)} />", "<App {...(props.foo.baz)} />"),
175+
(r#"<div {...props} a="a" {...props} />"#, r#"<div a="a" {...props} />"#),
176+
("<div {...props} {...props} {...props} />", "<div {...props} />"),
177+
];
150178

151-
Tester::new(JsxPropsNoSpreadMulti::NAME, pass, fail).test_and_snapshot();
179+
Tester::new(JsxPropsNoSpreadMulti::NAME, pass, fail).expect_fix(fix).test_and_snapshot();
152180
}

‎crates/oxc_linter/src/snapshots/jsx_props_no_spread_multi.snap

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ source: crates/oxc_linter/src/tester.rs
1717
· ────────────── ──────────────
1818
4
1919
╰────
20+
help: Remove the first spread.
2021

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

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

0 commit comments

Comments
 (0)
Please sign in to comment.