From 6c3d99a9519879bc0aa73d11feedc8defff8e82c Mon Sep 17 00:00:00 2001
From: Boshen <1430279+Boshen@users.noreply.github.com>
Date: Fri, 17 May 2024 14:20:08 +0000
Subject: [PATCH] fix(linter/jsx-no-undef): check for globals when an
identifier is undefined (#3331)
closes #3319
---
.../src/rules/react/jsx_no_undef.rs | 39 +++++++++++--------
1 file changed, 23 insertions(+), 16 deletions(-)
diff --git a/crates/oxc_linter/src/rules/react/jsx_no_undef.rs b/crates/oxc_linter/src/rules/react/jsx_no_undef.rs
index 57314e880..af2cb3844 100644
--- a/crates/oxc_linter/src/rules/react/jsx_no_undef.rs
+++ b/crates/oxc_linter/src/rules/react/jsx_no_undef.rs
@@ -1,8 +1,5 @@
use oxc_ast::{
- ast::{
- JSXElementName, JSXIdentifier, JSXMemberExpression, JSXMemberExpressionObject,
- JSXOpeningElement,
- },
+ ast::{JSXElementName, JSXIdentifier, JSXMemberExpression, JSXMemberExpressionObject},
AstKind,
};
use oxc_diagnostics::OxcDiagnostic;
@@ -39,12 +36,6 @@ declare_oxc_lint!(
correctness
);
-fn get_member_ident<'a>(expr: &'a JSXMemberExpression<'a>) -> &'a JSXIdentifier {
- match expr.object {
- JSXMemberExpressionObject::Identifier(ref ident) => ident,
- JSXMemberExpressionObject::MemberExpression(ref next_expr) => get_member_ident(next_expr),
- }
-}
fn get_resolvable_ident<'a>(node: &'a JSXElementName<'a>) -> Option<&'a JSXIdentifier> {
match node {
JSXElementName::Identifier(ref ident)
@@ -57,19 +48,29 @@ fn get_resolvable_ident<'a>(node: &'a JSXElementName<'a>) -> Option<&'a JSXIdent
}
}
+fn get_member_ident<'a>(expr: &'a JSXMemberExpression<'a>) -> &'a JSXIdentifier {
+ match &expr.object {
+ JSXMemberExpressionObject::Identifier(ident) => ident,
+ JSXMemberExpressionObject::MemberExpression(next_expr) => get_member_ident(next_expr),
+ }
+}
+
impl Rule for JsxNoUndef {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
- if let AstKind::JSXOpeningElement(JSXOpeningElement { name: el_name, .. }) = &node.kind() {
- if let Some(ident) = get_resolvable_ident(el_name) {
- if ident.name.as_str() == "this" {
+ if let AstKind::JSXOpeningElement(elem) = &node.kind() {
+ if let Some(ident) = get_resolvable_ident(&elem.name) {
+ let name = ident.name.as_str();
+ if name == "this" {
return;
}
- let jsx_scope_id = node.scope_id();
- for scope_id in ctx.scopes().ancestors(jsx_scope_id) {
- if ctx.scopes().has_binding(scope_id, &ident.name) {
+ for scope_id in ctx.scopes().ancestors(node.scope_id()) {
+ if ctx.scopes().has_binding(scope_id, name) {
return;
}
}
+ if ctx.globals().is_enabled(name) {
+ return;
+ }
ctx.diagnostic(jsx_no_undef_diagnostic(ident.name.as_str(), ident.span));
}
}
@@ -78,6 +79,8 @@ impl Rule for JsxNoUndef {
#[test]
fn test() {
+ use serde_json::json;
+
use crate::tester::Tester;
let pass = vec![
@@ -126,4 +129,8 @@ fn test() {
];
Tester::new(JsxNoUndef::NAME, pass, fail).test_and_snapshot();
+
+ let pass = vec![("let x = ;", None, Some(json!({ "globals": {"A": "readonly" } })))];
+ let fail = vec![("let x = ;", None, None)];
+ Tester::new(JsxNoUndef::NAME, pass, fail).test();
}