mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 13:24:57 +00:00
Unify Message
variants (#18051)
## Summary This PR unifies the ruff `Message` enum variants for syntax errors and rule violations into a single `Message` struct consisting of a shared `db::Diagnostic` and some additional, optional fields used for some rule violations. This version of `Message` is nearly a drop-in replacement for `ruff_diagnostics::Diagnostic`, which is the next step I have in mind for the refactor. I think this is also a useful checkpoint because we could possibly add some of these optional fields to the new `Diagnostic` type. I think we've previously discussed wanting support for `Fix`es, but the other fields seem less relevant, so we may just need to preserve the `Message` wrapper for a bit longer. ## Test plan Existing tests --------- Co-authored-by: Micha Reiser <micha@reiser.io>
This commit is contained in:
parent
236633cd42
commit
d6009eb942
27 changed files with 384 additions and 463 deletions
|
@ -7,6 +7,7 @@ use std::path::Path;
|
|||
#[cfg(not(fuzzing))]
|
||||
use anyhow::Result;
|
||||
use itertools::Itertools;
|
||||
use ruff_text_size::Ranged;
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use ruff_diagnostics::{Applicability, FixAvailability};
|
||||
|
@ -25,7 +26,6 @@ use crate::linter::check_path;
|
|||
use crate::message::{Emitter, EmitterContext, Message, TextEmitter};
|
||||
use crate::package::PackageRoot;
|
||||
use crate::packaging::detect_package_root;
|
||||
use crate::registry::AsRule;
|
||||
use crate::settings::types::UnsafeFixes;
|
||||
use crate::settings::{LinterSettings, flags};
|
||||
use crate::source_kind::SourceKind;
|
||||
|
@ -233,10 +233,9 @@ Source with applied fixes:
|
|||
|
||||
let messages = messages
|
||||
.into_iter()
|
||||
.filter_map(Message::into_diagnostic_message)
|
||||
.map(|mut diagnostic| {
|
||||
let rule = diagnostic.rule();
|
||||
let fixable = diagnostic.fix.as_ref().is_some_and(|fix| {
|
||||
.filter_map(|msg| Some((msg.to_rule()?, msg)))
|
||||
.map(|(rule, mut diagnostic)| {
|
||||
let fixable = diagnostic.fix().is_some_and(|fix| {
|
||||
matches!(
|
||||
fix.applicability(),
|
||||
Applicability::Safe | Applicability::Unsafe
|
||||
|
@ -269,16 +268,22 @@ Either ensure you always emit a fix or change `Violation::FIX_AVAILABILITY` to e
|
|||
}
|
||||
|
||||
assert!(
|
||||
!(fixable && diagnostic.suggestion.is_none()),
|
||||
!(fixable && diagnostic.suggestion().is_none()),
|
||||
"Diagnostic emitted by {rule:?} is fixable but \
|
||||
`Violation::fix_title` returns `None`"
|
||||
);
|
||||
|
||||
// Not strictly necessary but adds some coverage for this code path
|
||||
diagnostic.noqa_offset = directives.noqa_line_for.resolve(diagnostic.range.start());
|
||||
diagnostic.file = source_code.clone();
|
||||
// Not strictly necessary but adds some coverage for this code path by overriding the
|
||||
// noqa offset and the source file
|
||||
let range = diagnostic.range();
|
||||
diagnostic.noqa_offset = Some(directives.noqa_line_for.resolve(range.start()));
|
||||
if let Some(annotation) = diagnostic.diagnostic.primary_annotation_mut() {
|
||||
annotation.set_span(
|
||||
ruff_db::diagnostic::Span::from(source_code.clone()).with_range(range),
|
||||
);
|
||||
}
|
||||
|
||||
Message::Diagnostic(diagnostic)
|
||||
diagnostic
|
||||
})
|
||||
.chain(parsed.errors().iter().map(|parse_error| {
|
||||
Message::from_parse_error(parse_error, &locator, source_code.clone())
|
||||
|
@ -311,7 +316,7 @@ fn print_syntax_errors(
|
|||
|
||||
/// Print the [`Message::Diagnostic`]s in `messages`.
|
||||
fn print_diagnostics(mut messages: Vec<Message>, path: &Path, source: &SourceKind) -> String {
|
||||
messages.retain(Message::is_diagnostic_message);
|
||||
messages.retain(|msg| !msg.is_syntax_error());
|
||||
|
||||
if let Some(notebook) = source.as_ipy_notebook() {
|
||||
print_jupyter_messages(&messages, path, notebook)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue