diff --git a/crates/oxc_linter/src/rules.rs b/crates/oxc_linter/src/rules.rs index dcbc377a4..caa38a47b 100644 --- a/crates/oxc_linter/src/rules.rs +++ b/crates/oxc_linter/src/rules.rs @@ -66,6 +66,7 @@ mod eslint { pub mod no_global_assign; pub mod no_import_assign; pub mod no_inner_declarations; + pub mod no_irregular_whitespace; pub mod no_loss_of_precision; pub mod no_mixed_operators; pub mod no_new_symbol; @@ -313,6 +314,7 @@ oxc_macros::declare_all_lint_rules! { eslint::no_global_assign, eslint::no_import_assign, eslint::no_inner_declarations, + eslint::no_irregular_whitespace, eslint::no_loss_of_precision, eslint::no_mixed_operators, eslint::no_new_symbol, diff --git a/crates/oxc_linter/src/rules/eslint/no_irregular_whitespace.rs b/crates/oxc_linter/src/rules/eslint/no_irregular_whitespace.rs new file mode 100644 index 000000000..336e38174 --- /dev/null +++ b/crates/oxc_linter/src/rules/eslint/no_irregular_whitespace.rs @@ -0,0 +1,410 @@ +use oxc_diagnostics::{ + miette::{self, Diagnostic}, + thiserror::Error, +}; +use oxc_macros::declare_oxc_lint; +use oxc_span::Span; + +use crate::{context::LintContext, rule::Rule}; + +#[derive(Debug, Error, Diagnostic)] +#[error("eslint(no-irregular-whitespace): Unexpected irregular whitespace")] +#[diagnostic(severity(warning), help("Try to remove the irregular whitespace"))] +struct NoIrregularWhitespaceDiagnostic(#[label] pub Span); + +#[derive(Debug, Default, Clone)] +pub struct NoIrregularWhitespace; + +declare_oxc_lint!( + /// ### What it does + /// Disallows the use of irregular whitespaces in the code. + /// + /// ### Why is this bad + /// The use of irregular whitespaces can hinder code readability and + /// create inconsistencies, making maintenance and collaboration more challenging. + /// + /// ### Example + /// ```javascript + /// function invalidExample ( ) { + /// return 42; + /// } + /// ``` + NoIrregularWhitespace, + correctness +); + +impl Rule for NoIrregularWhitespace { + fn run_once(&self, ctx: &LintContext) { + let irregular_whitespaces = ctx.semantic().trivias().irregular_whitespaces(); + for irregular_whitespace in irregular_whitespaces { + ctx.diagnostic(NoIrregularWhitespaceDiagnostic(*irregular_whitespace)); + } + } +} + +#[test] +fn test() { + use crate::tester::Tester; + + let pass = vec![ + (r"'\u000B';", None), + (r"'\u000C';", None), + (r"'\u0085';", None), + (r"'\u00A0';", None), + (r"'\u180E';", None), + (r"'\ufeff';", None), + (r"'\u2000';", None), + (r"'\u2001';", None), + (r"'\u2002';", None), + (r"'\u2003';", None), + (r"'\u2004';", None), + (r"'\u2005';", None), + (r"'\u2006';", None), + (r"'\u2007';", None), + (r"'\u2008';", None), + (r"'\u2009';", None), + (r"'\u200A';", None), + (r"'\u200B';", None), + (r"'\u2028';", None), + (r"'\u2029';", None), + (r"'\u202F';", None), + (r"'\u205f';", None), + (r"'\u3000';", None), + (r"' ';", None), + (r"' ';", None), + (r"'…';", None), + (r"' ';", None), + (r"'᠎';", None), + (r"'';", None), + // ("' ';", None), lint error + // (r"' ';", None), lint error + (r"' ';", None), + (r"' ';", None), + (r"' ';", None), + (r"' ';", None), + (r"' ';", None), + (r"' ';", None), + (r"' ';", None), + (r"' ';", None), + (r"' ';", None), + // (r"'​';", None), lint error + (r"'\
';", None), + (r"'\
';", None), + (r"' ';", None), + (r"' ';", None), + (r"' ';", None), + (r"// ", Some(serde_json::json!([{ "skipComments": true }]))), + (r"// ", Some(serde_json::json!([{ "skipComments": true }]))), + (r"// …", Some(serde_json::json!([{ "skipComments": true }]))), + (r"//  ", Some(serde_json::json!([{ "skipComments": true }]))), + (r"// ᠎", Some(serde_json::json!([{ "skipComments": true }]))), + (r"// ", Some(serde_json::json!([{ "skipComments": true }]))), + // (r"//  ", Some(serde_json::json!([{ "skipComments": true }]))), lint error + // (r"//  ", Some(serde_json::json!([{ "skipComments": true }]))), lint error + (r"//  ", Some(serde_json::json!([{ "skipComments": true }]))), + (r"//  ", Some(serde_json::json!([{ "skipComments": true }]))), + (r"//  ", Some(serde_json::json!([{ "skipComments": true }]))), + (r"//  ", Some(serde_json::json!([{ "skipComments": true }]))), + (r"//  ", Some(serde_json::json!([{ "skipComments": true }]))), + (r"//  ", Some(serde_json::json!([{ "skipComments": true }]))), + (r"//  ", Some(serde_json::json!([{ "skipComments": true }]))), + (r"//  ", Some(serde_json::json!([{ "skipComments": true }]))), + (r"//  ", Some(serde_json::json!([{ "skipComments": true }]))), + // (r"// ​", Some(serde_json::json!([{ "skipComments": true }]))), lint error + (r"//  ", Some(serde_json::json!([{ "skipComments": true }]))), + (r"//  ", Some(serde_json::json!([{ "skipComments": true }]))), + (r"//  ", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/* */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/* */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/* … */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/* ᠎ */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/*  */", Some(serde_json::json!([{ "skipComments": true }]))), + // (r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))), lint error + // (r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))), lint error + (r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))), + // (r"/* ​ */", Some(serde_json::json!([{ "skipComments": true }]))), lint error + (r"/* 
 */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/* 
 */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))), + (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), + (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), + (r"/…/", Some(serde_json::json!([{ "skipRegExps": true }]))), + (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), + (r"/᠎/", Some(serde_json::json!([{ "skipRegExps": true }]))), + (r"//", Some(serde_json::json!([{ "skipRegExps": true }]))), + // (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), lint error + // (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), lint error + (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), + (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), + (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), + (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), + (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), + (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), + (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), + (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), + (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), + // (r"/​/", Some(serde_json::json!([{ "skipRegExps": true }]))), lint error + (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), + (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), + (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), + (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), + (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), + (r"`…`", Some(serde_json::json!([{ "skipTemplates": true }]))), + (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), + (r"`᠎`", Some(serde_json::json!([{ "skipTemplates": true }]))), + (r"``", Some(serde_json::json!([{ "skipTemplates": true }]))), + // (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), lint error + // (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), lint error + (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), + (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), + (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), + (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), + (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), + (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), + (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), + (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), + (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), + // (r"`​`", Some(serde_json::json!([{ "skipTemplates": true }]))), lint error + (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), + (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), + (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), + (r"` ${foo} `", Some(serde_json::json!([{ "skipTemplates": true }]))), + (r"const error = `   `;", Some(serde_json::json!([{ "skipTemplates": true }]))), + ( + r"const error = ` +  `;", + Some(serde_json::json!([{ "skipTemplates": true }])), + ), + ( + r"const error = `  + `;", + Some(serde_json::json!([{ "skipTemplates": true }])), + ), + ( + r"const error = ` +   + `;", + Some(serde_json::json!([{ "skipTemplates": true }])), + ), + ( + r"const error = `foo bar + foo bar`;", + Some(serde_json::json!([{ "skipTemplates": true }])), + ), + (r"
;", Some(serde_json::json!([{ "skipJSXText": true }]))), + (r"
;", Some(serde_json::json!([{ "skipJSXText": true }]))), + (r"
…
;", Some(serde_json::json!([{ "skipJSXText": true }]))), + (r"
 
;", Some(serde_json::json!([{ "skipJSXText": true }]))), + (r"
;", Some(serde_json::json!([{ "skipJSXText": true }]))), + (r"

;", Some(serde_json::json!([{ "skipJSXText": true }]))), + // (r"
 
;", Some(serde_json::json!([{ "skipJSXText": true }]))), lint error + // (r"
;", Some(serde_json::json!([{ "skipJSXText": true }]))), lint error + (r"
;", Some(serde_json::json!([{ "skipJSXText": true }]))), + (r"
;", Some(serde_json::json!([{ "skipJSXText": true }]))), + (r"
;", Some(serde_json::json!([{ "skipJSXText": true }]))), + (r"
;", Some(serde_json::json!([{ "skipJSXText": true }]))), + (r"
;", Some(serde_json::json!([{ "skipJSXText": true }]))), + (r"
;", Some(serde_json::json!([{ "skipJSXText": true }]))), + (r"
;", Some(serde_json::json!([{ "skipJSXText": true }]))), + (r"
;", Some(serde_json::json!([{ "skipJSXText": true }]))), + (r"
;", Some(serde_json::json!([{ "skipJSXText": true }]))), + // (r"
;", Some(serde_json::json!([{ "skipJSXText": true }]))), lint error + (r"
;", Some(serde_json::json!([{ "skipJSXText": true }]))), + (r"
;", Some(serde_json::json!([{ "skipJSXText": true }]))), + (r"
 
