Skip to content

Commit 8535af8

Browse files
ercbotMichaReiser
andauthored
[red-knot] Add support for the LSP diagnostic tag (astral-sh#17657)
Co-authored-by: Micha Reiser <[email protected]>
1 parent b51c4f8 commit 8535af8

File tree

3 files changed

+71
-4
lines changed

3 files changed

+71
-4
lines changed

crates/ruff_db/src/diagnostic/mod.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,11 @@ impl Diagnostic {
227227
pub fn primary_span(&self) -> Option<Span> {
228228
self.primary_annotation().map(|ann| ann.span.clone())
229229
}
230+
231+
/// Returns the tags from the primary annotation of this diagnostic if it exists.
232+
pub fn primary_tags(&self) -> Option<&[DiagnosticTag]> {
233+
self.primary_annotation().map(|ann| ann.tags.as_slice())
234+
}
230235
}
231236

232237
#[derive(Debug, Clone, Eq, PartialEq)]
@@ -338,6 +343,8 @@ pub struct Annotation {
338343
/// Whether this annotation is "primary" or not. When it isn't primary, an
339344
/// annotation is said to be "secondary."
340345
is_primary: bool,
346+
/// The diagnostic tags associated with this annotation.
347+
tags: Vec<DiagnosticTag>,
341348
}
342349

343350
impl Annotation {
@@ -355,6 +362,7 @@ impl Annotation {
355362
span,
356363
message: None,
357364
is_primary: true,
365+
tags: Vec::new(),
358366
}
359367
}
360368

@@ -370,6 +378,7 @@ impl Annotation {
370378
span,
371379
message: None,
372380
is_primary: false,
381+
tags: Vec::new(),
373382
}
374383
}
375384

@@ -412,6 +421,36 @@ impl Annotation {
412421
pub fn get_span(&self) -> &Span {
413422
&self.span
414423
}
424+
425+
/// Returns the tags associated with this annotation.
426+
pub fn get_tags(&self) -> &[DiagnosticTag] {
427+
&self.tags
428+
}
429+
430+
/// Attaches this tag to this annotation.
431+
///
432+
/// It will not replace any existing tags.
433+
pub fn tag(mut self, tag: DiagnosticTag) -> Annotation {
434+
self.tags.push(tag);
435+
self
436+
}
437+
438+
/// Attaches an additional tag to this annotation.
439+
pub fn push_tag(&mut self, tag: DiagnosticTag) {
440+
self.tags.push(tag);
441+
}
442+
}
443+
444+
/// Tags that can be associated with an annotation.
445+
///
446+
/// These tags are used to provide additional information about the annotation.
447+
/// and are passed through to the language server protocol.
448+
#[derive(Debug, Clone, Eq, PartialEq)]
449+
pub enum DiagnosticTag {
450+
/// Unused or unnecessary code. Used for unused parameters, unreachable code, etc.
451+
Unnecessary,
452+
/// Deprecated or obsolete code.
453+
Deprecated,
415454
}
416455

417456
/// A string identifier for a lint rule.

crates/ty_python_semantic/src/types/context.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::fmt;
22

33
use drop_bomb::DebugDropBomb;
4+
use ruff_db::diagnostic::DiagnosticTag;
45
use ruff_db::{
56
diagnostic::{Annotation, Diagnostic, DiagnosticId, IntoDiagnosticMessage, Severity, Span},
67
files::File,
@@ -259,6 +260,21 @@ impl LintDiagnosticGuard<'_, '_> {
259260
let ann = self.primary_annotation_mut().unwrap();
260261
ann.set_message(message);
261262
}
263+
264+
/// Adds a tag on the primary annotation for this diagnostic.
265+
///
266+
/// This tag is associated with the primary annotation created
267+
/// for every `Diagnostic` that uses the `LintDiagnosticGuard` API.
268+
/// Specifically, the annotation is derived from the `TextRange` given to
269+
/// the `InferContext::report_lint` API.
270+
///
271+
/// Callers can add additional primary or secondary annotations via the
272+
/// `DerefMut` trait implementation to a `Diagnostic`.
273+
#[expect(dead_code)]
274+
pub(super) fn add_primary_tag(&mut self, tag: DiagnosticTag) {
275+
let ann = self.primary_annotation_mut().unwrap();
276+
ann.push_tag(tag);
277+
}
262278
}
263279

264280
impl std::ops::Deref for LintDiagnosticGuard<'_, '_> {

crates/ty_server/src/server/api/requests/diagnostic.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ use std::borrow::Cow;
22

33
use lsp_types::request::DocumentDiagnosticRequest;
44
use lsp_types::{
5-
Diagnostic, DiagnosticSeverity, DocumentDiagnosticParams, DocumentDiagnosticReport,
6-
DocumentDiagnosticReportResult, FullDocumentDiagnosticReport, NumberOrString, Range,
7-
RelatedFullDocumentDiagnosticReport, Url,
5+
Diagnostic, DiagnosticSeverity, DiagnosticTag, DocumentDiagnosticParams,
6+
DocumentDiagnosticReport, DocumentDiagnosticReportResult, FullDocumentDiagnosticReport,
7+
NumberOrString, Range, RelatedFullDocumentDiagnosticReport, Url,
88
};
99

1010
use crate::document::ToRangeExt;
@@ -92,10 +92,22 @@ fn to_lsp_diagnostic(
9292
Severity::Error | Severity::Fatal => DiagnosticSeverity::ERROR,
9393
};
9494

95+
let tags = diagnostic
96+
.primary_tags()
97+
.map(|tags| {
98+
tags.iter()
99+
.map(|tag| match tag {
100+
ruff_db::diagnostic::DiagnosticTag::Unnecessary => DiagnosticTag::UNNECESSARY,
101+
ruff_db::diagnostic::DiagnosticTag::Deprecated => DiagnosticTag::DEPRECATED,
102+
})
103+
.collect::<Vec<DiagnosticTag>>()
104+
})
105+
.filter(|mapped_tags| !mapped_tags.is_empty());
106+
95107
Diagnostic {
96108
range,
97109
severity: Some(severity),
98-
tags: None,
110+
tags,
99111
code: Some(NumberOrString::String(diagnostic.id().to_string())),
100112
code_description: None,
101113
source: Some("ty".into()),

0 commit comments

Comments
 (0)