Skip to content

Commit 22de00d

Browse files
authored
[internal] Return Messages from check_path (#16837)
Summary -- This PR updates `check_path` in the `ruff_linter` crate to return a `Vec<Message>` instead of a `Vec<Diagnostic>`. The main motivation for this is to make it easier to convert semantic syntax errors directly into `Message`s rather than `Diagnostic`s in #16106. However, this also has the benefit of keeping the preview check on unsupported syntax errors in `check_path`, as suggested in #16429 (comment). All of the interesting changes are in the first commit. The second commit just renames variables like `diagnostics` to `messages`, and the third commit is a tiny import fix. I also updated the `ExpandedMessage::location` field name, which caused a few extra commits tidying up the playground code. I thought it was nicely symmetric with `end_location`, but I'm happy to revert that too. Test Plan -- Existing tests. I also tested the playground and server manually.
1 parent f2a9960 commit 22de00d

File tree

13 files changed

+278
-292
lines changed

13 files changed

+278
-292
lines changed

crates/ruff/src/cache.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ impl FileCache {
353353
fix: msg.fix.clone(),
354354
file: file.clone(),
355355
noqa_offset: msg.noqa_offset,
356+
parent: msg.parent,
356357
})
357358
})
358359
.collect()
@@ -445,6 +446,7 @@ impl LintCacheData {
445446
CacheMessage {
446447
kind: msg.kind.clone(),
447448
range: msg.range,
449+
parent: msg.parent,
448450
fix: msg.fix.clone(),
449451
noqa_offset: msg.noqa_offset,
450452
}
@@ -465,6 +467,7 @@ pub(super) struct CacheMessage {
465467
kind: DiagnosticKind,
466468
/// Range into the message's [`FileCache::source`].
467469
range: TextRange,
470+
parent: Option<TextSize>,
468471
fix: Option<Fix>,
469472
noqa_offset: TextSize,
470473
}
@@ -702,7 +705,10 @@ mod tests {
702705
.unwrap();
703706
}
704707

705-
assert_eq!(expected_diagnostics, got_diagnostics);
708+
assert_eq!(
709+
expected_diagnostics, got_diagnostics,
710+
"left == {expected_diagnostics:#?}, right == {got_diagnostics:#?}",
711+
);
706712
}
707713

708714
#[test]

crates/ruff_linter/src/fix/edits.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,7 @@ fn all_lines_fit(
592592
#[cfg(test)]
593593
mod tests {
594594
use anyhow::{anyhow, Result};
595+
use ruff_source_file::SourceFileBuilder;
595596
use test_case::test_case;
596597

597598
use ruff_diagnostics::{Diagnostic, Edit, Fix};
@@ -604,6 +605,7 @@ mod tests {
604605
use crate::fix::edits::{
605606
add_to_dunder_all, make_redundant_alias, next_stmt_break, trailing_semicolon,
606607
};
608+
use crate::message::DiagnosticMessage;
607609
use crate::Locator;
608610

609611
/// Parse the given source using [`Mode::Module`] and return the first statement.
@@ -735,14 +737,22 @@ x = 1 \
735737
let diag = {
736738
use crate::rules::pycodestyle::rules::MissingNewlineAtEndOfFile;
737739
let mut iter = edits.into_iter();
738-
Diagnostic::new(
740+
let diag = Diagnostic::new(
739741
MissingNewlineAtEndOfFile, // The choice of rule here is arbitrary.
740742
TextRange::default(),
741743
)
742744
.with_fix(Fix::safe_edits(
743745
iter.next().ok_or(anyhow!("expected edits nonempty"))?,
744746
iter,
745-
))
747+
));
748+
DiagnosticMessage {
749+
kind: diag.kind,
750+
range: diag.range,
751+
fix: diag.fix,
752+
parent: diag.parent,
753+
file: SourceFileBuilder::new("<filename>", "<code>").finish(),
754+
noqa_offset: TextSize::default(),
755+
}
746756
};
747757
assert_eq!(apply_fixes([diag].iter(), &locator).code, expect);
748758
Ok(())

crates/ruff_linter/src/fix/mod.rs

+58-28
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ use std::collections::BTreeSet;
33
use itertools::Itertools;
44
use rustc_hash::{FxHashMap, FxHashSet};
55

6-
use ruff_diagnostics::{Diagnostic, Edit, Fix, IsolationLevel, SourceMap};
6+
use ruff_diagnostics::{Edit, Fix, IsolationLevel, SourceMap};
77
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
88

99
use crate::linter::FixTable;
10+
use crate::message::{DiagnosticMessage, Message};
1011
use crate::registry::{AsRule, Rule};
1112
use crate::settings::types::UnsafeFixes;
1213
use crate::Locator;
@@ -26,16 +27,17 @@ pub(crate) struct FixResult {
2627

2728
/// Fix errors in a file, and write the fixed source code to disk.
2829
pub(crate) fn fix_file(
29-
diagnostics: &[Diagnostic],
30+
messages: &[Message],
3031
locator: &Locator,
3132
unsafe_fixes: UnsafeFixes,
3233
) -> Option<FixResult> {
3334
let required_applicability = unsafe_fixes.required_applicability();
3435

35-
let mut with_fixes = diagnostics
36+
let mut with_fixes = messages
3637
.iter()
37-
.filter(|diagnostic| {
38-
diagnostic
38+
.filter_map(Message::as_diagnostic_message)
39+
.filter(|message| {
40+
message
3941
.fix
4042
.as_ref()
4143
.is_some_and(|fix| fix.applies(required_applicability))
@@ -51,7 +53,7 @@ pub(crate) fn fix_file(
5153

5254
/// Apply a series of fixes.
5355
fn apply_fixes<'a>(
54-
diagnostics: impl Iterator<Item = &'a Diagnostic>,
56+
diagnostics: impl Iterator<Item = &'a DiagnosticMessage>,
5557
locator: &'a Locator<'a>,
5658
) -> FixResult {
5759
let mut output = String::with_capacity(locator.len());
@@ -161,30 +163,38 @@ fn cmp_fix(rule1: Rule, rule2: Rule, fix1: &Fix, fix2: &Fix) -> std::cmp::Orderi
161163

162164
#[cfg(test)]
163165
mod tests {
164-
use ruff_diagnostics::{Diagnostic, Edit, Fix, SourceMarker};
166+
use ruff_diagnostics::{Edit, Fix, SourceMarker};
167+
use ruff_source_file::SourceFileBuilder;
165168
use ruff_text_size::{Ranged, TextSize};
166169

167170
use crate::fix::{apply_fixes, FixResult};
171+
use crate::message::DiagnosticMessage;
168172
use crate::rules::pycodestyle::rules::MissingNewlineAtEndOfFile;
169173
use crate::Locator;
170174

171175
#[allow(deprecated)]
172-
fn create_diagnostics(edit: impl IntoIterator<Item = Edit>) -> Vec<Diagnostic> {
176+
fn create_diagnostics(
177+
filename: &str,
178+
source: &str,
179+
edit: impl IntoIterator<Item = Edit>,
180+
) -> Vec<DiagnosticMessage> {
173181
edit.into_iter()
174-
.map(|edit| Diagnostic {
182+
.map(|edit| DiagnosticMessage {
175183
// The choice of rule here is arbitrary.
176184
kind: MissingNewlineAtEndOfFile.into(),
177185
range: edit.range(),
178186
fix: Some(Fix::safe_edit(edit)),
179187
parent: None,
188+
file: SourceFileBuilder::new(filename, source).finish(),
189+
noqa_offset: TextSize::default(),
180190
})
181191
.collect()
182192
}
183193

184194
#[test]
185195
fn empty_file() {
186196
let locator = Locator::new(r"");
187-
let diagnostics = create_diagnostics([]);
197+
let diagnostics = create_diagnostics("<filename>", locator.contents(), []);
188198
let FixResult {
189199
code,
190200
fixes,
@@ -205,10 +215,14 @@ print("hello world")
205215
"#
206216
.trim(),
207217
);
208-
let diagnostics = create_diagnostics([Edit::insertion(
209-
"import sys\n".to_string(),
210-
TextSize::new(10),
211-
)]);
218+
let diagnostics = create_diagnostics(
219+
"<filename>",
220+
locator.contents(),
221+
[Edit::insertion(
222+
"import sys\n".to_string(),
223+
TextSize::new(10),
224+
)],
225+
);
212226
let FixResult {
213227
code,
214228
fixes,
@@ -243,11 +257,15 @@ class A(object):
243257
"
244258
.trim(),
245259
);
246-
let diagnostics = create_diagnostics([Edit::replacement(
247-
"Bar".to_string(),
248-
TextSize::new(8),
249-
TextSize::new(14),
250-
)]);
260+
let diagnostics = create_diagnostics(
261+
"<filename>",
262+
locator.contents(),
263+
[Edit::replacement(
264+
"Bar".to_string(),
265+
TextSize::new(8),
266+
TextSize::new(14),
267+
)],
268+
);
251269
let FixResult {
252270
code,
253271
fixes,
@@ -280,7 +298,11 @@ class A(object):
280298
"
281299
.trim(),
282300
);
283-
let diagnostics = create_diagnostics([Edit::deletion(TextSize::new(7), TextSize::new(15))]);
301+
let diagnostics = create_diagnostics(
302+
"<filename>",
303+
locator.contents(),
304+
[Edit::deletion(TextSize::new(7), TextSize::new(15))],
305+
);
284306
let FixResult {
285307
code,
286308
fixes,
@@ -313,10 +335,14 @@ class A(object, object, object):
313335
"
314336
.trim(),
315337
);
316-
let diagnostics = create_diagnostics([
317-
Edit::deletion(TextSize::from(8), TextSize::from(16)),
318-
Edit::deletion(TextSize::from(22), TextSize::from(30)),
319-
]);
338+
let diagnostics = create_diagnostics(
339+
"<filename>",
340+
locator.contents(),
341+
[
342+
Edit::deletion(TextSize::from(8), TextSize::from(16)),
343+
Edit::deletion(TextSize::from(22), TextSize::from(30)),
344+
],
345+
);
320346
let FixResult {
321347
code,
322348
fixes,
@@ -352,10 +378,14 @@ class A(object):
352378
"
353379
.trim(),
354380
);
355-
let diagnostics = create_diagnostics([
356-
Edit::deletion(TextSize::from(7), TextSize::from(15)),
357-
Edit::replacement("ignored".to_string(), TextSize::from(9), TextSize::from(11)),
358-
]);
381+
let diagnostics = create_diagnostics(
382+
"<filename>",
383+
locator.contents(),
384+
[
385+
Edit::deletion(TextSize::from(7), TextSize::from(15)),
386+
Edit::replacement("ignored".to_string(), TextSize::from(9), TextSize::from(11)),
387+
],
388+
);
359389
let FixResult {
360390
code,
361391
fixes,

0 commit comments

Comments
 (0)