mirror of
https://github.com/joshuadavidthomas/django-language-server.git
synced 2025-09-07 10:50:40 +00:00
feat: Integrate parser into diagnostics system for meaningful error reporting
This commit is contained in:
parent
9c268e80f7
commit
9b8a912d9f
1 changed files with 72 additions and 16 deletions
|
@ -1,5 +1,8 @@
|
|||
use tower_lsp::lsp_types::*;
|
||||
use crate::documents::TextDocument;
|
||||
use djls_template_ast::{Lexer, Parser};
|
||||
use djls_template_ast::ast::{Ast, Node, LineOffsets, Span};
|
||||
use djls_template_ast::tokens::TokenStream;
|
||||
|
||||
pub struct Diagnostics;
|
||||
|
||||
|
@ -7,29 +10,82 @@ impl Diagnostics {
|
|||
pub fn generate_for_document(document: &TextDocument) -> Vec<Diagnostic> {
|
||||
let mut diagnostics = Vec::new();
|
||||
|
||||
// Simple example: Check for TODO comments
|
||||
for (line_num, line) in document.get_text().lines().enumerate() {
|
||||
if let Some(col) = line.find("TODO") {
|
||||
let text = document.get_text();
|
||||
let lexer = Lexer::new(text);
|
||||
let token_stream = match lexer.tokenize() {
|
||||
Ok(tokens) => tokens,
|
||||
Err(e) => {
|
||||
diagnostics.push(Diagnostic {
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: line_num as u32,
|
||||
character: col as u32
|
||||
},
|
||||
end: Position {
|
||||
line: line_num as u32,
|
||||
character: (col + 4) as u32
|
||||
},
|
||||
},
|
||||
severity: Some(DiagnosticSeverity::INFORMATION),
|
||||
code: Some(NumberOrString::String("django.todo".to_string())),
|
||||
range: Range::new(Position::new(0, 0), Position::new(0, 0)),
|
||||
severity: Some(DiagnosticSeverity::ERROR),
|
||||
code: Some(NumberOrString::String("lexing_error".to_string())),
|
||||
source: Some("Django LSP".to_string()),
|
||||
message: "Found TODO comment".to_string(),
|
||||
message: format!("Lexing error: {}", e),
|
||||
..Default::default()
|
||||
});
|
||||
return diagnostics;
|
||||
}
|
||||
};
|
||||
|
||||
let mut parser = Parser::new(token_stream);
|
||||
let (ast, parse_errors) = match parser.parse() {
|
||||
Ok(result) => result,
|
||||
Err(e) => {
|
||||
diagnostics.push(Diagnostic {
|
||||
range: Range::new(Position::new(0, 0), Position::new(0, 0)),
|
||||
severity: Some(DiagnosticSeverity::ERROR),
|
||||
code: Some(NumberOrString::String("parsing_error".to_string())),
|
||||
source: Some("Django LSP".to_string()),
|
||||
message: format!("Parsing error: {}", e),
|
||||
..Default::default()
|
||||
});
|
||||
return diagnostics;
|
||||
}
|
||||
};
|
||||
|
||||
for error in parse_errors {
|
||||
diagnostics.push(Diagnostic {
|
||||
range: Range::new(Position::new(0, 0), Position::new(0, 0)), // Adjust range based on error
|
||||
severity: Some(DiagnosticSeverity::ERROR),
|
||||
code: Some(NumberOrString::String("parse_error".to_string())),
|
||||
source: Some("Django LSP".to_string()),
|
||||
message: format!("Parse error: {}", error),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
||||
for node in ast.nodes() {
|
||||
match node {
|
||||
Node::Block(block) => {
|
||||
if let Some(closing) = block.closing() {
|
||||
} else {
|
||||
let span = block.tag().span;
|
||||
let range = get_range_from_span(&ast.line_offsets(), &span);
|
||||
diagnostics.push(Diagnostic {
|
||||
range,
|
||||
severity: Some(DiagnosticSeverity::ERROR),
|
||||
code: Some(NumberOrString::String("unclosed_block".to_string())),
|
||||
source: Some("Django LSP".to_string()),
|
||||
message: format!("Unclosed block tag '{}'", block.tag().name),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
},
|
||||
Node::Variable { .. } => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
diagnostics
|
||||
}
|
||||
}
|
||||
|
||||
fn get_range_from_span(line_offsets: &LineOffsets, span: &Span) -> Range {
|
||||
let (start_line, start_col) = line_offsets.position_to_line_col(span.start as usize);
|
||||
let (end_line, end_col) = line_offsets.position_to_line_col((span.start + span.length) as usize);
|
||||
|
||||
Range {
|
||||
start: Position::new(start_line as u32 - 1, start_col as u32),
|
||||
end: Position::new(end_line as u32 - 1, end_col as u32),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue