mirror of https://github.com/astral-sh/ruff
Co-authored-by: Micha Reiser <micha@reiser.io> Co-authored-by: Andrew Gallant <andrew@astral.sh>
This commit is contained in:
parent
79f8473e51
commit
9b9d16c3ba
|
|
@ -2865,6 +2865,7 @@ dependencies = [
|
||||||
name = "ruff_db"
|
name = "ruff_db"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
"camino",
|
"camino",
|
||||||
"countme",
|
"countme",
|
||||||
"dashmap 6.1.0",
|
"dashmap 6.1.0",
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ ruff_python_trivia = { workspace = true }
|
||||||
ruff_source_file = { workspace = true }
|
ruff_source_file = { workspace = true }
|
||||||
ruff_text_size = { workspace = true }
|
ruff_text_size = { workspace = true }
|
||||||
|
|
||||||
|
anstyle = { workspace = true }
|
||||||
camino = { workspace = true }
|
camino = { workspace = true }
|
||||||
countme = { workspace = true }
|
countme = { workspace = true }
|
||||||
dashmap = { workspace = true }
|
dashmap = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ use crate::Db;
|
||||||
|
|
||||||
use self::render::FileResolver;
|
use self::render::FileResolver;
|
||||||
mod render;
|
mod render;
|
||||||
|
mod stylesheet;
|
||||||
|
|
||||||
/// A collection of information that can be rendered into a diagnostic.
|
/// A collection of information that can be rendered into a diagnostic.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ use ruff_annotate_snippets::{
|
||||||
use ruff_source_file::{LineIndex, OneIndexed, SourceCode};
|
use ruff_source_file::{LineIndex, OneIndexed, SourceCode};
|
||||||
use ruff_text_size::{TextRange, TextSize};
|
use ruff_text_size::{TextRange, TextSize};
|
||||||
|
|
||||||
|
use crate::diagnostic::stylesheet::{fmt_styled, DiagnosticStylesheet};
|
||||||
use crate::{
|
use crate::{
|
||||||
files::File,
|
files::File,
|
||||||
source::{line_index, source_text, SourceText},
|
source::{line_index, source_text, SourceText},
|
||||||
|
|
@ -48,6 +49,7 @@ impl<'a> DisplayDiagnostic<'a> {
|
||||||
} else {
|
} else {
|
||||||
AnnotateRenderer::plain()
|
AnnotateRenderer::plain()
|
||||||
};
|
};
|
||||||
|
|
||||||
DisplayDiagnostic {
|
DisplayDiagnostic {
|
||||||
config,
|
config,
|
||||||
resolver,
|
resolver,
|
||||||
|
|
@ -59,31 +61,64 @@ impl<'a> DisplayDiagnostic<'a> {
|
||||||
|
|
||||||
impl std::fmt::Display for DisplayDiagnostic<'_> {
|
impl std::fmt::Display for DisplayDiagnostic<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
if matches!(self.config.format, DiagnosticFormat::Concise) {
|
let stylesheet = if self.config.color {
|
||||||
match self.diag.severity() {
|
DiagnosticStylesheet::styled()
|
||||||
Severity::Info => f.write_str("info")?,
|
} else {
|
||||||
Severity::Warning => f.write_str("warning")?,
|
DiagnosticStylesheet::plain()
|
||||||
Severity::Error => f.write_str("error")?,
|
};
|
||||||
Severity::Fatal => f.write_str("fatal")?,
|
|
||||||
}
|
if matches!(self.config.format, DiagnosticFormat::Concise) {
|
||||||
|
let (severity, severity_style) = match self.diag.severity() {
|
||||||
|
Severity::Info => ("info", stylesheet.info),
|
||||||
|
Severity::Warning => ("warning", stylesheet.warning),
|
||||||
|
Severity::Error => ("error", stylesheet.error),
|
||||||
|
Severity::Fatal => ("fatal", stylesheet.error),
|
||||||
|
};
|
||||||
|
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"{severity}[{id}]",
|
||||||
|
severity = fmt_styled(severity, severity_style),
|
||||||
|
id = fmt_styled(self.diag.id(), stylesheet.emphasis)
|
||||||
|
)?;
|
||||||
|
|
||||||
write!(f, "[{rule}]", rule = self.diag.id())?;
|
|
||||||
if let Some(span) = self.diag.primary_span() {
|
if let Some(span) = self.diag.primary_span() {
|
||||||
write!(f, " {path}", path = self.resolver.path(span.file()))?;
|
write!(
|
||||||
|
f,
|
||||||
|
" {path}",
|
||||||
|
path = fmt_styled(self.resolver.path(span.file()), stylesheet.emphasis)
|
||||||
|
)?;
|
||||||
if let Some(range) = span.range() {
|
if let Some(range) = span.range() {
|
||||||
let input = self.resolver.input(span.file());
|
let input = self.resolver.input(span.file());
|
||||||
let start = input.as_source_code().line_column(range.start());
|
let start = input.as_source_code().line_column(range.start());
|
||||||
write!(f, ":{line}:{col}", line = start.line, col = start.column)?;
|
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
":{line}:{col}",
|
||||||
|
line = fmt_styled(start.line, stylesheet.emphasis),
|
||||||
|
col = fmt_styled(start.column, stylesheet.emphasis),
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
write!(f, ":")?;
|
write!(f, ":")?;
|
||||||
}
|
}
|
||||||
return writeln!(f, " {}", self.diag.concise_message());
|
return writeln!(f, " {message}", message = self.diag.concise_message());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut renderer = self.annotate_renderer.clone();
|
||||||
|
renderer = renderer
|
||||||
|
.error(stylesheet.error)
|
||||||
|
.warning(stylesheet.warning)
|
||||||
|
.info(stylesheet.info)
|
||||||
|
.note(stylesheet.note)
|
||||||
|
.help(stylesheet.help)
|
||||||
|
.line_no(stylesheet.line_no)
|
||||||
|
.emphasis(stylesheet.emphasis)
|
||||||
|
.none(stylesheet.none);
|
||||||
|
|
||||||
let resolved = Resolved::new(&self.resolver, self.diag);
|
let resolved = Resolved::new(&self.resolver, self.diag);
|
||||||
let renderable = resolved.to_renderable(self.config.context);
|
let renderable = resolved.to_renderable(self.config.context);
|
||||||
for diag in renderable.diagnostics.iter() {
|
for diag in renderable.diagnostics.iter() {
|
||||||
writeln!(f, "{}", self.annotate_renderer.render(diag.to_annotate()))?;
|
writeln!(f, "{}", renderer.render(diag.to_annotate()))?;
|
||||||
}
|
}
|
||||||
writeln!(f)
|
writeln!(f)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
use anstyle::{AnsiColor, Effects, Style};
|
||||||
|
use std::fmt::Formatter;
|
||||||
|
|
||||||
|
pub(super) const fn fmt_styled<'a, T>(
|
||||||
|
content: T,
|
||||||
|
style: anstyle::Style,
|
||||||
|
) -> impl std::fmt::Display + 'a
|
||||||
|
where
|
||||||
|
T: std::fmt::Display + 'a,
|
||||||
|
{
|
||||||
|
struct FmtStyled<T> {
|
||||||
|
content: T,
|
||||||
|
style: anstyle::Style,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> std::fmt::Display for FmtStyled<T>
|
||||||
|
where
|
||||||
|
T: std::fmt::Display,
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"{style_start}{content}{style_end}",
|
||||||
|
style_start = self.style.render(),
|
||||||
|
content = self.content,
|
||||||
|
style_end = self.style.render_reset()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FmtStyled { content, style }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct DiagnosticStylesheet {
|
||||||
|
pub(crate) error: Style,
|
||||||
|
pub(crate) warning: Style,
|
||||||
|
pub(crate) info: Style,
|
||||||
|
pub(crate) note: Style,
|
||||||
|
pub(crate) help: Style,
|
||||||
|
pub(crate) line_no: Style,
|
||||||
|
pub(crate) emphasis: Style,
|
||||||
|
pub(crate) none: Style,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for DiagnosticStylesheet {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::plain()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DiagnosticStylesheet {
|
||||||
|
/// Default terminal styling
|
||||||
|
pub fn styled() -> Self {
|
||||||
|
let bright_blue = AnsiColor::BrightBlue.on_default();
|
||||||
|
Self {
|
||||||
|
error: AnsiColor::BrightRed.on_default().effects(Effects::BOLD),
|
||||||
|
warning: AnsiColor::Yellow.on_default().effects(Effects::BOLD),
|
||||||
|
info: bright_blue.effects(Effects::BOLD),
|
||||||
|
note: AnsiColor::BrightGreen.on_default().effects(Effects::BOLD),
|
||||||
|
help: AnsiColor::BrightCyan.on_default().effects(Effects::BOLD),
|
||||||
|
line_no: bright_blue.effects(Effects::BOLD),
|
||||||
|
emphasis: Style::new().effects(Effects::BOLD),
|
||||||
|
none: Style::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn plain() -> Self {
|
||||||
|
Self {
|
||||||
|
error: Style::new(),
|
||||||
|
warning: Style::new(),
|
||||||
|
info: Style::new(),
|
||||||
|
note: Style::new(),
|
||||||
|
help: Style::new(),
|
||||||
|
line_no: Style::new(),
|
||||||
|
emphasis: Style::new(),
|
||||||
|
none: Style::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue