1pub mod core;
2pub mod db;
3
4#[cfg(feature = "codegen")]
5pub mod codegen;
6
7use crate::core::document::Document;
8use dashmap::DashMap;
9use lsp_types_max::{
10 Diagnostic, DidChangeTextDocumentParams, DidCloseTextDocumentParams, DidOpenTextDocumentParams,
11 DocumentUri,
12};
13use parking_lot::Mutex;
14use tree_sitter::Parser;
15
16pub struct AutoLspAdapter {
23 documents: DashMap<DocumentUri, Mutex<Document>>,
25}
26
27impl Default for AutoLspAdapter {
28 fn default() -> Self {
29 Self::new_default()
30 }
31}
32
33impl AutoLspAdapter {
34 pub fn new_default() -> Self {
36 Self {
37 documents: DashMap::new(),
38 }
39 }
40
41 pub fn handle_did_open(
43 &self,
44 params: DidOpenTextDocumentParams,
45 language: tree_sitter::Language,
46 ) {
47 let uri = params.text_document.uri;
48 let text = params.text_document.text;
49
50 let mut parser = Parser::new();
51 parser
52 .set_language(&language)
53 .expect("Error loading grammar");
54
55 if let Some(tree) = parser.parse(&text, None) {
56 let doc = Document::new(text, tree, None);
57 self.documents.insert(uri, Mutex::new(doc));
58 }
59 }
60
61 pub fn handle_did_change(
63 &self,
64 params: DidChangeTextDocumentParams,
65 language: tree_sitter::Language,
66 ) {
67 let uri = params.text_document.uri;
68 if let Some(doc_ref) = self.documents.get(&uri) {
69 let mut doc = doc_ref.lock();
70 let mut parser = Parser::new();
71 parser
72 .set_language(&language)
73 .expect("Error loading grammar");
74
75 let _ = doc.update(&mut parser, ¶ms.content_changes);
76 }
77 }
78
79 pub fn handle_did_close(&self, params: DidCloseTextDocumentParams) {
81 self.documents.remove(¶ms.text_document.uri);
82 }
83
84 pub fn pull_diagnostics(&self, uri: &DocumentUri) -> Vec<Diagnostic> {
86 let mut diags = Vec::new();
87 if let Some(doc_ref) = self.documents.get(uri) {
88 let doc = doc_ref.lock();
89
90 let mut queue = vec![doc.tree.root_node()];
93 while let Some(node) = queue.pop() {
94 if node.is_error() || node.is_missing() {
95 let range = doc.denormalize_range(&node.range()).unwrap_or_default();
96 diags.push(Diagnostic {
97 range,
98 severity: Some(lsp_types_max::DiagnosticSeverity::ERROR),
99 code: Some(lsp_types_max::NumberOrString::String(
100 "AST_ERROR".to_string(),
101 )),
102 source: Some("lsp-max-ast".to_string()),
103 message: "Syntax error detected by formal parser.".to_string(),
104 ..Default::default()
105 });
106 }
107
108 for i in 0..node.child_count() as u32 {
110 if let Some(child) = node.child(i) {
111 queue.push(child);
112 }
113 }
114 }
115 }
116 diags
117 }
118
119 pub fn get_document<F, R>(&self, uri: &DocumentUri, f: F) -> Option<R>
121 where
122 F: FnOnce(&Document) -> R,
123 {
124 self.documents.get(uri).map(|doc_ref| f(&doc_ref.lock()))
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131
132 #[test]
133 fn test_adapter_initialization() {
134 let adapter = AutoLspAdapter::new_default();
135 assert!(adapter.documents.is_empty());
136 }
137}