@@ -6,6 +6,55 @@ use djls_templates::TemplateErrorAccumulator;
66use djls_workspace:: SourceFile ;
77use tower_lsp_server:: lsp_types;
88
9+ trait DiagnosticError : std:: fmt:: Display {
10+ fn span ( & self ) -> Option < ( u32 , u32 ) > ;
11+ fn diagnostic_code ( & self ) -> & ' static str ;
12+
13+ fn message ( & self ) -> String {
14+ self . to_string ( )
15+ }
16+ }
17+
18+ impl DiagnosticError for TemplateError {
19+ fn span ( & self ) -> Option < ( u32 , u32 ) > {
20+ None
21+ }
22+
23+ fn diagnostic_code ( & self ) -> & ' static str {
24+ match self {
25+ TemplateError :: Parser ( _) => "T100" ,
26+ TemplateError :: Io ( _) => "T900" ,
27+ TemplateError :: Config ( _) => "T901" ,
28+ }
29+ }
30+ }
31+
32+ impl DiagnosticError for ValidationError {
33+ fn span ( & self ) -> Option < ( u32 , u32 ) > {
34+ match self {
35+ ValidationError :: UnbalancedStructure { opening_span, .. } => {
36+ Some ( ( opening_span. start , opening_span. length ) )
37+ }
38+ ValidationError :: UnclosedTag { span, .. }
39+ | ValidationError :: OrphanedTag { span, .. }
40+ | ValidationError :: UnmatchedBlockName { span, .. }
41+ | ValidationError :: MissingRequiredArguments { span, .. }
42+ | ValidationError :: TooManyArguments { span, .. } => Some ( ( span. start , span. length ) ) ,
43+ }
44+ }
45+
46+ fn diagnostic_code ( & self ) -> & ' static str {
47+ match self {
48+ ValidationError :: UnclosedTag { .. } => "S100" ,
49+ ValidationError :: UnbalancedStructure { .. } => "S101" ,
50+ ValidationError :: OrphanedTag { .. } => "S102" ,
51+ ValidationError :: UnmatchedBlockName { .. } => "S103" ,
52+ ValidationError :: MissingRequiredArguments { .. } => "S104" ,
53+ ValidationError :: TooManyArguments { .. } => "S105" ,
54+ }
55+ }
56+ }
57+
958/// Convert a Span to an LSP Range using line offsets.
1059fn span_to_lsp_range ( span : Span , line_offsets : & LineOffsets ) -> lsp_types:: Range {
1160 let start_pos = span. start as usize ;
@@ -26,37 +75,9 @@ fn span_to_lsp_range(span: Span, line_offsets: &LineOffsets) -> lsp_types::Range
2675 }
2776}
2877
29- /// Convert a template error to an LSP diagnostic.
30- fn template_error_to_diagnostic (
31- error : & TemplateError ,
32- line_offsets : & LineOffsets ,
33- ) -> lsp_types:: Diagnostic {
34- let range = error
35- . span ( )
36- . map ( |( start, length) | {
37- let span = Span :: new ( start, length) ;
38- span_to_lsp_range ( span, line_offsets)
39- } )
40- . unwrap_or_default ( ) ;
41-
42- lsp_types:: Diagnostic {
43- range,
44- severity : Some ( lsp_types:: DiagnosticSeverity :: ERROR ) ,
45- code : Some ( lsp_types:: NumberOrString :: String (
46- error. diagnostic_code ( ) . to_string ( ) ,
47- ) ) ,
48- code_description : None ,
49- source : Some ( "Django Language Server" . to_string ( ) ) ,
50- message : error. to_string ( ) ,
51- related_information : None ,
52- tags : None ,
53- data : None ,
54- }
55- }
56-
57- /// Convert a validation error (`ValidationError`) to an LSP diagnostic.
58- fn validation_error_to_diagnostic (
59- error : & ValidationError ,
78+ /// Convert any error implementing `DiagnosticError` to an LSP diagnostic.
79+ fn error_to_diagnostic (
80+ error : & impl DiagnosticError ,
6081 line_offsets : & LineOffsets ,
6182) -> lsp_types:: Diagnostic {
6283 let range = error
@@ -75,7 +96,7 @@ fn validation_error_to_diagnostic(
7596 ) ) ,
7697 code_description : None ,
7798 source : Some ( "Django Language Server" . to_string ( ) ) ,
78- message : error. to_string ( ) ,
99+ message : error. message ( ) ,
79100 related_information : None ,
80101 tags : None ,
81102 data : None ,
@@ -111,7 +132,7 @@ pub fn collect_diagnostics(
111132
112133 // Convert template errors to diagnostics
113134 for error_acc in template_errors {
114- diagnostics. push ( template_error_to_diagnostic ( & error_acc. 0 , & line_offsets) ) ;
135+ diagnostics. push ( error_to_diagnostic ( & error_acc. 0 , & line_offsets) ) ;
115136 }
116137
117138 // If parsing succeeded, run validation
@@ -123,7 +144,7 @@ pub fn collect_diagnostics(
123144
124145 // Convert validation errors to diagnostics
125146 for error_acc in validation_errors {
126- diagnostics. push ( validation_error_to_diagnostic ( & error_acc. 0 , & line_offsets) ) ;
147+ diagnostics. push ( error_to_diagnostic ( & error_acc. 0 , & line_offsets) ) ;
127148 }
128149 }
129150
0 commit comments