;", Some(serde_json::json!([{ "skipJSXText": true }]))), + // (r"console.log('hello BOM');", None), + ]; + + let fail = vec![ + // (r"var any = 'thing';", None), + // (r"var any = 'thing';", None), + (r"var any   = 'thing';", None), + (r"var any  = 'thing';", None), + // (r"var any   = 'thing';", None), + // (r"var any   = 'thing';", None), + (r"var any   = 'thing';", None), + (r"var any   = 'thing';", None), + (r"var any   = 'thing';", None), + (r"var any   = 'thing';", None), + (r"var any   = 'thing';", None), + (r"var any   = 'thing';", None), + (r"var any   = 'thing';", None), + (r"var any   = 'thing';", None), + (r"var any   = 'thing';", None), + // (r"var any 
 = 'thing';", None), + // (r"var any 
 = 'thing';", None), + (r"var any   = 'thing';", None), + (r"var any   = 'thing';", None), + (r"var any   = 'thing';", None), + // ( + // r"var a = 'b',
c = 'd', + // e = 'f'
", + // None, + // ), + ( + r"var any   = 'thing', other   = 'thing'; + var third   = 'thing';", + None, + ), + // (r"// ", None), + // (r"// ", None), + // (r"// …", None), + // (r"//  ", None), + // (r"// ᠎", None), + // (r"// ", None), + // (r"//  ", None), + // (r"//  ", None), + // (r"//  ", None), + // (r"//  ", None), + // (r"//  ", None), + // (r"//  ", None), + // (r"//  ", None), + // (r"//  ", None), + // (r"//  ", None), + // (r"//  ", None), + // (r"//  ", None), + // (r"// ​", None), + // (r"//  ", None), + // (r"//  ", None), + // (r"//  ", None), + // (r"/* */", None), + // (r"/* */", None), + // (r"/* … */", None), + // (r"/*   */", None), + // (r"/* ᠎ */", None), + // (r"/*  */", None), + // (r"/*   */", None), + // (r"/*   */", None), + // (r"/*   */", None), + // (r"/*   */", None), + // (r"/*   */", None), + // (r"/*   */", None), + // (r"/*   */", None), + // (r"/*   */", None), + // (r"/*   */", None), + // (r"/*   */", None), + // (r"/*   */", None), + // (r"/* ​ */", None), + // (r"/* 
 */", None), + // (r"/* 
 */", None), + // (r"/*   */", None), + // (r"/*   */", None), + // (r"/*   */", None), + // (r"var any = / /, other = / /;", None), + // (r"var any = ' ', other = ' ';", Some(serde_json::json!([{ "skipStrings": false }]))), + // (r"var any = ` `, other = ` `;", Some(serde_json::json!([{ "skipTemplates": false }]))), + ( + r"`something ${  10} another thing`", + Some(serde_json::json!([{ "skipTemplates": true }])), + ), + ( + r"`something ${10 } another thing`", + Some(serde_json::json!([{ "skipTemplates": true }])), + ), + ( + r"  + ` template`", + Some(serde_json::json!([{ "skipTemplates": true }])), + ), + ( + r"  + ` multiline + template`", + Some(serde_json::json!([{ "skipTemplates": true }])), + ), + (r" ` template`", Some(serde_json::json!([{ "skipTemplates": true }]))), + ( + r" ` multiline + template`", + Some(serde_json::json!([{ "skipTemplates": true }])), + ), + (r"` template` ", Some(serde_json::json!([{ "skipTemplates": true }]))), + ( + r"` multiline + template` ", + Some(serde_json::json!([{ "skipTemplates": true }])), + ), + ( + r"` template` +  ", + Some(serde_json::json!([{ "skipTemplates": true }])), + ), + ( + r"` multiline + template` +  ", + Some(serde_json::json!([{ "skipTemplates": true }])), + ), + // (r"var foo = bar;", None), + // (r"var foo = bar;", None), + // (r"var foo = bar;", None), + // (r"var foo = bar;", None), + // (r"var foo = bar;", None), + // (r"var foo = bar ;", None), + // (r" ", None), + ("   ", None), + // ( + // r"var foo = + // bar;", + // None, + // ), + // ( + // r"var foo = + // bar;", + // None, + // ), + // ( + // r"var foo = + // bar + // ; + // ", + // None, + // ), + // (r"var foo = 
