[red-knot] Make `Diagnostic::file` optional (#15640)

This commit is contained in:
Micha Reiser 2025-01-23 10:43:14 +01:00 committed by GitHub
parent 1ecd97855e
commit 23c222368e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 36 additions and 26 deletions

View File

@ -402,8 +402,8 @@ impl Diagnostic for IOErrorDiagnostic {
self.error.to_string().into()
}
fn file(&self) -> File {
self.file
fn file(&self) -> Option<File> {
Some(self.file)
}
fn range(&self) -> Option<TextRange> {

View File

@ -5,6 +5,7 @@ use red_knot_python_semantic::{
use ruff_db::system::{System, SystemPath};
use ruff_macros::Combine;
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
use thiserror::Error;
/// The options for the project.

View File

@ -802,8 +802,8 @@ impl Diagnostic for TypeCheckDiagnostic {
TypeCheckDiagnostic::message(self).into()
}
fn file(&self) -> File {
TypeCheckDiagnostic::file(self)
fn file(&self) -> Option<File> {
Some(TypeCheckDiagnostic::file(self))
}
fn range(&self) -> Option<TextRange> {

View File

@ -75,9 +75,9 @@ fn to_lsp_diagnostic(
diagnostic: &dyn ruff_db::diagnostic::Diagnostic,
encoding: crate::PositionEncoding,
) -> Diagnostic {
let range = if let Some(range) = diagnostic.range() {
let index = line_index(db.upcast(), diagnostic.file());
let source = source_text(db.upcast(), diagnostic.file());
let range = if let (Some(file), Some(range)) = (diagnostic.file(), diagnostic.range()) {
let index = line_index(db.upcast(), file);
let source = source_text(db.upcast(), file);
range.to_range(&source, &index, encoding)
} else {

View File

@ -198,8 +198,8 @@ mod tests {
"dummy".into()
}
fn file(&self) -> File {
self.file
fn file(&self) -> Option<File> {
Some(self.file)
}
fn range(&self) -> Option<TextRange> {

View File

@ -385,8 +385,8 @@ mod tests {
self.message.into()
}
fn file(&self) -> File {
self.file
fn file(&self) -> Option<File> {
Some(self.file)
}
fn range(&self) -> Option<TextRange> {

View File

@ -152,8 +152,18 @@ pub trait Diagnostic: Send + Sync + std::fmt::Debug {
fn message(&self) -> Cow<str>;
fn file(&self) -> File;
/// The file this diagnostic is associated with.
///
/// File can be `None` for diagnostics that don't originate from a file.
/// For example:
/// * A diagnostic indicating that a directory couldn't be read.
/// * A diagnostic related to a CLI argument
fn file(&self) -> Option<File>;
/// The primary range of the diagnostic in `file`.
///
/// The range can be `None` if the diagnostic doesn't have a file
/// or it applies to the entire file (e.g. the file should be executable but isn't).
fn range(&self) -> Option<TextRange>;
fn severity(&self) -> Severity;
@ -197,16 +207,15 @@ impl std::fmt::Display for DisplayDiagnostic<'_> {
Severity::Fatal => f.write_str("fatal")?,
}
write!(
f,
"[{rule}] {path}",
rule = self.diagnostic.id(),
path = self.diagnostic.file().path(self.db)
)?;
write!(f, "[{rule}]", rule = self.diagnostic.id())?;
if let Some(range) = self.diagnostic.range() {
let index = line_index(self.db, self.diagnostic.file());
let source = source_text(self.db, self.diagnostic.file());
if let Some(file) = self.diagnostic.file() {
write!(f, " {path}", path = file.path(self.db))?;
}
if let (Some(file), Some(range)) = (self.diagnostic.file(), self.diagnostic.range()) {
let index = line_index(self.db, file);
let source = source_text(self.db, file);
let start = index.source_location(range.start(), &source);
@ -229,7 +238,7 @@ where
(**self).message()
}
fn file(&self) -> File {
fn file(&self) -> Option<File> {
(**self).file()
}
@ -254,7 +263,7 @@ where
(**self).message()
}
fn file(&self) -> File {
fn file(&self) -> Option<File> {
(**self).file()
}
@ -276,7 +285,7 @@ impl Diagnostic for Box<dyn Diagnostic> {
(**self).message()
}
fn file(&self) -> File {
fn file(&self) -> Option<File> {
(**self).file()
}
@ -310,8 +319,8 @@ impl Diagnostic for ParseDiagnostic {
self.error.error.to_string().into()
}
fn file(&self) -> File {
self.file
fn file(&self) -> Option<File> {
Some(self.file)
}
fn range(&self) -> Option<TextRange> {