conjure_cp_essence_parser/diagnostics/
source_map.rs1use crate::diagnostics::diagnostics_api::{Position, SymbolKind};
6use rangemap::RangeMap;
7pub type SpanId = u32;
8
9#[derive(Debug, Clone)]
10pub struct HoverInfo {
11 pub description: String, pub kind: Option<SymbolKind>, pub ty: Option<String>, pub decl_span: Option<SpanId>, }
16#[derive(Debug, Clone)]
19pub struct SourceSpan {
20 pub start_byte: usize, pub end_byte: usize,
22 pub start_point: Position,
23 pub end_point: Position,
24 pub hover_info: Option<HoverInfo>,
25}
26
27#[derive(Debug, Default, Clone)]
29pub struct SourceMap {
30 pub spans: Vec<SourceSpan>,
31 pub by_byte: RangeMap<usize, SpanId>,
32}
33
34pub fn alloc_span(
37 range: tree_sitter::Range,
38 source_map: &mut SourceMap,
39 hover_info: Option<HoverInfo>,
40) -> SpanId {
41 let span_id = source_map.spans.len() as SpanId;
42 source_map.spans.push(SourceSpan {
43 start_byte: range.start_byte,
44 end_byte: range.end_byte,
45 start_point: Position {
46 line: range.start_point.row as u32,
47 character: range.start_point.column as u32,
48 },
49 end_point: Position {
50 line: range.end_point.row as u32,
51 character: range.end_point.column as u32,
52 },
53 hover_info,
54 });
55 if range.start_byte < range.end_byte {
59 source_map
60 .by_byte
61 .insert(range.start_byte..range.end_byte, span_id);
62 }
63 span_id
64}
65
66impl SourceMap {
67 pub fn span_id_at_byte(&self, byte: usize) -> Option<SpanId> {
69 self.by_byte.get(&byte).copied()
70 }
71
72 pub fn hover_info_at_byte(&self, byte: usize) -> Option<&HoverInfo> {
74 self.span_id_at_byte(byte)
75 .and_then(|span_id| self.spans.get(span_id as usize))
76 .and_then(|span| span.hover_info.as_ref())
77 }
78}
79
80pub fn span_with_hover(
83 node: &tree_sitter::Node,
84 _source: &str,
85 map: &mut SourceMap,
86 info: HoverInfo,
87) -> SpanId {
88 alloc_span(node.range(), map, Some(info))
89}