@@ -26,6 +26,7 @@ use azure::AzureRenderer;
2626use pylint:: PylintRenderer ;
2727
2828mod azure;
29+ mod full;
2930#[ cfg( feature = "serde" ) ]
3031mod json;
3132#[ cfg( feature = "serde" ) ]
@@ -256,7 +257,7 @@ impl<'a> Resolved<'a> {
256257/// both.)
257258#[ derive( Debug ) ]
258259struct ResolvedDiagnostic < ' a > {
259- severity : Severity ,
260+ level : AnnotateLevel ,
260261 id : Option < String > ,
261262 message : String ,
262263 annotations : Vec < ResolvedAnnotation < ' a > > ,
@@ -281,7 +282,7 @@ impl<'a> ResolvedDiagnostic<'a> {
281282 let id = Some ( diag. inner . id . to_string ( ) ) ;
282283 let message = diag. inner . message . as_str ( ) . to_string ( ) ;
283284 ResolvedDiagnostic {
284- severity : diag. inner . severity ,
285+ level : diag. inner . severity . to_annotate ( ) ,
285286 id,
286287 message,
287288 annotations,
@@ -304,7 +305,7 @@ impl<'a> ResolvedDiagnostic<'a> {
304305 } )
305306 . collect ( ) ;
306307 ResolvedDiagnostic {
307- severity : diag. inner . severity ,
308+ level : diag. inner . severity . to_annotate ( ) ,
308309 id : None ,
309310 message : diag. inner . message . as_str ( ) . to_string ( ) ,
310311 annotations,
@@ -371,7 +372,7 @@ impl<'a> ResolvedDiagnostic<'a> {
371372 snippets_by_input
372373 . sort_by ( |snips1, snips2| snips1. has_primary . cmp ( & snips2. has_primary ) . reverse ( ) ) ;
373374 RenderableDiagnostic {
374- severity : self . severity ,
375+ level : self . level ,
375376 id : self . id . as_deref ( ) ,
376377 message : & self . message ,
377378 snippets_by_input,
@@ -459,7 +460,7 @@ struct Renderable<'r> {
459460#[ derive( Debug ) ]
460461struct RenderableDiagnostic < ' r > {
461462 /// The severity of the diagnostic.
462- severity : Severity ,
463+ level : AnnotateLevel ,
463464 /// The ID of the diagnostic. The ID can usually be used on the CLI or in a
464465 /// config file to change the severity of a lint.
465466 ///
@@ -478,15 +479,14 @@ struct RenderableDiagnostic<'r> {
478479impl RenderableDiagnostic < ' _ > {
479480 /// Convert this to an "annotate" snippet.
480481 fn to_annotate ( & self ) -> AnnotateMessage < ' _ > {
481- let level = self . severity . to_annotate ( ) ;
482482 let snippets = self . snippets_by_input . iter ( ) . flat_map ( |snippets| {
483483 let path = snippets. path ;
484484 snippets
485485 . snippets
486486 . iter ( )
487487 . map ( |snippet| snippet. to_annotate ( path) )
488488 } ) ;
489- let mut message = level. title ( self . message ) ;
489+ let mut message = self . level . title ( self . message ) ;
490490 if let Some ( id) = self . id {
491491 message = message. id ( id) ;
492492 }
@@ -864,7 +864,10 @@ mod tests {
864864
865865 use ruff_diagnostics:: { Edit , Fix } ;
866866
867- use crate :: diagnostic:: { Annotation , DiagnosticId , SecondaryCode , Severity , Span } ;
867+ use crate :: diagnostic:: {
868+ Annotation , DiagnosticId , IntoDiagnosticMessage , SecondaryCode , Severity , Span ,
869+ SubDiagnosticSeverity ,
870+ } ;
868871 use crate :: files:: system_path_to_file;
869872 use crate :: system:: { DbWithWritableSystem , SystemPath } ;
870873 use crate :: tests:: TestDb ;
@@ -1548,7 +1551,7 @@ watermelon
15481551
15491552 let mut diag = env. err ( ) . primary ( "animals" , "3" , "3" , "" ) . build ( ) ;
15501553 diag. sub (
1551- env. sub_builder ( Severity :: Info , "this is a helpful note" )
1554+ env. sub_builder ( SubDiagnosticSeverity :: Info , "this is a helpful note" )
15521555 . build ( ) ,
15531556 ) ;
15541557 insta:: assert_snapshot!(
@@ -1577,15 +1580,15 @@ watermelon
15771580
15781581 let mut diag = env. err ( ) . primary ( "animals" , "3" , "3" , "" ) . build ( ) ;
15791582 diag. sub (
1580- env. sub_builder ( Severity :: Info , "this is a helpful note" )
1583+ env. sub_builder ( SubDiagnosticSeverity :: Info , "this is a helpful note" )
15811584 . build ( ) ,
15821585 ) ;
15831586 diag. sub (
1584- env. sub_builder ( Severity :: Info , "another helpful note" )
1587+ env. sub_builder ( SubDiagnosticSeverity :: Info , "another helpful note" )
15851588 . build ( ) ,
15861589 ) ;
15871590 diag. sub (
1588- env. sub_builder ( Severity :: Info , "and another helpful note" )
1591+ env. sub_builder ( SubDiagnosticSeverity :: Info , "and another helpful note" )
15891592 . build ( ) ,
15901593 ) ;
15911594 insta:: assert_snapshot!(
@@ -2370,7 +2373,7 @@ watermelon
23702373 /// sub-diagnostic with "error" severity and canned values for
23712374 /// its identifier and message.
23722375 fn sub_warn ( & mut self ) -> SubDiagnosticBuilder < ' _ > {
2373- self . sub_builder ( Severity :: Warning , "sub-diagnostic message" )
2376+ self . sub_builder ( SubDiagnosticSeverity :: Warning , "sub-diagnostic message" )
23742377 }
23752378
23762379 /// Returns a builder for tersely constructing diagnostics.
@@ -2391,7 +2394,11 @@ watermelon
23912394 }
23922395
23932396 /// Returns a builder for tersely constructing sub-diagnostics.
2394- fn sub_builder ( & mut self , severity : Severity , message : & str ) -> SubDiagnosticBuilder < ' _ > {
2397+ fn sub_builder (
2398+ & mut self ,
2399+ severity : SubDiagnosticSeverity ,
2400+ message : & str ,
2401+ ) -> SubDiagnosticBuilder < ' _ > {
23952402 let subdiag = SubDiagnostic :: new ( severity, message) ;
23962403 SubDiagnosticBuilder { env : self , subdiag }
23972404 }
@@ -2494,6 +2501,12 @@ watermelon
24942501 self . diag . set_noqa_offset ( noqa_offset) ;
24952502 self
24962503 }
2504+
2505+ /// Adds a "help" sub-diagnostic with the given message.
2506+ fn help ( mut self , message : impl IntoDiagnosticMessage ) -> DiagnosticBuilder < ' e > {
2507+ self . diag . help ( message) ;
2508+ self
2509+ }
24972510 }
24982511
24992512 /// A helper builder for tersely populating a `SubDiagnostic`.
@@ -2600,7 +2613,8 @@ def fibonacci(n):
26002613
26012614 let diagnostics = vec ! [
26022615 env. builder( "unused-import" , Severity :: Error , "`os` imported but unused" )
2603- . primary( "fib.py" , "1:7" , "1:9" , "Remove unused import: `os`" )
2616+ . primary( "fib.py" , "1:7" , "1:9" , "" )
2617+ . help( "Remove unused import: `os`" )
26042618 . secondary_code( "F401" )
26052619 . fix( Fix :: unsafe_edit( Edit :: range_deletion( TextRange :: new(
26062620 TextSize :: from( 0 ) ,
@@ -2613,12 +2627,8 @@ def fibonacci(n):
26132627 Severity :: Error ,
26142628 "Local variable `x` is assigned to but never used" ,
26152629 )
2616- . primary(
2617- "fib.py" ,
2618- "6:4" ,
2619- "6:5" ,
2620- "Remove assignment to unused variable `x`" ,
2621- )
2630+ . primary( "fib.py" , "6:4" , "6:5" , "" )
2631+ . help( "Remove assignment to unused variable `x`" )
26222632 . secondary_code( "F841" )
26232633 . fix( Fix :: unsafe_edit( Edit :: deletion(
26242634 TextSize :: from( 94 ) ,
@@ -2720,7 +2730,8 @@ if call(foo
27202730
27212731 let diagnostics = vec ! [
27222732 env. builder( "unused-import" , Severity :: Error , "`os` imported but unused" )
2723- . primary( "notebook.ipynb" , "2:7" , "2:9" , "Remove unused import: `os`" )
2733+ . primary( "notebook.ipynb" , "2:7" , "2:9" , "" )
2734+ . help( "Remove unused import: `os`" )
27242735 . secondary_code( "F401" )
27252736 . fix( Fix :: safe_edit( Edit :: range_deletion( TextRange :: new(
27262737 TextSize :: from( 9 ) ,
@@ -2733,12 +2744,8 @@ if call(foo
27332744 Severity :: Error ,
27342745 "`math` imported but unused" ,
27352746 )
2736- . primary(
2737- "notebook.ipynb" ,
2738- "4:7" ,
2739- "4:11" ,
2740- "Remove unused import: `math`" ,
2741- )
2747+ . primary( "notebook.ipynb" , "4:7" , "4:11" , "" )
2748+ . help( "Remove unused import: `math`" )
27422749 . secondary_code( "F401" )
27432750 . fix( Fix :: safe_edit( Edit :: range_deletion( TextRange :: new(
27442751 TextSize :: from( 28 ) ,
@@ -2751,12 +2758,8 @@ if call(foo
27512758 Severity :: Error ,
27522759 "Local variable `x` is assigned to but never used" ,
27532760 )
2754- . primary(
2755- "notebook.ipynb" ,
2756- "10:4" ,
2757- "10:5" ,
2758- "Remove assignment to unused variable `x`" ,
2759- )
2761+ . primary( "notebook.ipynb" , "10:4" , "10:5" , "" )
2762+ . help( "Remove assignment to unused variable `x`" )
27602763 . secondary_code( "F841" )
27612764 . fix( Fix :: unsafe_edit( Edit :: range_deletion( TextRange :: new(
27622765 TextSize :: from( 94 ) ,
0 commit comments