refactor(linter): remove MessageRule (#25031)

This struct was introduced by Bulk-Suppressions (https://github.com/oxc-project/oxc/pull/19328).
`OxcDiagnostic` already contains `OxcCode` with the relevant information.

Downside: The `oxc_parser` diagnostics can be included now in the suppression file.
This commit is contained in:
Sysix committed 2026-07-29 10:56:30 +00:00
1 parent 1fb3d7073c
commit 31fb4c1508
6 files changed
+36 -82

No files matched your search

+2 -6
View File
@@ -1,6 +1,6 @@
#![expect(rustdoc::private_intra_doc_links)] // useful for intellisense
use std::{borrow::Cow, ffi::OsStr, ops::Deref, path::Path, rc::Rc};
use std::{ffi::OsStr, ops::Deref, path::Path, rc::Rc};
use javascript_globals::{GLOBALS, GLOBALS_BUILTIN, GLOBALS_ES2026};
@@ -17,7 +17,7 @@ use crate::{
FrameworkFlags, ModuleRecord, OxlintEnv, OxlintGlobals, OxlintSettings, WEBSITE_BASE_RULES_URL,
config::GlobalValue,
disable_directives::DisableDirectives,
fixer::{Fix, FixKind, Message, MessageRule, PossibleFixes, RuleFix, RuleFixer},
fixer::{Fix, FixKind, Message, PossibleFixes, RuleFix, RuleFixer},
frameworks::FrameworkOptions,
};
@@ -292,10 +292,6 @@ impl<'a> LintContext<'a> {
if message.error.severity != self.severity {
message.error = message.error.with_severity(self.severity);
}
message.rule = Some(MessageRule {
plugin_name: Cow::Borrowed(self.current_plugin_name),
rule_name: Cow::Borrowed(self.current_rule_name),
});
self.parent.push_diagnostic(message);
}
+2 -3
View File
@@ -1,6 +1,6 @@
use oxc_span::Span;
use crate::{Fix, FixKind, Message};
use crate::{Fix, FixKind, Message, oxc_code_short_canonical_name};
use std::borrow::Cow;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -12,7 +12,6 @@ enum DisableDirective {
impl Message {
pub(crate) fn add_ignore_fix(&mut self, section_offset: u32, section_source_text: &str) {
let Some(message_rule) = &self.rule else { return };
// If the error is exactly at the section offset and has 0 span length, it means that the file is the problem
// and attaching a ignore comment would not ignore the error.
// This is because the ignore comment would need to be placed before the error offset, which is not possible.
@@ -20,7 +19,7 @@ impl Message {
return;
}
let rule_name = message_rule.short_canonical_name();
let Some(rule_name) = oxc_code_short_canonical_name(&self.error.code) else { return };
self.fixes.extend_fix(vec![
disable_for_this_line(&rule_name, self.span.start, section_offset, section_source_text),
+18 -32
View File
@@ -1,29 +1,8 @@
use std::borrow::Cow;
use oxc_codegen::{Codegen, CodegenOptions};
use oxc_diagnostics::OxcCode;
use oxc_diagnostics::OxcDiagnostic;
use oxc_span::{GetSpan, SourceType, Span};
/// Identifies the lint rule that produced a [`Message`].
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct MessageRule {
/// Canonical plugin name, like `react`, `jsx-a11y`, `typescript`, etc.
pub plugin_name: Cow<'static, str>,
/// Canonical rule name: like `no-unused-vars` or `no-floating-promises`
pub rule_name: Cow<'static, str>,
}
impl MessageRule {
/// Returns the canonical name of the rule in the format `{plugin}/{rule}`. Omits
/// the plugin name for core rules (like `no-undef` instead of `eslint/no-undef`).
pub fn short_canonical_name(&self) -> String {
if self.plugin_name == "eslint" {
return self.rule_name.to_string();
}
format!("{}/{}", self.plugin_name, self.rule_name)
}
}
use std::borrow::Cow;
use crate::LintContext;
@@ -31,6 +10,21 @@ mod disable_fix;
mod fix;
pub use fix::{CompositeFix, Fix, FixKind, MergeFixesError, PossibleFixes, RuleFix};
pub fn oxc_code_short_canonical_name(code: &OxcCode) -> Option<String> {
let Some(scope) = &code.scope else {
return None;
};
let Some(number) = &code.number else {
return None;
};
if scope == "eslint" {
return Some(number.to_string());
}
Some(format!("{scope}/{number}"))
}
/// Produces [`RuleFix`] instances. Inspired by ESLint's [`RuleFixer`].
///
/// [`RuleFixer`]: https://github.com/eslint/eslint/blob/v9.9.1/lib/linter/rule-fixer.js
@@ -268,8 +262,6 @@ pub struct Message {
pub fixes: PossibleFixes,
pub span: Span,
fixed: bool,
/// The lint rule that produced this message, if any. Only defined for lint rule errors, and `None` otherwise.
pub rule: Option<MessageRule>,
}
impl Message {
@@ -282,13 +274,7 @@ impl Message {
.map(|span| Span::new(span.offset(), span.offset() + span.len()))
.unwrap_or_default();
Self { error, span, fixes, fixed: false, rule: None }
}
#[must_use]
pub fn with_rule(mut self, rule: MessageRule) -> Self {
self.rule = Some(rule);
self
Self { error, span, fixes, fixed: false }
}
/// move the offset of all spans to the right
+8 -23
View File
@@ -7,7 +7,6 @@
#![expect(clippy::missing_errors_doc)]
use std::{
borrow::Cow,
iter, mem,
path::Path,
ptr::{self, NonNull},
@@ -81,7 +80,7 @@ pub use crate::{
JsFix, LintFileResult, LoadPluginResult, convert_and_merge_js_fixes,
},
external_plugin_store::{ExternalOptionsId, ExternalPluginStore, ExternalRuleId},
fixer::{Fix, FixKind, Fixer, Message, MessageRule, PossibleFixes},
fixer::{Fix, FixKind, Fixer, Message, PossibleFixes, oxc_code_short_canonical_name},
frameworks::FrameworkFlags,
lint_runner::{DirectivesStore, LintRunner, LintRunnerBuilder},
loader::LINTABLE_EXTENSIONS,
@@ -145,14 +144,6 @@ fn cmp_diagnostics_for_runtime_optimization_assertion(
.then_with(|| left.error.url.cmp(&right.error.url))
.then_with(|| left.span.cmp(&right.span))
.then_with(|| left.fixes.cmp_fix_sequence(&right.fixes))
.then_with(|| {
left.rule.as_ref().map(|rule| (rule.plugin_name.as_ref(), rule.rule_name.as_ref())).cmp(
&right
.rule
.as_ref()
.map(|rule| (rule.plugin_name.as_ref(), rule.rule_name.as_ref())),
)
})
}
/// Per-thread scratch buffers for dispatching rules to AST nodes by node type.
@@ -889,19 +880,13 @@ impl Linter {
PossibleFixes::from(fix)
};
ctx_host.push_diagnostic(
Message::new(
OxcDiagnostic::error(diagnostic.message)
.with_label(span)
.with_error_code(plugin_name.to_string(), rule_name.to_string())
.with_severity(severity.into()),
possible_fixes,
)
.with_rule(MessageRule {
plugin_name: Cow::Owned(plugin_name.to_string()),
rule_name: Cow::Owned(rule_name.to_string()),
}),
);
ctx_host.push_diagnostic(Message::new(
OxcDiagnostic::error(diagnostic.message)
.with_label(span)
.with_error_code(plugin_name.to_string(), rule_name.to_string())
.with_severity(severity.into()),
possible_fixes,
));
}
}
Err(err) => {
+3 -11
View File
@@ -4,7 +4,7 @@ use oxc_diagnostics::Severity;
use rustc_hash::FxHashMap;
use crate::{
Message,
Message, oxc_code_short_canonical_name,
suppression::{
DiagnosticCounts, Filename, RuntimeSuppressionMap, StaticSuppressionMap, SuppressionFile,
SuppressionFileState,
@@ -103,11 +103,7 @@ impl DiffManager {
continue;
}
let Some(key) = message
.rule
.as_ref()
.map(super::super::fixer::MessageRule::short_canonical_name)
else {
let Some(key) = oxc_code_short_canonical_name(&message.error.code) else {
continue;
};
@@ -146,11 +142,7 @@ impl DiffManager {
return true;
}
let Some(key) = message
.rule
.as_ref()
.map(super::super::fixer::MessageRule::short_canonical_name)
else {
let Some(key) = oxc_code_short_canonical_name(&message.error.code) else {
return true;
};
+3 -7
View File
@@ -19,8 +19,8 @@ use oxc_span::{SourceType, Span};
use super::{AllowWarnDeny, ConfigStore, DisableDirectives, ResolvedLinterState, read_to_string};
use crate::{
CompositeFix, FixKind, Fixer, Message, MessageRule, PossibleFixes, RuleTimingRecord,
RuleTimingSource, RuleTimingStore, WEBSITE_BASE_RULES_URL, suppression::DiffManager,
CompositeFix, FixKind, Fixer, Message, PossibleFixes, RuleTimingRecord, RuleTimingSource,
RuleTimingStore, WEBSITE_BASE_RULES_URL, suppression::DiffManager,
};
/// State required to initialize the `tsgolint` linter.
@@ -823,7 +823,6 @@ impl From<TsGoLintInternalDiagnostic> for OxcDiagnostic {
impl Message {
/// Converts a `TsGoLintDiagnostic` into a `Message` with possible fixes.
fn from_tsgo_lint_diagnostic(mut val: TsGoLintRuleDiagnostic, source_text: &str) -> Self {
let rule_name = val.rule.clone();
let fix = if val.fixes.is_empty() {
None
} else {
@@ -859,10 +858,7 @@ impl Message {
#[expect(clippy::from_iter_instead_of_collect)]
let possible_fixes = PossibleFixes::from_iter(iter::chain(fix, suggestions));
Self::new(val.into(), possible_fixes).with_rule(MessageRule {
plugin_name: Cow::Borrowed("typescript"),
rule_name: Cow::Owned(rule_name),
})
Self::new(val.into(), possible_fixes)
}
}