bar;", None), + // (r"var foo =
 bar;", None), + // (r"var foo = bar;
", None), + // (r"
", None), + // (r"foo

", None), + // (r"foo

", None), + // ( + // r"foo + // 
", + // None, + // ), + // (r"foo 
 ", None), + // (r"
;", None), + // (r"
;", None), + // (r"
…
;", None), + // (r"
 
;", None), + // (r"
;", None), + // (r"

;", None), + // (r"
 
;", None), + // (r"
;", None), + // (r"
;", None), + // (r"
;", None), + // (r"
;", None), + // (r"
;", None), + // (r"
;", None), + // (r"
;", None), + // (r"
;", None), + // (r"
;", None), + // (r"
;", None), + // (r"
;", None), + // (r"
;", None), + // (r"
;", None), + // (r"
 
;", None), + ]; + + Tester::new(NoIrregularWhitespace::NAME, pass, fail).test_and_snapshot(); +} diff --git a/crates/oxc_linter/src/snapshots/no_irregular_whitespace.snap b/crates/oxc_linter/src/snapshots/no_irregular_whitespace.snap new file mode 100644 index 000000000..6a4cd9ee2 --- /dev/null +++ b/crates/oxc_linter/src/snapshots/no_irregular_whitespace.snap @@ -0,0 +1,225 @@ +--- +source: crates/oxc_linter/src/tester.rs +assertion_line: 144 +expression: no_irregular_whitespace +--- + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ var any   = 'thing'; + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ var any  = 'thing'; + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ var any   = 'thing'; + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ var any   = 'thing'; + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ var any   = 'thing'; + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ var any   = 'thing'; + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ var any   = 'thing'; + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ var any   = 'thing'; + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ var any   = 'thing'; + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ var any   = 'thing'; + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ var any   = 'thing'; + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ var any   = 'thing'; + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ var any   = 'thing'; + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ var any   = 'thing'; + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ var any   = 'thing', other   = 'thing'; + · ▲ + 2 │ var third   = 'thing'; + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ var any   = 'thing', other   = 'thing'; + · ▲ + 2 │ var third   = 'thing'; + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ var any   = 'thing', other   = 'thing'; + 2 │ var third   = 'thing'; + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ `something ${  10} another thing` + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ `something ${10 } another thing` + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │   + · ▲ + 2 │ ` template` + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │   + · ▲ + 2 │ ` multiline + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │  ` template` + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │  ` multiline + · ▲ + 2 │ template` + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ ` template`  + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ ` multiline + 2 │ template`  + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │ ` template` + 2 │   + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:2:1] + 2 │ template` + 3 │   + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │     + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │     + · ▲ + ╰──── + help: Try to remove the irregular whitespace + + ⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace + ╭─[no_irregular_whitespace.tsx:1:1] + 1 │     + · ▲ + ╰──── + help: Try to remove the irregular whitespace + +