Skip to content

Commit bbb7eb1

Browse files
feat(linter): add auto-fix to react/forward-ref-uses-ref (#11342)
### Example ```jsx forwardRef(function(a) {}) // function(a) {} forwardRef((a) => {}) // (a) => {} ```
1 parent 01a4647 commit bbb7eb1

File tree

1 file changed

+29
-21
lines changed

1 file changed

+29
-21
lines changed

crates/oxc_linter/src/rules/react/forward_ref_uses_ref.rs

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use crate::{ContextHost, FrameworkFlags};
2-
use oxc_ast::{AstKind, ast::Expression};
2+
use oxc_ast::{
3+
AstKind,
4+
ast::{CallExpression, Expression},
5+
};
36
use oxc_diagnostics::OxcDiagnostic;
47
use oxc_macros::declare_oxc_lint;
58
use oxc_span::Span;
@@ -57,28 +60,21 @@ declare_oxc_lint!(
5760
ForwardRefUsesRef,
5861
react,
5962
correctness,
60-
pending
61-
// TODO: two ways to fix it: add `ref` param or remove `forwardRef` call
63+
fix
6264
);
6365

64-
fn check_forward_ref_inner(exp: &Expression, ctx: &LintContext) {
65-
match exp {
66-
Expression::ArrowFunctionExpression(f) => {
67-
if f.params.parameters_count() >= 2 || f.params.rest.is_some() {
68-
return;
69-
}
70-
ctx.diagnostic(forward_ref_uses_ref_diagnostic(f.span));
71-
}
72-
Expression::FunctionExpression(f) => {
73-
if f.params.parameters_count() >= 2 || f.params.rest.is_some() {
74-
return;
75-
}
76-
ctx.diagnostic(forward_ref_uses_ref_diagnostic(f.span));
77-
}
78-
// NOTE: Not sure whether to warn in `forwardRef(((props, ref) => null))` (with parentheses)
79-
// Expression::ParenthesizedExpression(p) => check_forward_ref_inner(&p.expression),
80-
_ => {}
66+
fn check_forward_ref_inner(exp: &Expression, call_expr: &CallExpression, ctx: &LintContext) {
67+
let (params, span) = match exp {
68+
Expression::ArrowFunctionExpression(f) => (&f.params, f.span),
69+
Expression::FunctionExpression(f) => (&f.params, f.span),
70+
_ => return,
71+
};
72+
if params.parameters_count() != 1 || params.rest.is_some() {
73+
return;
8174
}
75+
ctx.diagnostic_with_fix(forward_ref_uses_ref_diagnostic(span), |fixer| {
76+
fixer.replace_with(call_expr, exp)
77+
});
8278
}
8379

8480
impl Rule for ForwardRefUsesRef {
@@ -97,7 +93,7 @@ impl Rule for ForwardRefUsesRef {
9793
return; // SpreadElement like forwardRef(...x)
9894
};
9995

100-
check_forward_ref_inner(first_arg_as_exp, ctx);
96+
check_forward_ref_inner(first_arg_as_exp, call_expr, ctx);
10197
}
10298

10399
fn should_run(&self, ctx: &ContextHost) -> bool {
@@ -165,6 +161,9 @@ fn test() {
165161
import * as React from 'react'
166162
(props) => null;
167163
",
164+
"forwardRef(() => {})",
165+
"forwardRef(function () {})",
166+
"forwardRef(function (a, b, c) {})",
168167
];
169168

170169
let fail = vec![
@@ -198,10 +197,19 @@ fn test() {
198197
",
199198
];
200199

200+
let fix = vec![
201+
("forwardRef((a) => {})", "(a) => {}"),
202+
("forwardRef(a => {})", "a => {}"),
203+
("forwardRef(function (a) {})", "function (a) {}"),
204+
("forwardRef(function(a,) {})", "function(a,) {}"),
205+
("React.forwardRef(function(a) {})", "function(a) {}"),
206+
];
207+
201208
Tester::new(ForwardRefUsesRef::NAME, ForwardRefUsesRef::PLUGIN, pass, fail)
202209
.with_lint_options(LintOptions {
203210
framework_hints: FrameworkFlags::React,
204211
..LintOptions::default()
205212
})
213+
.expect_fix(fix)
206214
.test_and_snapshot();
207215
}

0 commit comments

Comments
 (0)