Skip to content

Commit 10a1d9f

Browse files
authored
Unify OldDiagnostic and Message (#18391)
Summary -- This PR unifies the remaining differences between `OldDiagnostic` and `Message` (`OldDiagnostic` was only missing an optional `noqa_offset` field) and replaces `Message` with `OldDiagnostic`. The biggest functional difference is that the combined `OldDiagnostic` kind no longer implements `AsRule` for an infallible conversion to `Rule`. This was pretty easy to work around with `is_some_and` and `is_none_or` in the few places it was needed. In `LintContext::report_diagnostic_if_enabled` we can just use the new `Violation::rule` method, which takes care of most cases. Most of the interesting changes are in [this range](https://github.com/astral-sh/ruff/pull/18391/files/8156992540f4e81f914a9534e99241b1e14382a1) before I started renaming. Test Plan -- Existing tests Future Work -- I think it's time to start shifting some of these fields to the new `Diagnostic` kind. I believe we want `Fix` for sure, but I'm less sure about the others. We may want to keep a thin wrapper type here anyway to implement a `rule` method, so we could leave some of these fields on that too.
1 parent 4e83db4 commit 10a1d9f

File tree

96 files changed

+902
-914
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+902
-914
lines changed

crates/ruff/src/cache.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use tempfile::NamedTempFile;
1919

2020
use ruff_cache::{CacheKey, CacheKeyHasher};
2121
use ruff_diagnostics::Fix;
22-
use ruff_linter::message::Message;
22+
use ruff_linter::message::OldDiagnostic;
2323
use ruff_linter::package::PackageRoot;
2424
use ruff_linter::{VERSION, warn_user};
2525
use ruff_macros::CacheKey;
@@ -341,16 +341,16 @@ impl FileCache {
341341
/// Convert the file cache into `Diagnostics`, using `path` as file name.
342342
pub(crate) fn to_diagnostics(&self, path: &Path) -> Option<Diagnostics> {
343343
self.data.lint.as_ref().map(|lint| {
344-
let messages = if lint.messages.is_empty() {
344+
let diagnostics = if lint.messages.is_empty() {
345345
Vec::new()
346346
} else {
347347
let file = SourceFileBuilder::new(path.to_string_lossy(), &*lint.source).finish();
348348
lint.messages
349349
.iter()
350350
.map(|msg| {
351-
Message::diagnostic(
352-
msg.body.clone(),
353-
msg.suggestion.clone(),
351+
OldDiagnostic::lint(
352+
&msg.body,
353+
msg.suggestion.as_ref(),
354354
msg.range,
355355
msg.fix.clone(),
356356
msg.parent,
@@ -366,7 +366,7 @@ impl FileCache {
366366
} else {
367367
FxHashMap::default()
368368
};
369-
Diagnostics::new(messages, notebook_indexes)
369+
Diagnostics::new(diagnostics, notebook_indexes)
370370
})
371371
}
372372
}
@@ -427,27 +427,27 @@ pub(crate) struct LintCacheData {
427427
}
428428

429429
impl LintCacheData {
430-
pub(crate) fn from_messages(
431-
messages: &[Message],
430+
pub(crate) fn from_diagnostics(
431+
diagnostics: &[OldDiagnostic],
432432
notebook_index: Option<NotebookIndex>,
433433
) -> Self {
434-
let source = if let Some(msg) = messages.first() {
434+
let source = if let Some(msg) = diagnostics.first() {
435435
msg.source_file().source_text().to_owned()
436436
} else {
437437
String::new() // No messages, no need to keep the source!
438438
};
439439

440-
let messages = messages
440+
let messages = diagnostics
441441
.iter()
442442
// Parse the kebab-case rule name into a `Rule`. This will fail for syntax errors, so
443443
// this also serves to filter them out, but we shouldn't be caching files with syntax
444444
// errors anyway.
445-
.filter_map(|msg| Some((msg.name().parse().ok()?, msg)))
445+
.filter_map(|msg| Some((msg.noqa_code().and_then(|code| code.rule())?, msg)))
446446
.map(|(rule, msg)| {
447447
// Make sure that all message use the same source file.
448448
assert_eq!(
449449
msg.source_file(),
450-
messages.first().unwrap().source_file(),
450+
diagnostics.first().unwrap().source_file(),
451451
"message uses a different source file"
452452
);
453453
CacheMessage {
@@ -612,7 +612,7 @@ mod tests {
612612
use test_case::test_case;
613613

614614
use ruff_cache::CACHE_DIR_NAME;
615-
use ruff_linter::message::Message;
615+
use ruff_linter::message::OldDiagnostic;
616616
use ruff_linter::package::PackageRoot;
617617
use ruff_linter::settings::flags;
618618
use ruff_linter::settings::types::UnsafeFixes;
@@ -680,7 +680,7 @@ mod tests {
680680
UnsafeFixes::Enabled,
681681
)
682682
.unwrap();
683-
if diagnostics.messages.iter().any(Message::is_syntax_error) {
683+
if diagnostics.inner.iter().any(OldDiagnostic::is_syntax_error) {
684684
parse_errors.push(path.clone());
685685
}
686686
paths.push(path);

crates/ruff/src/commands/check.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use rustc_hash::FxHashMap;
1313

1414
use ruff_db::panic::catch_unwind;
1515
use ruff_linter::OldDiagnostic;
16-
use ruff_linter::message::Message;
1716
use ruff_linter::package::PackageRoot;
1817
use ruff_linter::registry::Rule;
1918
use ruff_linter::settings::types::UnsafeFixes;
@@ -130,9 +129,10 @@ pub(crate) fn check(
130129
SourceFileBuilder::new(path.to_string_lossy().as_ref(), "").finish();
131130

132131
Diagnostics::new(
133-
vec![Message::from_diagnostic(
134-
OldDiagnostic::new(IOError { message }, TextRange::default(), &dummy),
135-
None,
132+
vec![OldDiagnostic::new(
133+
IOError { message },
134+
TextRange::default(),
135+
&dummy,
136136
)],
137137
FxHashMap::default(),
138138
)
@@ -166,7 +166,7 @@ pub(crate) fn check(
166166
|a, b| (a.0 + b.0, a.1 + b.1),
167167
);
168168

169-
all_diagnostics.messages.sort();
169+
all_diagnostics.inner.sort();
170170

171171
// Store the caches.
172172
caches.persist()?;
@@ -283,7 +283,7 @@ mod test {
283283
.with_show_fix_status(true)
284284
.emit(
285285
&mut output,
286-
&diagnostics.messages,
286+
&diagnostics.inner,
287287
&EmitterContext::new(&FxHashMap::default()),
288288
)
289289
.unwrap();

crates/ruff/src/commands/check_stdin.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,6 @@ pub(crate) fn check_stdin(
5252
noqa,
5353
fix_mode,
5454
)?;
55-
diagnostics.messages.sort_unstable();
55+
diagnostics.inner.sort_unstable();
5656
Ok(diagnostics)
5757
}

crates/ruff/src/diagnostics.rs

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use rustc_hash::FxHashMap;
1515
use ruff_linter::OldDiagnostic;
1616
use ruff_linter::codes::Rule;
1717
use ruff_linter::linter::{FixTable, FixerResult, LinterResult, ParseSource, lint_fix, lint_only};
18-
use ruff_linter::message::Message;
1918
use ruff_linter::package::PackageRoot;
2019
use ruff_linter::pyproject_toml::lint_pyproject_toml;
2120
use ruff_linter::settings::types::UnsafeFixes;
@@ -32,18 +31,18 @@ use crate::cache::{Cache, FileCacheKey, LintCacheData};
3231

3332
#[derive(Debug, Default, PartialEq)]
3433
pub(crate) struct Diagnostics {
35-
pub(crate) messages: Vec<Message>,
34+
pub(crate) inner: Vec<OldDiagnostic>,
3635
pub(crate) fixed: FixMap,
3736
pub(crate) notebook_indexes: FxHashMap<String, NotebookIndex>,
3837
}
3938

4039
impl Diagnostics {
4140
pub(crate) fn new(
42-
messages: Vec<Message>,
41+
diagnostics: Vec<OldDiagnostic>,
4342
notebook_indexes: FxHashMap<String, NotebookIndex>,
4443
) -> Self {
4544
Self {
46-
messages,
45+
inner: diagnostics,
4746
fixed: FixMap::default(),
4847
notebook_indexes,
4948
}
@@ -63,15 +62,12 @@ impl Diagnostics {
6362
let name = path.map_or_else(|| "-".into(), Path::to_string_lossy);
6463
let source_file = SourceFileBuilder::new(name, "").finish();
6564
Self::new(
66-
vec![Message::from_diagnostic(
67-
OldDiagnostic::new(
68-
IOError {
69-
message: err.to_string(),
70-
},
71-
TextRange::default(),
72-
&source_file,
73-
),
74-
None,
65+
vec![OldDiagnostic::new(
66+
IOError {
67+
message: err.to_string(),
68+
},
69+
TextRange::default(),
70+
&source_file,
7571
)],
7672
FxHashMap::default(),
7773
)
@@ -102,7 +98,11 @@ impl Diagnostics {
10298
let name = path.map_or_else(|| "-".into(), Path::to_string_lossy);
10399
let dummy = SourceFileBuilder::new(name, "").finish();
104100
Self::new(
105-
vec![Message::syntax_error(err, TextRange::default(), dummy)],
101+
vec![OldDiagnostic::syntax_error(
102+
err,
103+
TextRange::default(),
104+
dummy,
105+
)],
106106
FxHashMap::default(),
107107
)
108108
}
@@ -121,7 +121,7 @@ impl Add for Diagnostics {
121121

122122
impl AddAssign for Diagnostics {
123123
fn add_assign(&mut self, other: Self) {
124-
self.messages.extend(other.messages);
124+
self.inner.extend(other.inner);
125125
self.fixed += other.fixed;
126126
self.notebook_indexes.extend(other.notebook_indexes);
127127
}
@@ -202,7 +202,7 @@ pub(crate) fn lint_path(
202202
if match fix_mode {
203203
flags::FixMode::Generate => true,
204204
flags::FixMode::Apply | flags::FixMode::Diff => {
205-
diagnostics.messages.is_empty() && diagnostics.fixed.is_empty()
205+
diagnostics.inner.is_empty() && diagnostics.fixed.is_empty()
206206
}
207207
} {
208208
return Ok(diagnostics);
@@ -222,7 +222,7 @@ pub(crate) fn lint_path(
222222
Some(source_type) => source_type,
223223
None => match SourceType::from(path) {
224224
SourceType::Toml(TomlSourceType::Pyproject) => {
225-
let messages = if settings
225+
let diagnostics = if settings
226226
.rules
227227
.iter_enabled()
228228
.any(|rule_code| rule_code.lint_source().is_pyproject_toml())
@@ -240,7 +240,7 @@ pub(crate) fn lint_path(
240240
vec![]
241241
};
242242
return Ok(Diagnostics {
243-
messages,
243+
inner: diagnostics,
244244
..Diagnostics::default()
245245
});
246246
}
@@ -324,7 +324,7 @@ pub(crate) fn lint_path(
324324
};
325325

326326
let has_error = result.has_syntax_errors();
327-
let messages = result.messages;
327+
let diagnostics = result.diagnostics;
328328

329329
if let Some((cache, relative_path, key)) = caching {
330330
// We don't cache parsing errors.
@@ -335,14 +335,14 @@ pub(crate) fn lint_path(
335335
if match fix_mode {
336336
flags::FixMode::Generate => true,
337337
flags::FixMode::Apply | flags::FixMode::Diff => {
338-
messages.is_empty() && fixed.is_empty()
338+
diagnostics.is_empty() && fixed.is_empty()
339339
}
340340
} {
341341
cache.update_lint(
342342
relative_path.to_owned(),
343343
&key,
344-
LintCacheData::from_messages(
345-
&messages,
344+
LintCacheData::from_diagnostics(
345+
&diagnostics,
346346
transformed.as_ipy_notebook().map(Notebook::index).cloned(),
347347
),
348348
);
@@ -357,7 +357,7 @@ pub(crate) fn lint_path(
357357
};
358358

359359
Ok(Diagnostics {
360-
messages,
360+
inner: diagnostics,
361361
fixed: FixMap::from_iter([(fs::relativize_path(path), fixed)]),
362362
notebook_indexes,
363363
})
@@ -396,7 +396,7 @@ pub(crate) fn lint_stdin(
396396
}
397397

398398
return Ok(Diagnostics {
399-
messages: lint_pyproject_toml(&source_file, &settings.linter),
399+
inner: lint_pyproject_toml(&source_file, &settings.linter),
400400
fixed: FixMap::from_iter([(fs::relativize_path(path), FixTable::default())]),
401401
notebook_indexes: FxHashMap::default(),
402402
});
@@ -417,7 +417,7 @@ pub(crate) fn lint_stdin(
417417
};
418418

419419
// Lint the inputs.
420-
let (LinterResult { messages, .. }, transformed, fixed) =
420+
let (LinterResult { diagnostics, .. }, transformed, fixed) =
421421
if matches!(fix_mode, flags::FixMode::Apply | flags::FixMode::Diff) {
422422
if let Ok(FixerResult {
423423
result,
@@ -501,7 +501,7 @@ pub(crate) fn lint_stdin(
501501
};
502502

503503
Ok(Diagnostics {
504-
messages,
504+
inner: diagnostics,
505505
fixed: FixMap::from_iter([(
506506
fs::relativize_path(path.unwrap_or_else(|| Path::new("-"))),
507507
fixed,

crates/ruff/src/lib.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ pub fn check(args: CheckCommand, global_options: GlobalConfigArgs) -> Result<Exi
363363
Printer::clear_screen()?;
364364
printer.write_to_user("Starting linter in watch mode...\n");
365365

366-
let messages = commands::check::check(
366+
let diagnostics = commands::check::check(
367367
&files,
368368
&pyproject_config,
369369
&config_arguments,
@@ -372,7 +372,7 @@ pub fn check(args: CheckCommand, global_options: GlobalConfigArgs) -> Result<Exi
372372
fix_mode,
373373
unsafe_fixes,
374374
)?;
375-
printer.write_continuously(&mut writer, &messages, preview)?;
375+
printer.write_continuously(&mut writer, &diagnostics, preview)?;
376376

377377
// In watch mode, we may need to re-resolve the configuration.
378378
// TODO(charlie): Re-compute other derivative values, like the `printer`.
@@ -392,7 +392,7 @@ pub fn check(args: CheckCommand, global_options: GlobalConfigArgs) -> Result<Exi
392392
Printer::clear_screen()?;
393393
printer.write_to_user("File change detected...\n");
394394

395-
let messages = commands::check::check(
395+
let diagnostics = commands::check::check(
396396
&files,
397397
&pyproject_config,
398398
&config_arguments,
@@ -401,7 +401,7 @@ pub fn check(args: CheckCommand, global_options: GlobalConfigArgs) -> Result<Exi
401401
fix_mode,
402402
unsafe_fixes,
403403
)?;
404-
printer.write_continuously(&mut writer, &messages, preview)?;
404+
printer.write_continuously(&mut writer, &diagnostics, preview)?;
405405
}
406406
Err(err) => return Err(err.into()),
407407
}
@@ -463,11 +463,11 @@ pub fn check(args: CheckCommand, global_options: GlobalConfigArgs) -> Result<Exi
463463
// there are any violations, unless we're explicitly asked to exit zero on
464464
// fix.
465465
if cli.exit_non_zero_on_fix {
466-
if !diagnostics.fixed.is_empty() || !diagnostics.messages.is_empty() {
466+
if !diagnostics.fixed.is_empty() || !diagnostics.inner.is_empty() {
467467
return Ok(ExitStatus::Failure);
468468
}
469469
} else {
470-
if !diagnostics.messages.is_empty() {
470+
if !diagnostics.inner.is_empty() {
471471
return Ok(ExitStatus::Failure);
472472
}
473473
}

0 commit comments

Comments
 (0)