diff --git a/.changeset/fixanalyzer_suppression_comment_fails_with_inner_comments_in_functions.md b/.changeset/fixanalyzer_suppression_comment_fails_with_inner_comments_in_functions.md new file mode 100644 index 000000000000..ef0c048213ca --- /dev/null +++ b/.changeset/fixanalyzer_suppression_comment_fails_with_inner_comments_in_functions.md @@ -0,0 +1,5 @@ +--- +biome_analyze: patch +--- + +# fix suppression comment fails with inner comments in functions diff --git a/crates/biome_analyze/src/lib.rs b/crates/biome_analyze/src/lib.rs index 9cfd53d5dc27..d5604a14e99b 100644 --- a/crates/biome_analyze/src/lib.rs +++ b/crates/biome_analyze/src/lib.rs @@ -2,7 +2,6 @@ use biome_console::markup; use biome_parser::AnyParse; -use std::cmp::Ordering; use std::collections::{BTreeMap, BinaryHeap}; use std::fmt::{Debug, Display, Formatter}; use std::ops; @@ -397,6 +396,7 @@ where // Flush signals from the queue until the end of the current token is reached let cutoff = token.text_range().end(); + println!("token is: {:?}", token.text()); self.flush_matches(Some(cutoff)) } @@ -404,6 +404,7 @@ where /// signals that start after this position in the file will be skipped fn flush_matches(&mut self, cutoff: Option) -> ControlFlow { while let Some(entry) = self.signal_queue.peek() { + println!("entry_rule is: {:?}", entry.rule); let start = entry.text_range.start(); if let Some(cutoff) = cutoff { if start >= cutoff { @@ -429,6 +430,7 @@ where self.signal_queue.pop(); break; } + println!("self.line_suppression in analyzer: {:?}", self.suppressions.line_suppressions); // Search for an active line suppression comment covering the range of // this signal: first try to load the last line suppression and see @@ -444,28 +446,28 @@ where && suppression.text_range.start() <= start }); + println!("suppression in analyzer xxx: {:?}", suppression); + let suppression = match suppression { Some(suppression) => Some(suppression), None => { let index = self.suppressions .line_suppressions - .binary_search_by(|suppression| { - if suppression.text_range.end() < entry.text_range.start() { - Ordering::Less - } else if entry.text_range.end() < suppression.text_range.start() { - Ordering::Greater - } else { - Ordering::Equal - } + .partition_point(|suppression| { + suppression.text_range.end() < entry.text_range.start() }); - index - .ok() - .map(|index| &mut self.suppressions.line_suppressions[index]) + if index >= self.suppressions.line_suppressions.len() { + None + } else { + Some(&mut self.suppressions.line_suppressions[index]) + } } }; + println!("suppression in analyzer yyyyy: {:?}", suppression); + let suppression = suppression.filter(|suppression| { if suppression.suppress_all { return true; diff --git a/crates/biome_js_analyze/src/lib.rs b/crates/biome_js_analyze/src/lib.rs index fecf1d2fa9cc..b1422908482d 100644 --- a/crates/biome_js_analyze/src/lib.rs +++ b/crates/biome_js_analyze/src/lib.rs @@ -872,6 +872,50 @@ let d; ); } + #[test] + fn suppression_range_should_report_when_contains_inner_comment() { + const SOURCE: &str = " +// biome-ignore lint/complexity/useArrowFunction: single rule +const foo0 = function (bar: string) { + // biome-ignore lint/style/noParameterAssign: single rule + bar = 'baz'; +};"; + + let parsed = parse(SOURCE, JsFileSource::js_module(), JsParserOptions::default()); + + let enabled_rules = vec![ + RuleFilter::Rule("style", "noParameterAssign"), + RuleFilter::Rule("complexity", "useArrowFunction"), + ]; + + let filter = AnalysisFilter { + categories: RuleCategoriesBuilder::default().with_lint().build(), + enabled_rules: Some(enabled_rules.as_slice()), + ..AnalysisFilter::default() + }; + let options = AnalyzerOptions::default(); + analyze( + &parsed.tree(), + filter, + &options, + Vec::new(), + JsFileSource::js_module(), + None, + |signal| { + if let Some(diag) = signal.diagnostic() { + let error = diag + .with_file_path("dummyFile") + .with_file_source_code(SOURCE); + let text = print_diagnostic_to_string(&error); + eprintln!("{text}"); + panic!("Unexpected diagnostic"); + } + + ControlFlow::::Continue(()) + }, + ); + } + #[test] fn unused_range_suppression() { const SOURCE: &str = "