[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
https://github.com/astral-sh/ruff/pull/16429#discussion_r1974748024.

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.
This commit is contained in:
Brent Westbrook 2025-03-19 10:08:07 -04:00 committed by GitHub
parent f2a9960fb3
commit 22de00de16
13 changed files with 280 additions and 294 deletions

View file

@ -58,8 +58,7 @@ pub struct FixerResult<'a> {
pub fixed: FixTable,
}
/// Generate `Diagnostic`s from the source code contents at the
/// given `Path`.
/// Generate [`Message`]s from the source code contents at the given `Path`.
#[allow(clippy::too_many_arguments)]
pub fn check_path(
path: &Path,
@ -74,7 +73,7 @@ pub fn check_path(
source_type: PySourceType,
parsed: &Parsed<ModModule>,
target_version: PythonVersion,
) -> Vec<Diagnostic> {
) -> Vec<Message> {
// Aggregate all diagnostics.
let mut diagnostics = vec![];
@ -322,7 +321,20 @@ pub fn check_path(
}
}
diagnostics
let syntax_errors = if settings.preview.is_enabled() {
parsed.unsupported_syntax_errors()
} else {
&[]
};
diagnostics_to_messages(
diagnostics,
parsed.errors(),
syntax_errors,
path,
locator,
directives,
)
}
const MAX_ITERATIONS: usize = 100;
@ -357,7 +369,7 @@ pub fn add_noqa_to_path(
);
// Generate diagnostics, ignoring any existing `noqa` directives.
let diagnostics = check_path(
let messages = check_path(
path,
package,
&locator,
@ -376,7 +388,7 @@ pub fn add_noqa_to_path(
// TODO(dhruvmanila): Add support for Jupyter Notebooks
add_noqa(
path,
&diagnostics,
&messages,
&locator,
indexer.comment_ranges(),
&settings.external,
@ -417,7 +429,7 @@ pub fn lint_only(
);
// Generate diagnostics.
let diagnostics = check_path(
let messages = check_path(
path,
package,
&locator,
@ -432,21 +444,8 @@ pub fn lint_only(
target_version,
);
let syntax_errors = if settings.preview.is_enabled() {
parsed.unsupported_syntax_errors()
} else {
&[]
};
LinterResult {
messages: diagnostics_to_messages(
diagnostics,
parsed.errors(),
syntax_errors,
path,
&locator,
&directives,
),
messages,
has_syntax_error: parsed.has_syntax_errors(),
}
}
@ -532,7 +531,7 @@ pub fn lint_fix<'a>(
);
// Generate diagnostics.
let diagnostics = check_path(
let messages = check_path(
path,
package,
&locator,
@ -571,7 +570,7 @@ pub fn lint_fix<'a>(
code: fixed_contents,
fixes: applied,
source_map,
}) = fix_file(&diagnostics, &locator, unsafe_fixes)
}) = fix_file(&messages, &locator, unsafe_fixes)
{
if iterations < MAX_ITERATIONS {
// Count the number of fixed errors.
@ -588,25 +587,12 @@ pub fn lint_fix<'a>(
continue;
}
report_failed_to_converge_error(path, transformed.source_code(), &diagnostics);
report_failed_to_converge_error(path, transformed.source_code(), &messages);
}
let syntax_errors = if settings.preview.is_enabled() {
parsed.unsupported_syntax_errors()
} else {
&[]
};
return Ok(FixerResult {
result: LinterResult {
messages: diagnostics_to_messages(
diagnostics,
parsed.errors(),
syntax_errors,
path,
&locator,
&directives,
),
messages,
has_syntax_error: !is_valid_syntax,
},
transformed,
@ -625,8 +611,8 @@ fn collect_rule_codes(rules: impl IntoIterator<Item = Rule>) -> String {
}
#[allow(clippy::print_stderr)]
fn report_failed_to_converge_error(path: &Path, transformed: &str, diagnostics: &[Diagnostic]) {
let codes = collect_rule_codes(diagnostics.iter().map(|diagnostic| diagnostic.kind.rule()));
fn report_failed_to_converge_error(path: &Path, transformed: &str, messages: &[Message]) {
let codes = collect_rule_codes(messages.iter().filter_map(Message::rule));
if cfg!(debug_assertions) {
eprintln!(
"{}{} Failed to converge after {} iterations in `{}` with rule codes {}:---\n{}\n---",