From 1f3b143678cbbd7a32804529455d646b189c6462 Mon Sep 17 00:00:00 2001 From: Don Isaac Date: Mon, 12 Aug 2024 15:52:35 -0400 Subject: [PATCH] fix(linter/jsx-a11y): reduce false negatives for html-has-lang --- .../src/rules/jsx_a11y/html_has_lang.rs | 26 +++++++++++--- .../src/rules/jsx_a11y/img_redundant_alt.rs | 3 +- .../src/rules/jsx_a11y/no_redundant_roles.rs | 3 +- crates/oxc_linter/src/rules/jsx_a11y/scope.rs | 3 +- .../rules/jsx_a11y/tabindex_no_positive.rs | 3 +- .../src/snapshots/html_has_lang.snap | 35 +++++++++++++++++++ 6 files changed, 65 insertions(+), 8 deletions(-) diff --git a/crates/oxc_linter/src/rules/jsx_a11y/html_has_lang.rs b/crates/oxc_linter/src/rules/jsx_a11y/html_has_lang.rs index ed4612045f0e2e..c6aa85567f9e5d 100644 --- a/crates/oxc_linter/src/rules/jsx_a11y/html_has_lang.rs +++ b/crates/oxc_linter/src/rules/jsx_a11y/html_has_lang.rs @@ -1,5 +1,5 @@ use oxc_ast::{ - ast::{JSXAttributeItem, JSXAttributeValue, JSXElementName}, + ast::{JSXAttributeItem, JSXAttributeValue, JSXElementName, JSXExpression}, AstKind, }; use oxc_diagnostics::OxcDiagnostic; @@ -83,9 +83,19 @@ impl Rule for HtmlHasLang { fn is_valid_lang_prop(item: &JSXAttributeItem) -> bool { match get_prop_value(item) { - Some(JSXAttributeValue::ExpressionContainer(container)) => { - !container.expression.is_expression() || !container.expression.is_undefined() - } + Some(JSXAttributeValue::ExpressionContainer(container)) => match &container.expression { + JSXExpression::EmptyExpression(_) + | JSXExpression::NullLiteral(_) + | JSXExpression::BooleanLiteral(_) + | JSXExpression::NumericLiteral(_) => false, + JSXExpression::Identifier(id) => id.name != "undefined", + JSXExpression::StringLiteral(str) => !str.value.as_str().is_empty(), + JSXExpression::TemplateLiteral(t) => { + !t.expressions.is_empty() + || t.quasis.iter().filter(|q| !q.value.raw.is_empty()).count() > 0 + } + _ => true, + }, Some(JSXAttributeValue::StringLiteral(str)) => !str.value.as_str().is_empty(), _ => true, } @@ -109,6 +119,9 @@ fn test() { (r"
;", None, None, None), (r#""#, None, None, None), (r#""#, None, None, None), + (r#""#, None, None, None), + (r"", None, None, None), + (r"", None, None, None), (r";", None, None, None), (r";", None, None, None), (r";", None, None, None), @@ -119,6 +132,11 @@ fn test() { (r";", None, None, None), (r";", None, None, None), (r";", None, None, None), + (r";", None, None, None), + (r";", None, None, None), + (r";", None, None, None), + (r";", None, None, None), + (r";", None, None, None), (r#";"#, None, None, None), ("", None, Some(settings()), None), ]; diff --git a/crates/oxc_linter/src/rules/jsx_a11y/img_redundant_alt.rs b/crates/oxc_linter/src/rules/jsx_a11y/img_redundant_alt.rs index 9be533c2b9dbd2..680ca2491ee17b 100644 --- a/crates/oxc_linter/src/rules/jsx_a11y/img_redundant_alt.rs +++ b/crates/oxc_linter/src/rules/jsx_a11y/img_redundant_alt.rs @@ -18,7 +18,8 @@ use crate::{ }; fn img_redundant_alt_diagnostic(span0: Span) -> OxcDiagnostic { - OxcDiagnostic::warn("Redundant alt attribute.").with_help("Provide no redundant alt text for image. Screen-readers already announce `img` tags as an image. You don’t need to use the words `image`, `photo,` or `picture` (or any specified custom words) in the alt prop.").with_label(span0) + OxcDiagnostic::warn("Redundant alt attribute.") + .with_help("Provide no redundant alt text for image. Screen-readers already announce `img` tags as an image. You don’t need to use the words `image`, `photo,` or `picture` (or any specified custom words) in the alt prop.").with_label(span0) } #[derive(Debug, Default, Clone)] diff --git a/crates/oxc_linter/src/rules/jsx_a11y/no_redundant_roles.rs b/crates/oxc_linter/src/rules/jsx_a11y/no_redundant_roles.rs index 77670164dbc21e..481220df075acc 100644 --- a/crates/oxc_linter/src/rules/jsx_a11y/no_redundant_roles.rs +++ b/crates/oxc_linter/src/rules/jsx_a11y/no_redundant_roles.rs @@ -43,7 +43,8 @@ declare_oxc_lint!( ///