diff --git a/.gitignore b/.gitignore index a22c530d36fd7..8931780ed21a9 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,21 @@ target/ /npm/*/node_modules /napi/*/npm-dir +# vscode +/editors/vscode/.vscode-test/ +/editors/vscode/node_modules/ +/editors/vscode/icon.png +/editors/vscode/out/ +/editors/vscode/*.vsix +/editors/vscode/test_workspace/ +/editors/vscode/test_workspace_second/ +/editors/vscode/*.test.code-workspace + +.vscode/settings.json + # Cloned conformance repos +tasks/coverage/acorn-test262-diff/ +tasks/coverage/acorn-test262/ tasks/coverage/babel/ tasks/coverage/test262/ tasks/coverage/typescript/ diff --git a/crates/oxc_linter/src/rules/eslint/no_warning_comments.rs b/crates/oxc_linter/src/rules/eslint/no_warning_comments.rs index 8b7964c706ab0..197852aa0dc14 100644 --- a/crates/oxc_linter/src/rules/eslint/no_warning_comments.rs +++ b/crates/oxc_linter/src/rules/eslint/no_warning_comments.rs @@ -1,237 +1,247 @@ use cow_utils::CowUtils; -use lazy_regex::{Regex, regex}; use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use rustc_hash::FxHashSet; -use serde_json::Value; use crate::{context::LintContext, rule::Rule}; -fn no_warning_comments_diagnostic(term: &str, comment: &str, span: Span) -> OxcDiagnostic { - const CHAR_LIMIT: usize = 40; - - let mut comment_to_display = String::new(); - let mut truncated = false; - - for word in comment.split_whitespace() { - let tmp = if comment_to_display.is_empty() { - word.to_string() - } else { - format!("{comment_to_display} {word}") - }; - - if tmp.len() <= CHAR_LIMIT { - comment_to_display = tmp; - } else { - truncated = true; - break; - } - } - - let display = if truncated { format!("{comment_to_display}...") } else { comment_to_display }; - - OxcDiagnostic::warn(format!("Unexpected '{term}' comment: {display}")) - .with_help("Remove or rephrase this comment") +fn no_with_diagnostic(span: Span) -> OxcDiagnostic { + OxcDiagnostic::warn("Unexpected use of `with` statement.") + .with_help("Do not use the `with` statement.") .with_label(span) } -#[derive(Debug, Clone)] -struct NoWarningCommentsConfig { - terms: Vec, - patterns: Vec, -} - -#[derive(Debug, Clone, PartialEq, Eq)] -enum Location { - Start, - Anywhere, +#[derive(Debug, Default, Clone)] +pub struct NoWarningCommentsConfig { + terms: Option>, + decorations: Option>, + location: Option, } - -#[derive(Debug, Clone)] +#[derive(Debug, Default, Clone)] pub struct NoWarningComments(Box); -impl Default for NoWarningComments { - fn default() -> Self { - let terms = vec!["todo".to_string(), "fixme".to_string(), "xxx".to_string()]; - let location = Location::Start; - let decoration = FxHashSet::default(); - Self::new(&terms, &location, &decoration) - } -} - +// See for documentation details. declare_oxc_lint!( /// ### What it does /// - /// Disallows warning comments such as TODO, FIXME, XXX in code. + /// Briefly describe the rule's purpose. /// /// ### Why is this bad? /// - /// Developers often add comments like TODO or FIXME to mark incomplete work or areas - /// that need attention. While useful during development, these comments can indicate - /// unfinished code that shouldn't be shipped to production. This rule helps catch - /// such comments before they make it into production code. + /// Explain why violating this rule is problematic. /// /// ### Examples /// /// Examples of **incorrect** code for this rule: - /// ```javascript - /// // TODO: implement this feature - /// function doSomething() {} - /// - /// // FIXME: this is broken - /// const x = 1; - /// - /// /* XXX: hack */ - /// let y = 2; + /// ```js + /// FIXME: Tests will fail if examples are missing or syntactically incorrect. /// ``` /// /// Examples of **correct** code for this rule: - /// ```javascript - /// // This is a regular comment - /// function doSomething() {} - /// - /// // Note: This explains something - /// const x = 1; - /// ``` - /// - /// ### Options - /// - /// This rule has an options object with the following defaults: - /// - /// ```json - /// { - /// "terms": ["todo", "fixme", "xxx"], - /// "location": "start", - /// "decoration": [] - /// } + /// ```js + /// FIXME: Tests will fail if examples are missing or syntactically incorrect. /// ``` - /// - /// #### `terms` - /// - /// An array of terms to match. The matching is case-insensitive. - /// - /// #### `location` - /// - /// Where to check for the terms: - /// - `"start"` (default): Terms must appear at the start of the comment (after any decoration) - /// - `"anywhere"`: Terms can appear anywhere in the comment - /// - /// #### `decoration` - /// - /// An array of characters to ignore at the start of comments when `location` is `"start"`. - /// Useful for ignoring common comment decorations like `*` in JSDoc-style comments. NoWarningComments, eslint, - pedantic, - // TODO: Replace this with an actual config struct. This is a dummy value to - // indicate that this rule has configuration and avoid errors. - config = Value, + nursery, // TODO: change category to `correctness`, `suspicious`, `pedantic`, `perf`, `restriction`, or `style` + // See for details + pending // TODO: describe fix capabilities. Remove if no fix can be done, + // keep at 'pending' if you think one could be added but don't know how. + // Options are 'fix', 'fix_dangerous', 'suggestion', and 'conditional_fix_suggestion' ); -impl Rule for NoWarningComments { - fn from_configuration(value: serde_json::Value) -> Result { - let config = value.get(0); - - let terms = config.and_then(|v| v.get("terms")).and_then(|v| v.as_array()).map_or_else( - || vec!["todo".to_string(), "fixme".to_string(), "xxx".to_string()], - |arr| { - arr.iter() - .filter_map(|v| v.as_str()) - .map(|s| s.cow_to_lowercase().into_owned()) - .collect::>() - }, - ); - - let location = config.and_then(|v| v.get("location")).and_then(|v| v.as_str()).map_or( - Location::Start, - |s| { - if s.eq_ignore_ascii_case("anywhere") { - Location::Anywhere - } else { - Location::Start - } - }, - ); - - let decoration = config - .and_then(|v| v.get("decoration")) - .and_then(|v| v.as_array()) - .map(|arr| { - arr.iter().filter_map(|v| v.as_str()).map(str::to_string).collect::>() - }) - .unwrap_or_default(); - - Ok(Self::new(&terms, &location, &decoration)) +// Refactor this function to make it more Rusty +fn trim_decorations_until_terms<'a>( + s: &'a str, // can accept string slice as input; not an owned String + decorations: &[String], // slice of string slices + terms: &[String], // slice of string slices +) -> &'a str { + // return a slice of the original string (&'a str) without copying + let mut i = 0; + let s_len = s.len(); + while i < s_len { + if terms.is_empty() { + break; + } + if terms.iter().any(|term| s[i..].starts_with(term)) { + break; // stop if a term matches + } + let c = s[i..].chars().next().unwrap(); + if decorations.iter().any(|d| *d == c.to_string()) { + i += c.len_utf8(); // keep going with the loop + } else { + break; // stop if non-decoration + } } + &s[i..] // new slice from position i +} + +/// Checks if any word matches the term, including non-alphanumeric characters. +/// if term is "todo", it matches "todo", "todo!", "(todo)", etc. +/// This is done by checking if the term is a substring of any word. +/// if word is todoMVC and term is todo it will not match. +/// This function is not working correctly so we need to go through the various options. +/// --- "/* eslint one-var: 2 */" --- +fn any_word_matches_term(words: &[String], term: &str) -> bool { + let term_lower = term.cow_to_lowercase(); + // let is_term_alnum = term_lower.chars().all(|c| c.is_alphanumeric()); + words.iter().any(|word| { + // term is alphanumeric, word is alphanumeric, check for exact match ; todo && todoMVC => todo == todoMVC + // term is alphanumeric, word is not alphanumeric, check for contains ; todo && todo! => todo! contains todo + + let word_lower = word.cow_to_lowercase(); + let is_word_alnum = word_lower.chars().all(char::is_alphanumeric); + if is_word_alnum { word_lower == term_lower } else { word_lower.contains(&*term_lower) } + }) +} +// https://eslint.org/docs/latest/rules/no-warning-comments#options +// if location is "start" then ignore decorators, if "anywhere" then do not ignore decorators. If location is not provided then default to "start". +impl Rule for NoWarningComments { fn run_once(&self, ctx: &LintContext) { - for comment in ctx.semantic().comments() { - let comment_text = ctx.source_range(comment.content_span()); + ctx.semantic().comments().iter().for_each(|comment| { + let span = comment.span; + let span_pointers: (u32, u32) = (span.start + 2, span.end); + let comment_text = ctx + .source_text() + .get((span_pointers.0 as usize)..(span_pointers.1 as usize)) + .unwrap() + .cow_to_lowercase(); + + // it would be better to strip comments with no-warning-comments if comment_text.contains("no-warning-comments") { - continue; + return; } - if let Some(matched_term) = self.matches_warning_term(comment_text) { - ctx.diagnostic(no_warning_comments_diagnostic( - matched_term, - comment_text, - comment.span, - )); + // If there are no decorations it returns none so we need to match it otherwise it panics + let cleaned_text = match &self.0.decorations { + Some(decorations) => { + let empty_vec: Vec = Vec::new(); + trim_decorations_until_terms( + &comment_text, + decorations, + self.0.terms.as_ref().unwrap_or(&empty_vec), + ) + } + None => &comment_text, + }; + + // We have handled ("//!TODO ", Some(serde_json::json!([{ "decoration": ["*"] }]))) + // But it made the following to fail: Some(serde_json::json!([{ "terms": ["[litera|$]"], "location": "anywhere" }])), + let words = cleaned_text + .split_whitespace() + // .split(|c: char| !c.is_alphanumeric()) + .filter(|w| !w.is_empty()) + .map(|w| cow_utils::CowUtils::cow_to_lowercase(w).into_owned()) + .collect::>(); + + // performance might be an issue here with nested loops. Look at refactoring not with regex. + + // if the terms exist in the comment text then report a diagnostic + // if there are no terms then use default terms + if let Some(terms) = &self.0.terms { + for term in terms { + if any_word_matches_term(&words, term) { + ctx.diagnostic(no_with_diagnostic(span)); + } + } + } else { + let default_terms = vec!["todo", "fixme", "xxx"]; + for term in default_terms { + match &self.0.location { + Some(location) => { + if location == "start" { + if words[0] != term.cow_to_lowercase() {} + } else if any_word_matches_term(&words, term) { + ctx.diagnostic(no_with_diagnostic(span)); + } + } + None => { + if words[0] == term.cow_to_lowercase() { + ctx.diagnostic(no_with_diagnostic(span)); + } + } + } + } } - } + // 24/10/25 there is an issue with the location + // if you do not have location set to anywhere it will use the default of start + // if the location is start we should start with rather than contains + }); + + // 1. create a copy of the source code x + // 2. create a copy of the decoration, location and terms. We can get these from the configuration using the from_config function x + // 3. escape the decoration special characters. Decoration can be a string or an array of strings. x + // if it is a line comment, skip // first + // if it is a block comment, skip /* first: we are not there yet. + // escape each decoration character until you reach a non-decoration character or the term itself, e.g. *todo + // 4. creates a constant of /\bno-warning-comments\b/u + // 5. for each of the warning terms it converts the term to a regular expression: + // - escape the term special characters + // - create a constant of the word boundary which is \\b + // - create a variable for the prefix + // - if the location is "start" then it sets prefix to the escaped decoration `^[\\s${escapedDecoration}]*` + // - tests /^\w/u against the term and if they match sets the prefix to the word boundary + // - sets a constant for the suffix by running a test /\w$/u against the term if true sets suffix to word boundary otherwise sets suffix to an empty string + // - creates a constant for flag of "iu" + // - returns a regular expression with the prefix, term, and suffix passing in the flags + // 6. creates a constant comments which gets all of the comments from the source code using the ast comments. Gets all of the tree nodes that are comments. + // 7. for each comment: + // - filters out any comments which start with shebang #! + // - runs the check comment function. + // 8. check comment function: + // - sets a constant for the comment text which is node.value + // - if it is a directive comment e.g. eslint-disable-next-line or selfConfigRegEx it returns early + // - creates a constant of the matches containing the warning terms. Which is a list of warning terms. + // - for each match: + // - takes the comment and splits it by spaces + // - adds the comment to the comment that will be displayed + // - if the line is longer than 40 characters it will be truncated with an ellipsis + // - it will report the message to the context with messageId unexpectedCooment with the data being the matched term and the comment but if it is too long it is truncated to 40 characters with an ellipsis } -} -impl NoWarningComments { - fn new(terms: &[String], location: &Location, decoration: &FxHashSet) -> Self { - let patterns = Self::build_patterns(terms, location, decoration); - Self(Box::new(NoWarningCommentsConfig { terms: terms.to_vec(), patterns })) - } + // this could do with a tidy up. + fn from_configuration(value: serde_json::Value) -> Self { + // Read the configuration for term, decoration and location from _value and then + // return NoWarningComments {} struct with the attributes terms, decoration and locations. - fn build_patterns( - terms: &[String], - location: &Location, - decoration: &FxHashSet, - ) -> Vec { - let decoration_chars: String = decoration.iter().map(|s| regex::escape(s)).collect(); + // TODO: Create. NoWarningCommentsConfig struct and box it inside the return struct NoWarningCommentsConfig + // See crates/oxc_linter/src/rules/eslint/default_case.rs. - terms - .iter() - .filter_map(|term| { - let ends_with_word = - term.chars().last().is_some_and(|c| c.is_alphanumeric() || c == '_'); - let suffix = if ends_with_word { r"\b" } else { "" }; - let escaped_term = regex::escape(term); + let mut cfg = NoWarningCommentsConfig::default(); - let pattern = match location { - Location::Start => { - format!(r"(?i)^[\s{decoration_chars}]*{escaped_term}{suffix}") - } - Location::Anywhere => { - let starts_with_word = - term.chars().next().is_some_and(|c| c.is_alphanumeric() || c == '_'); - let prefix = if starts_with_word { r"\b" } else { "" }; + if let Some(config) = value.get(0) { + if let Some(terms_config) = config.get("terms") { + cfg.terms = terms_config.as_array().map(|arr| { + arr.iter() + .filter_map(|v| v.as_str().map(std::string::ToString::to_string)) + .collect::>() + }); + } - format!(r"(?i){prefix}{escaped_term}{suffix}") - } - }; + if let Some(decorations_config) = config.get("decoration") { + cfg.decorations = decorations_config.as_array().map(|arr| { + arr.iter() + .filter_map(|v| v.as_str().map(std::string::ToString::to_string)) + .collect::>() + }); + } - Regex::new(&pattern).ok() - }) - .collect() - } + if let Some(location_config) = config.get("location") { + cfg.location = location_config.as_str().map(std::string::ToString::to_string); + } else { + // Default to "start" if location is not provided + cfg.location = Some("start".to_string()); + } + } - fn matches_warning_term(&self, comment_text: &str) -> Option<&str> { - self.0 - .terms - .iter() - .zip(&self.0.patterns) - .find_map(|(term, pattern)| pattern.is_match(comment_text).then_some(term.as_str())) + Self(Box::new(cfg)) } } +// cargo insta accept +// cargo test -p oxc_linter -- --nocapture no_warning_comments #[test] fn test() { use crate::tester::Tester; @@ -267,31 +277,27 @@ fn test() { ( r#"/*eslint no-warning-comments: [2, { "terms": ["todo", "fixme", "any other term"], "location": "anywhere" }]*/ - var x = 10; - "#, + var x = 10; + "#, None, ), ( r#"/*eslint no-warning-comments: [2, { "terms": ["todo", "fixme", "any other term"], "location": "anywhere" }]*/ - var x = 10; - "#, + var x = 10; + "#, Some(serde_json::json!([{ "location": "anywhere" }])), ), ("// foo", Some(serde_json::json!([{ "terms": ["foo-bar"] }]))), ( "/** multi-line block comment with lines starting with - TODO - FIXME or - XXX - */", + TODO + FIXME or + XXX + */", None, ), ("//!TODO ", Some(serde_json::json!([{ "decoration": ["*"] }]))), - ( - "// not a todo! here", - Some(serde_json::json!([{ "terms": ["todo!"], "location": "start" }])), // additional test not in ESLint - ), ]; let fail = vec![ @@ -344,8 +350,8 @@ fn test() { ), ( "/** - *any block comment - *with (TODO, FIXME's or XXX!) **/", + *any block comment + *with (TODO, FIXME's or XXX!) **/", Some(serde_json::json!([{ "location": "anywhere" }])), ), ( @@ -359,8 +365,8 @@ fn test() { ), ( "/* TODO: something - really longer than 40 characters - and also a new line */", + really longer than 40 characters + and also a new line */", Some(serde_json::json!([{ "location": "anywhere" }])), ), ("// TODO: small", Some(serde_json::json!([{ "location": "anywhere" }]))), @@ -372,6 +378,7 @@ fn test() { "// Comment ending with term followed by punctuation TODO!", Some(serde_json::json!([{ "terms": ["todo"], "location": "anywhere" }])), ), + // // this test is now failing ... ( "// Comment ending with term including punctuation TODO!", Some(serde_json::json!([{ "terms": ["todo!"], "location": "anywhere" }])), @@ -410,20 +417,20 @@ fn test() { ), ( "/* - TODO undecorated multi-line block comment (start) - */", + TODO undecorated multi-line block comment (start) + */", Some(serde_json::json!([{ "terms": ["todo"], "location": "start" }])), ), ( "///// TODO decorated single-line comment with decoration array - /////", + /////", Some( serde_json::json!([ { "terms": ["todo"], "location": "start", "decoration": ["*", "/"] }, ]), ), ), ( "///*/*/ TODO decorated single-line comment with multiple decoration characters (start) - /////", + /////", Some( serde_json::json!([ { "terms": ["todo"], "location": "start", "decoration": ["*", "/"] }, ]), ), @@ -434,10 +441,6 @@ fn test() { serde_json::json!([ { "terms": ["*todo"], "location": "start", "decoration": ["*"] }, ]), ), ), - ( - "// todo! with punctuation at start", - Some(serde_json::json!([{ "terms": ["todo!"], "location": "start" }])), - ), // additional test not in ESLint ]; Tester::new(NoWarningComments::NAME, NoWarningComments::PLUGIN, pass, fail).test_and_snapshot(); diff --git a/crates/oxc_linter/src/snapshots/eslint_no_warning_comments.snap b/crates/oxc_linter/src/snapshots/eslint_no_warning_comments.snap index 23e63c29e65ed..44133248f50a8 100644 --- a/crates/oxc_linter/src/snapshots/eslint_no_warning_comments.snap +++ b/crates/oxc_linter/src/snapshots/eslint_no_warning_comments.snap @@ -1,302 +1,380 @@ --- source: crates/oxc_linter/src/tester.rs --- - - ⚠ eslint(no-warning-comments): Unexpected 'fixme' comment: fixme + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // fixme · ──────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'fixme' comment: any fixme + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // any fixme · ──────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'fixme' comment: any fixme + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // any fixme · ──────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'fixme' comment: any FIXME + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // any FIXME · ──────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'fixme' comment: any fIxMe + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // any fIxMe · ──────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'fixme' comment: any fixme + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ /* any fixme */ · ─────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'fixme' comment: any FIXME + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ /* any FIXME */ · ─────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'fixme' comment: any fIxMe + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ /* any fIxMe */ · ─────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'fixme' comment: any fixme or todo + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // any fixme or todo · ──────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'fixme' comment: any fixme or todo + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. + ╭─[no_warning_comments.tsx:1:1] + 1 │ // any fixme or todo + · ──────────────────── + ╰──── + help: Do not use the `with` statement. + + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ /* any fixme or todo */ · ─────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo' comment: any fixme or todo + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ /* any fixme or todo */ · ─────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'fixme' comment: fixme and todo + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. + ╭─[no_warning_comments.tsx:1:1] + 1 │ /* any fixme or todo */ + · ─────────────────────── + ╰──── + help: Do not use the `with` statement. + + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. + ╭─[no_warning_comments.tsx:1:1] + 1 │ /* any fixme or todo */ + · ─────────────────────── + ╰──── + help: Do not use the `with` statement. + + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ /* fixme and todo */ · ──────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo' comment: fixme and todo + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ /* fixme and todo */ · ──────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'fixme' comment: any fixme + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. + ╭─[no_warning_comments.tsx:1:1] + 1 │ /* fixme and todo */ + · ──────────────────── + ╰──── + help: Do not use the `with` statement. + + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ /* any fixme */ · ─────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'fixme' comment: fixme! + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ /* fixme! */ · ──────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected '[litera|$]' comment: regex [litera|$] + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // regex [litera|$] · ─────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'eslint' comment: eslint one-var: 2 + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ /* eslint one-var: 2 */ · ─────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'one' comment: eslint one-var: 2 + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ /* eslint one-var: 2 */ · ─────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. + + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. + ╭─[no_warning_comments.tsx:1:1] + 1 │ /* any block comment with TODO, FIXME or XXX */ + · ─────────────────────────────────────────────── + ╰──── + help: Do not use the `with` statement. + + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. + ╭─[no_warning_comments.tsx:1:1] + 1 │ /* any block comment with TODO, FIXME or XXX */ + · ─────────────────────────────────────────────── + ╰──── + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo' comment: any block comment with TODO, FIXME or... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ /* any block comment with TODO, FIXME or XXX */ · ─────────────────────────────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. + + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. + ╭─[no_warning_comments.tsx:1:1] + 1 │ /* any block comment with (TODO, FIXME's or XXX!) */ + · ──────────────────────────────────────────────────── + ╰──── + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo' comment: any block comment with (TODO, FIXME's or... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ /* any block comment with (TODO, FIXME's or XXX!) */ · ──────────────────────────────────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo' comment: * *any block comment *with (TODO,... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. + ╭─[no_warning_comments.tsx:1:1] + 1 │ /* any block comment with (TODO, FIXME's or XXX!) */ + · ──────────────────────────────────────────────────── + ╰──── + help: Do not use the `with` statement. + + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ ╭─▶ /** 2 │ │ *any block comment 3 │ ╰─▶ *with (TODO, FIXME's or XXX!) **/ ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo' comment: any comment with TODO, FIXME or XXX + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. + ╭─[no_warning_comments.tsx:1:1] + 1 │ ╭─▶ /** + 2 │ │ *any block comment + 3 │ ╰─▶ *with (TODO, FIXME's or XXX!) **/ + ╰──── + help: Do not use the `with` statement. + + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. + ╭─[no_warning_comments.tsx:1:1] + 1 │ ╭─▶ /** + 2 │ │ *any block comment + 3 │ ╰─▶ *with (TODO, FIXME's or XXX!) **/ + ╰──── + help: Do not use the `with` statement. + + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. + ╭─[no_warning_comments.tsx:1:1] + 1 │ // any comment with TODO, FIXME or XXX + · ────────────────────────────────────── + ╰──── + help: Do not use the `with` statement. + + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // any comment with TODO, FIXME or XXX · ────────────────────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo' comment: TODO: something small + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. + ╭─[no_warning_comments.tsx:1:1] + 1 │ // any comment with TODO, FIXME or XXX + · ────────────────────────────────────── + ╰──── + help: Do not use the `with` statement. + + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // TODO: something small · ──────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo' comment: TODO: something really longer than 40... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // TODO: something really longer than 40 characters · ─────────────────────────────────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo' comment: TODO: something really longer than 40... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ ╭─▶ /* TODO: something 2 │ │ really longer than 40 characters 3 │ ╰─▶ and also a new line */ ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo' comment: TODO: small + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // TODO: small · ────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo' comment: ... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // https://github.com/eslint/eslint/pull/13522#discussion_r470293411 TODO · ───────────────────────────────────────────────────────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo' comment: Comment ending with term followed by... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // Comment ending with term followed by punctuation TODO! · ───────────────────────────────────────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo!' comment: Comment ending with term including... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // Comment ending with term including punctuation TODO! · ─────────────────────────────────────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo!' comment: Comment ending with term including... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // Comment ending with term including punctuation followed by more TODO!!! · ────────────────────────────────────────────────────────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo' comment: !TODO comment starting with term... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // !TODO comment starting with term preceded by punctuation · ─────────────────────────────────────────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected '!todo' comment: !TODO comment starting with term... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // !TODO comment starting with term including punctuation · ───────────────────────────────────────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected '!todo' comment: !!!TODO comment starting with term... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // !!!TODO comment starting with term including punctuation preceded by more · ──────────────────────────────────────────────────────────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'fix!' comment: FIX!term ending with punctuation... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // FIX!term ending with punctuation followed word character · ─────────────────────────────────────────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected '!fix' comment: Term starting with punctuation preceded... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ // Term starting with punctuation preceded word character!FIX · ───────────────────────────────────────────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected '!xxx' comment: !XXX comment starting with no spaces... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ //!XXX comment starting with no spaces (anywhere) · ───────────────────────────────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected '!xxx' comment: !XXX comment starting with no spaces... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ //!XXX comment starting with no spaces (start) · ────────────────────────────────────────────── ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo' comment: TODO undecorated multi-line block... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ ╭─▶ /* 2 │ │ TODO undecorated multi-line block comment (start) 3 │ ╰─▶ */ ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo' comment: /// TODO decorated single-line comment... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ ///// TODO decorated single-line comment with decoration array · ────────────────────────────────────────────────────────────── 2 │ ///// ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected 'todo' comment: /*/*/ TODO decorated single-line comment... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ ///*/*/ TODO decorated single-line comment with multiple decoration characters (start) · ────────────────────────────────────────────────────────────────────────────────────── 2 │ ///// ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement. - ⚠ eslint(no-warning-comments): Unexpected '*todo' comment: **TODO term starts with a decoration... + ⚠ eslint(no-warning-comments): Unexpected use of `with` statement. ╭─[no_warning_comments.tsx:1:1] 1 │ //**TODO term starts with a decoration character · ──────────────────────────────────────────────── ╰──── - help: Remove or rephrase this comment - - ⚠ eslint(no-warning-comments): Unexpected 'todo!' comment: todo! with punctuation at start - ╭─[no_warning_comments.tsx:1:1] - 1 │ // todo! with punctuation at start - · ────────────────────────────────── - ╰──── - help: Remove or rephrase this comment + help: Do not use the `with` statement.