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 doc_key: Option<String>, pub kind: Option<SymbolKind>, pub ty: Option<String>, pub decl_span: Option<SpanId>, }
17#[derive(Debug, Clone)]
20pub struct SourceSpan {
21 pub start_byte: usize, pub end_byte: usize,
23 pub start_point: Position,
24 pub end_point: Position,
25 pub hover_info: Option<HoverInfo>,
26}
27
28#[derive(Debug, Default, Clone)]
30pub struct SourceMap {
31 pub spans: Vec<SourceSpan>,
32 pub by_byte: RangeMap<usize, SpanId>,
33}
34
35pub fn alloc_span(
38 range: tree_sitter::Range,
39 source_map: &mut SourceMap,
40 hover_info: Option<HoverInfo>,
41) -> SpanId {
42 let span_id = source_map.spans.len() as SpanId;
43 source_map.spans.push(SourceSpan {
44 start_byte: range.start_byte,
45 end_byte: range.end_byte,
46 start_point: Position {
47 line: range.start_point.row as u32,
48 character: range.start_point.column as u32,
49 },
50 end_point: Position {
51 line: range.end_point.row as u32,
52 character: range.end_point.column as u32,
53 },
54 hover_info,
55 });
56 if range.start_byte < range.end_byte {
60 source_map
61 .by_byte
62 .insert(range.start_byte..range.end_byte, span_id);
63 }
64 span_id
65}
66
67impl SourceMap {
68 pub fn span_id_at_byte(&self, byte: usize) -> Option<SpanId> {
70 self.by_byte.get(&byte).copied()
71 }
72
73 pub fn hover_info_at_byte(&self, byte: usize) -> Option<&HoverInfo> {
75 self.span_id_at_byte(byte)
76 .and_then(|span_id| self.spans.get(span_id as usize))
77 .and_then(|span| span.hover_info.as_ref())
78 }
79}
80
81pub fn span_with_hover(
84 node: &tree_sitter::Node,
85 _source: &str,
86 map: &mut SourceMap,
87 info: HoverInfo,
88) -> SpanId {
89 alloc_span(node.range(), map, Some(info))
90}