diff --git a/crates/oxc_linter/src/context.rs b/crates/oxc_linter/src/context.rs index 40657f50d6382..5064dcc7407fd 100644 --- a/crates/oxc_linter/src/context.rs +++ b/crates/oxc_linter/src/context.rs @@ -3,7 +3,7 @@ use std::{cell::RefCell, path::Path, rc::Rc, sync::Arc}; use oxc_cfg::ControlFlowGraph; use oxc_diagnostics::{OxcDiagnostic, Severity}; use oxc_semantic::{AstNodes, JSDocFinder, ScopeTree, Semantic, SymbolTable}; -use oxc_span::{SourceType, Span}; +use oxc_span::{GetSpan, SourceType, Span}; use oxc_syntax::module_record::ModuleRecord; use crate::{ @@ -157,7 +157,7 @@ impl<'a> LintContext<'a> { } fn add_diagnostic(&self, message: Message<'a>) { - if !self.disable_directives.contains(self.current_rule_name, message.start()) { + if !self.disable_directives.contains(self.current_rule_name, message.span()) { let mut message = message; if message.error.severity != self.severity { message.error = message.error.with_severity(self.severity); diff --git a/crates/oxc_linter/src/disable_directives.rs b/crates/oxc_linter/src/disable_directives.rs index 46d164820db80..d3ea039f813e9 100644 --- a/crates/oxc_linter/src/disable_directives.rs +++ b/crates/oxc_linter/src/disable_directives.rs @@ -27,8 +27,8 @@ pub struct DisableDirectives<'a> { } impl<'a> DisableDirectives<'a> { - pub fn contains(&self, rule_name: &'static str, start: u32) -> bool { - self.intervals.find(start, start + 1).any(|interval| { + pub fn contains(&self, rule_name: &'static str, span: Span) -> bool { + self.intervals.find(span.start, span.end).any(|interval| { interval.val == DisabledRule::All // Our rule name currently does not contain the prefix. // For example, this will match `@typescript-eslint/no-var-requires` given diff --git a/crates/oxc_linter/src/fixer.rs b/crates/oxc_linter/src/fixer.rs index 9ce5373eab0c7..40e242f004593 100644 --- a/crates/oxc_linter/src/fixer.rs +++ b/crates/oxc_linter/src/fixer.rs @@ -189,15 +189,24 @@ impl<'a> Message<'a> { Self { error, start, end, fix, fixed: false } } + #[inline] pub fn start(&self) -> u32 { self.start } + #[inline] pub fn end(&self) -> u32 { self.end } } +impl<'a> GetSpan for Message<'a> { + #[inline] + fn span(&self) -> Span { + Span::new(self.start(), self.end()) + } +} + /// The fixer of the code. /// Note that our parser has handled the BOM, so we don't need to port the BOM test cases from `ESLint`. pub struct Fixer<'a> { diff --git a/crates/oxc_linter/src/rules/unicorn/no_empty_file.rs b/crates/oxc_linter/src/rules/unicorn/no_empty_file.rs index 6cc94539c15d2..820292f54e6a5 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_empty_file.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_empty_file.rs @@ -58,7 +58,13 @@ impl Rule for NoEmptyFile { return; } - ctx.diagnostic(no_empty_file_diagnostic(Span::new(0, 0))); + let mut span = program.span; + // only show diagnostic for the first 100 characters to avoid huge diagnostic messages with + // empty programs containing a bunch of comments. + // NOTE: if the enable/disable directives come after the first 100 characters they won't be + // respected by this diagnostic. + span.end = std::cmp::min(span.end, 100); + ctx.diagnostic(no_empty_file_diagnostic(span)); } } @@ -104,6 +110,7 @@ fn test() { r"[]", r"(() => {})()", "(() => {})();", + "/* eslint-disable no-empty-file */", ]; let fail = vec![ diff --git a/crates/oxc_linter/src/snapshots/no_empty_file.snap b/crates/oxc_linter/src/snapshots/no_empty_file.snap index c27c2bf20b908..7906d01f45d71 100644 --- a/crates/oxc_linter/src/snapshots/no_empty_file.snap +++ b/crates/oxc_linter/src/snapshots/no_empty_file.snap @@ -9,141 +9,140 @@ source: crates/oxc_linter/src/tester.rs ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ - · ▲ + · ─ ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ - · ▲ + · ──── ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ - · ▲ + · ─ ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 0 │ - · ▲ + · ─ ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ - · ▲ + · ─ ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] - 1 │ - · ▲ - 2 │ - 3 │ + 1 │ ╭─▶ + 2 │ │ + 3 │ ╰─▶ ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ // comment - · ▲ + · ────────── ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ /* comment */ - · ▲ + · ───────────── ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ #!/usr/bin/env node - · ▲ + · ─────────────────── ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ 'use asm'; - · ▲ + · ────────── ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ 'use strict'; - · ▲ + · ───────────── ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ "use strict" - · ▲ + · ──────────── ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ "" - · ▲ + · ── ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ ; - · ▲ + · ─ ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ ;; - · ▲ + · ── ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ {} - · ▲ + · ── ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ {;;} - · ▲ + · ──── ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ {{}} - · ▲ + · ──── ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ ""; - · ▲ + · ─── ╰──── help: Delete this file or add some code to it. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ╭─[no_empty_file.tsx:1:1] 1 │ "use strict"; - · ▲ + · ───────────── ╰──── help: Delete this file or add some code to it.