fix(linter): find disabled directives using the message's Span. (#4010)

fixes #4005
This commit is contained in:
rzvxa 2024-07-02 10:49:05 +00:00
parent 1854a52bd7
commit 432d6d93c9
5 changed files with 43 additions and 28 deletions

View file

@ -3,7 +3,7 @@ use std::{cell::RefCell, path::Path, rc::Rc, sync::Arc};
use oxc_cfg::ControlFlowGraph; use oxc_cfg::ControlFlowGraph;
use oxc_diagnostics::{OxcDiagnostic, Severity}; use oxc_diagnostics::{OxcDiagnostic, Severity};
use oxc_semantic::{AstNodes, JSDocFinder, ScopeTree, Semantic, SymbolTable}; 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 oxc_syntax::module_record::ModuleRecord;
use crate::{ use crate::{
@ -157,7 +157,7 @@ impl<'a> LintContext<'a> {
} }
fn add_diagnostic(&self, message: Message<'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; let mut message = message;
if message.error.severity != self.severity { if message.error.severity != self.severity {
message.error = message.error.with_severity(self.severity); message.error = message.error.with_severity(self.severity);

View file

@ -27,8 +27,8 @@ pub struct DisableDirectives<'a> {
} }
impl<'a> DisableDirectives<'a> { impl<'a> DisableDirectives<'a> {
pub fn contains(&self, rule_name: &'static str, start: u32) -> bool { pub fn contains(&self, rule_name: &'static str, span: Span) -> bool {
self.intervals.find(start, start + 1).any(|interval| { self.intervals.find(span.start, span.end).any(|interval| {
interval.val == DisabledRule::All interval.val == DisabledRule::All
// Our rule name currently does not contain the prefix. // Our rule name currently does not contain the prefix.
// For example, this will match `@typescript-eslint/no-var-requires` given // For example, this will match `@typescript-eslint/no-var-requires` given

View file

@ -189,15 +189,24 @@ impl<'a> Message<'a> {
Self { error, start, end, fix, fixed: false } Self { error, start, end, fix, fixed: false }
} }
#[inline]
pub fn start(&self) -> u32 { pub fn start(&self) -> u32 {
self.start self.start
} }
#[inline]
pub fn end(&self) -> u32 { pub fn end(&self) -> u32 {
self.end self.end
} }
} }
impl<'a> GetSpan for Message<'a> {
#[inline]
fn span(&self) -> Span {
Span::new(self.start(), self.end())
}
}
/// The fixer of the code. /// 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`. /// 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> { pub struct Fixer<'a> {

View file

@ -58,7 +58,13 @@ impl Rule for NoEmptyFile {
return; 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"[]",
r"(() => {})()", r"(() => {})()",
"(() => {})();", "(() => {})();",
"/* eslint-disable no-empty-file */",
]; ];
let fail = vec![ let fail = vec![

View file

@ -9,141 +9,140 @@ source: crates/oxc_linter/src/tester.rs
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ 1 │
· ·
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ 1 │
· · ────
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ 1 │
· ·
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
0 │ 0 │
· ·
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ 1 │
· ·
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ 1 │ ╭─▶
· ▲ 2 │ │
2 │ 3 │ ╰─▶
3 │
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ // comment 1 │ // comment
· · ──────────
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ /* comment */ 1 │ /* comment */
· · ─────────────
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ #!/usr/bin/env node 1 │ #!/usr/bin/env node
· · ───────────────────
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ 'use asm'; 1 │ 'use asm';
· · ──────────
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ 'use strict'; 1 │ 'use strict';
· · ─────────────
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ "use strict" 1 │ "use strict"
· · ────────────
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ "" 1 │ ""
· · ──
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ ; 1 │ ;
· ·
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ ;; 1 │ ;;
· · ──
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ {} 1 │ {}
· · ──
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ {;;} 1 │ {;;}
· · ────
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ {{}} 1 │ {{}}
· · ────
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ ""; 1 │ "";
· · ───
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.
⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed. ⚠ eslint-plugin-unicorn(no-empty-file): Empty files are not allowed.
╭─[no_empty_file.tsx:1:1] ╭─[no_empty_file.tsx:1:1]
1 │ "use strict"; 1 │ "use strict";
· · ─────────────
╰──── ╰────
help: Delete this file or add some code to it. help: Delete this file or add some code to it.