I'm using tower-lsp for a LanguageServer
and have setup diagnostics in my server in two ways:
Using publish_diagnostics()
async fn did_open(&self, params: DidOpenTextDocumentParams) {
// File path
let path = params.text_document.uri.to_file_path().unwrap().canonicalize().unwrap();
// Only process AS3/MXML/CSS files
if !FlexPath::new_native(&path.to_str().unwrap()).has_extensions(["as", "mxml", "css"]) {
return;
}
// Initial directory
let dir = path.parent().unwrap().to_owned();
// Compile project if needed
let result = self.compile_project(
&dir,
/* content_change_callback */
|| {
// Contribute initial content
self.opened_file_content.borrow_mut().insert(path.clone(), params.text_document.text);
},
/* no need to recompile */
false,
/* cancel compilation? */
async |_| false
).await;
if let Ok((depseq, _as3host)) = result {
let entry_package = depseq.packages.last().unwrap();
if let Some(source) = entry_package.source_by_path(&path) {
let cu = source.compilation_unit();
self.client.publish_diagnostics(Url::from_file_path(&cu.file_path().unwrap()).unwrap(), self.convert_diagnostics(&cu), None).await;
}
}
}
Using the diagnostic notification
async fn diagnostic(&self, params: DocumentDiagnosticParams) -> Result<DocumentDiagnosticReportResult> {
let path = params.text_document.uri.to_file_path().unwrap().canonicalize().unwrap();
// Only process AS3/MXML/CSS files
if !FlexPath::new_native(&path.to_str().unwrap()).has_extensions(["as", "mxml", "css"]) {
return Ok(DocumentDiagnosticReportResult::Report(DocumentDiagnosticReport::Full(RelatedFullDocumentDiagnosticReport {
related_documents: None,
full_document_diagnostic_report: FullDocumentDiagnosticReport {
result_id: None,
items: vec![],
},
})));
}
for (depseq, _) in self.compiler_results.borrow().iter() {
let entry_package = depseq.packages.last().unwrap();
if let Some(source) = entry_package.source_by_path(&path) {
let cu = source.compilation_unit();
return Ok(DocumentDiagnosticReportResult::Report(DocumentDiagnosticReport::Full(RelatedFullDocumentDiagnosticReport {
related_documents: None,
full_document_diagnostic_report: FullDocumentDiagnosticReport {
result_id: None,
items: self.convert_diagnostics(&cu),
},
})));
}
}
Ok(DocumentDiagnosticReportResult::Report(DocumentDiagnosticReport::Full(RelatedFullDocumentDiagnosticReport {
related_documents: None,
full_document_diagnostic_report: FullDocumentDiagnosticReport {
result_id: None,
items: vec![],
},
})))
}
Here's the convert_diagnostics()
function:
pub fn convert_diagnostics(&self, cu: &Rc<CompilationUnit>) -> Vec<realhydroper_lsp::lsp_types::Diagnostic> {
let flexpath = FlexPath::new_native(&cu.file_path().unwrap());
let mut items: Vec<realhydroper_lsp::lsp_types::Diagnostic> = vec![];
for orig_diag in cu.diagnostics() {
let range = as3parser_loc_to_utf16_range(&orig_diag.location());
items.push(realhydroper_lsp::lsp_types::Diagnostic {
range,
severity: Some(if orig_diag.is_error() {
DiagnosticSeverity::ERROR
} else {
DiagnosticSeverity::WARNING
}),
source: Some(if flexpath.has_extension("as") { "as3" } else if flexpath.has_extension("mxml") { "mxml" } else { "css" }.to_owned()),
message: WhackDiagnostic(&orig_diag).format_message_english(),
code: None,
code_description: None,
related_information: None,
tags: None,
data: None,
});
}
items
}
Log from my VS Code extension:
[Info - 4:34:12 PM] server initialized!
When I hover something (I did not implement it, so it's correct):
[Info - 4:34:12 PM] server initialized!
[Error - 4:34:42 PM] Request textDocument/hover failed.
Message: Method not found
Code: -32601
However, diagnostics don't show up.