mirror of https://github.com/astral-sh/ruff
[ty_test] Store CheckOutput references in SortedCheckOutputs
Update SortedCheckOutputs to store references to CheckOutput instead of owned values, matching the design of the previous SortedDiagnostics implementation. This avoids unnecessary cloning and makes the API more consistent. Changes: - SortedCheckOutputs now stores Vec<&CheckOutput> - new() takes IntoIterator<Item = &CheckOutput> - LineCheckOutputs.outputs is now &[&CheckOutput] - Implement Unmatched and UnmatchedWithColumn for &CheckOutput - Update match_line to take &[&CheckOutput] 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
180d9de472
commit
41772466d5
|
|
@ -39,18 +39,21 @@ impl CheckOutput {
|
||||||
/// [`LineOutputRange`] has one entry for each contiguous slice of the outputs vector
|
/// [`LineOutputRange`] has one entry for each contiguous slice of the outputs vector
|
||||||
/// containing outputs which all start on the same line.
|
/// containing outputs which all start on the same line.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct SortedCheckOutputs {
|
pub(crate) struct SortedCheckOutputs<'a> {
|
||||||
outputs: Vec<CheckOutput>,
|
outputs: Vec<&'a CheckOutput>,
|
||||||
line_ranges: Vec<LineOutputRange>,
|
line_ranges: Vec<LineOutputRange>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SortedCheckOutputs {
|
impl<'a> SortedCheckOutputs<'a> {
|
||||||
pub(crate) fn new(outputs: &[CheckOutput], line_index: &LineIndex) -> Self {
|
pub(crate) fn new(
|
||||||
|
outputs: impl IntoIterator<Item = &'a CheckOutput>,
|
||||||
|
line_index: &LineIndex,
|
||||||
|
) -> Self {
|
||||||
let mut outputs: Vec<_> = outputs
|
let mut outputs: Vec<_> = outputs
|
||||||
.iter()
|
.into_iter()
|
||||||
.map(|output| OutputWithLine {
|
.map(|output| OutputWithLine {
|
||||||
line_number: output.line_number(line_index),
|
line_number: output.line_number(line_index),
|
||||||
output: output.clone(),
|
output,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
outputs.sort_unstable_by_key(|output_with_line| output_with_line.line_number);
|
outputs.sort_unstable_by_key(|output_with_line| output_with_line.line_number);
|
||||||
|
|
@ -104,9 +107,9 @@ impl SortedCheckOutputs {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct OutputWithLine {
|
struct OutputWithLine<'a> {
|
||||||
line_number: OneIndexed,
|
line_number: OneIndexed,
|
||||||
output: CheckOutput,
|
output: &'a CheckOutput,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Range delineating check outputs in [`SortedCheckOutputs`] that begin on a single line.
|
/// Range delineating check outputs in [`SortedCheckOutputs`] that begin on a single line.
|
||||||
|
|
@ -118,7 +121,7 @@ struct LineOutputRange {
|
||||||
|
|
||||||
/// Iterator to group sorted check outputs by line.
|
/// Iterator to group sorted check outputs by line.
|
||||||
pub(crate) struct LineCheckOutputsIterator<'a> {
|
pub(crate) struct LineCheckOutputsIterator<'a> {
|
||||||
outputs: &'a [CheckOutput],
|
outputs: &'a [&'a CheckOutput],
|
||||||
inner: std::slice::Iter<'a, LineOutputRange>,
|
inner: std::slice::Iter<'a, LineOutputRange>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,7 +149,7 @@ pub(crate) struct LineCheckOutputs<'a> {
|
||||||
pub(crate) line_number: OneIndexed,
|
pub(crate) line_number: OneIndexed,
|
||||||
|
|
||||||
/// Check outputs starting on this line.
|
/// Check outputs starting on this line.
|
||||||
pub(crate) outputs: &'a [CheckOutput],
|
pub(crate) outputs: &'a [&'a CheckOutput],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ use ruff_source_file::{LineIndex, OneIndexed};
|
||||||
|
|
||||||
use crate::assertion::{InlineFileAssertions, ParsedAssertion, UnparsedAssertion};
|
use crate::assertion::{InlineFileAssertions, ParsedAssertion, UnparsedAssertion};
|
||||||
use crate::check_output::{CheckOutput, SortedCheckOutputs};
|
use crate::check_output::{CheckOutput, SortedCheckOutputs};
|
||||||
use crate::hover::HoverOutput;
|
|
||||||
use crate::db::Db;
|
use crate::db::Db;
|
||||||
|
use crate::hover::HoverOutput;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub(super) struct FailuresByLine {
|
pub(super) struct FailuresByLine {
|
||||||
|
|
@ -171,7 +171,7 @@ fn maybe_add_undefined_reveal_clarification(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Unmatched for CheckOutput {
|
impl Unmatched for &CheckOutput {
|
||||||
fn unmatched(&self) -> String {
|
fn unmatched(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
CheckOutput::Diagnostic(diag) => diag.unmatched(),
|
CheckOutput::Diagnostic(diag) => diag.unmatched(),
|
||||||
|
|
@ -180,7 +180,7 @@ impl Unmatched for CheckOutput {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnmatchedWithColumn for CheckOutput {
|
impl UnmatchedWithColumn for &CheckOutput {
|
||||||
fn unmatched_with_column(&self, column: OneIndexed) -> String {
|
fn unmatched_with_column(&self, column: OneIndexed) -> String {
|
||||||
match self {
|
match self {
|
||||||
CheckOutput::Diagnostic(diag) => diag.unmatched_with_column(column),
|
CheckOutput::Diagnostic(diag) => diag.unmatched_with_column(column),
|
||||||
|
|
@ -191,7 +191,11 @@ impl UnmatchedWithColumn for CheckOutput {
|
||||||
|
|
||||||
impl Unmatched for &HoverOutput {
|
impl Unmatched for &HoverOutput {
|
||||||
fn unmatched(&self) -> String {
|
fn unmatched(&self) -> String {
|
||||||
format!("{} hover result: {}", "unexpected:".red(), self.inferred_type)
|
format!(
|
||||||
|
"{} hover result: {}",
|
||||||
|
"unexpected:".red(),
|
||||||
|
self.inferred_type
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -267,14 +271,14 @@ impl Matcher {
|
||||||
/// assertions.
|
/// assertions.
|
||||||
fn match_line<'a, 'b>(
|
fn match_line<'a, 'b>(
|
||||||
&self,
|
&self,
|
||||||
outputs: &'a [CheckOutput],
|
outputs: &'a [&'a CheckOutput],
|
||||||
assertions: &'a [UnparsedAssertion<'b>],
|
assertions: &'a [UnparsedAssertion<'b>],
|
||||||
) -> Result<(), Vec<String>>
|
) -> Result<(), Vec<String>>
|
||||||
where
|
where
|
||||||
'b: 'a,
|
'b: 'a,
|
||||||
{
|
{
|
||||||
let mut failures = vec![];
|
let mut failures = vec![];
|
||||||
let mut unmatched: Vec<&CheckOutput> = outputs.iter().collect();
|
let mut unmatched = outputs.to_vec();
|
||||||
for assertion in assertions {
|
for assertion in assertions {
|
||||||
match assertion.parse(&self.line_index, &self.source) {
|
match assertion.parse(&self.line_index, &self.source) {
|
||||||
Ok(assertion) => {
|
Ok(assertion) => {
|
||||||
|
|
@ -308,10 +312,11 @@ impl Matcher {
|
||||||
.column
|
.column
|
||||||
})
|
})
|
||||||
.unwrap_or(OneIndexed::from_zero_indexed(0)),
|
.unwrap_or(OneIndexed::from_zero_indexed(0)),
|
||||||
CheckOutput::Hover(hover) => self
|
CheckOutput::Hover(hover) => {
|
||||||
.line_index
|
self.line_index
|
||||||
.line_column(hover.offset, &self.source)
|
.line_column(hover.offset, &self.source)
|
||||||
.column,
|
.column
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -335,9 +340,7 @@ impl Matcher {
|
||||||
let lint_name_matches = !error.rule.is_some_and(|rule| {
|
let lint_name_matches = !error.rule.is_some_and(|rule| {
|
||||||
!(diagnostic.id().is_lint_named(rule) || diagnostic.id().as_str() == rule)
|
!(diagnostic.id().is_lint_named(rule) || diagnostic.id().as_str() == rule)
|
||||||
});
|
});
|
||||||
let column_matches = error
|
let column_matches = error.column.is_none_or(|col| col == self.column(output));
|
||||||
.column
|
|
||||||
.is_none_or(|col| col == self.column(output));
|
|
||||||
let message_matches = error.message_contains.is_none_or(|needle| {
|
let message_matches = error.message_contains.is_none_or(|needle| {
|
||||||
diagnostic.concise_message().to_string().contains(needle)
|
diagnostic.concise_message().to_string().contains(needle)
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue