use super::{Context, LintRule};
use crate::handler::{Handler, Traverse};
use crate::tags::{self, Tags};
use crate::Program;
use deno_ast::view::{JSXElement, JSXElementChild, JSXFragment};
use deno_ast::SourceRanged;
#[derive(Debug)]
pub struct JSXNoUselessFragment;
const CODE: &str = "jsx-no-useless-fragment";
impl LintRule for JSXNoUselessFragment {
fn tags(&self) -> Tags {
&[tags::RECOMMENDED, tags::REACT, tags::JSX, tags::FRESH]
}
fn code(&self) -> &'static str {
CODE
}
fn lint_program_with_ast_view(
&self,
context: &mut Context,
program: Program,
) {
JSXNoUselessFragmentHandler.traverse(program, context);
}
}
const MESSAGE: &str = "Unnecessary Fragment detected";
const HINT: &str = "Remove this Fragment";
struct JSXNoUselessFragmentHandler;
impl Handler for JSXNoUselessFragmentHandler {
fn jsx_fragment(&mut self, node: &JSXFragment, ctx: &mut Context) {
if node.children.is_empty() {
ctx.add_diagnostic_with_hint(node.range(), CODE, MESSAGE, HINT);
} else if node.children.len() == 1 {
if let Some(
JSXElementChild::JSXElement(_) | JSXElementChild::JSXFragment(_),
) = &node.children.first()
{
ctx.add_diagnostic_with_hint(node.range(), CODE, MESSAGE, HINT);
}
}
}
fn jsx_element(&mut self, node: &JSXElement, ctx: &mut Context) {
for child in node.children {
if let JSXElementChild::JSXFragment(frag) = child {
ctx.add_diagnostic_with_hint(frag.range(), CODE, MESSAGE, HINT);
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn jsx_no_useless_fragment_valid() {
assert_lint_ok! {
JSXNoUselessFragment,
filename: "file:///foo.jsx",
r#"<><div /><div /></>"#,
r#"<>foo<div /></>"#,
r#"<>{foo}</>"#,
r#"<>{foo}bar</>"#,
};
}
#[test]
fn jsx_no_useless_fragment_invalid() {
assert_lint_err! {
JSXNoUselessFragment,
filename: "file:///foo.jsx",
r#"<></>"#: [
{
col: 0,
message: MESSAGE,
hint: HINT,
}
],
r#"<><div /></>"#: [
{
col: 0,
message: MESSAGE,
hint: HINT,
}
],
r#"<p>foo <>bar</></p>"#: [
{
col: 7,
message: MESSAGE,
hint: HINT,
}
],
r#"<p>foo <><div /><div /></></p>"#: [
{
col: 7,
message: MESSAGE,
hint: HINT,
}
],
};
}
}