use super::parsed_doc::ParsedDoc;
use crate::diagnostics::error::{Diagnostic, SemanticDiagnostic, Severity};
use crate::parse::engine::ParseError;
use crate::types::{Pos, Span};
pub use lsp_types::{Diagnostic as LspDiagnostic, DiagnosticSeverity, Position, Range};
#[must_use]
pub fn byte_offset_to_position(doc: &ParsedDoc, offset: Pos) -> Position {
let (line, character) = doc.offset_to_line_col_utf16(offset);
Position { line, character }
}
#[must_use]
pub fn span_to_range(doc: &ParsedDoc, span: Span) -> Range {
let start = byte_offset_to_position(doc, span.start);
let end = byte_offset_to_position(doc, span.end);
Range { start, end }
}
#[must_use]
pub fn position_to_byte_offset(doc: &ParsedDoc, pos: Position) -> Option<Pos> {
doc.line_index()
.line_col_utf16_to_byte(doc.source_str(), pos.line, pos.character)
}
const fn severity_to_lsp(sev: Severity) -> DiagnosticSeverity {
match sev {
Severity::Error => DiagnosticSeverity::ERROR,
Severity::Warning => DiagnosticSeverity::WARNING,
Severity::Deprecation => DiagnosticSeverity::HINT,
Severity::Note => DiagnosticSeverity::INFORMATION,
}
}
#[must_use]
pub fn parse_diagnostic_to_lsp(doc: &ParsedDoc, diag: &Diagnostic) -> LspDiagnostic {
let primary = diag.primary_span(doc.source().len());
LspDiagnostic {
range: span_to_range(doc, primary),
severity: Some(DiagnosticSeverity::ERROR),
code: None,
code_description: None,
source: Some("sipha".to_string()),
message: diag.message(None, None),
related_information: None,
tags: None,
data: None,
}
}
#[must_use]
pub fn semantic_diagnostic_to_lsp(doc: &ParsedDoc, diag: &SemanticDiagnostic) -> LspDiagnostic {
LspDiagnostic {
range: span_to_range(doc, diag.span),
severity: Some(severity_to_lsp(diag.severity)),
code: diag.code.clone().map(lsp_types::NumberOrString::String),
code_description: None,
source: Some("sipha".to_string()),
message: diag.message.clone(),
related_information: None,
tags: None,
data: None,
}
}
#[must_use]
pub fn parse_error_to_lsp(doc: &ParsedDoc, err: &ParseError) -> Option<LspDiagnostic> {
match err {
ParseError::NoMatch(d) => Some(parse_diagnostic_to_lsp(doc, d)),
ParseError::BadGraph(_) | ParseError::UnknownRuleName(_) => None,
}
}