1#![allow(missing_docs)]
10
11use std::collections::BTreeMap;
12use std::rc::Rc;
13
14use harn_vm::VmValue;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19pub enum SymbolKind {
20 Function,
21 Method,
22 Class,
23 Struct,
24 Enum,
25 Interface,
26 Protocol,
27 Type,
28 Variable,
29 Module,
30 Other,
31}
32
33impl SymbolKind {
34 pub fn as_str(self) -> &'static str {
36 match self {
37 SymbolKind::Function => "function",
38 SymbolKind::Method => "method",
39 SymbolKind::Class => "class",
40 SymbolKind::Struct => "struct",
41 SymbolKind::Enum => "enum",
42 SymbolKind::Interface => "interface",
43 SymbolKind::Protocol => "protocol",
44 SymbolKind::Type => "type",
45 SymbolKind::Variable => "variable",
46 SymbolKind::Module => "module",
47 SymbolKind::Other => "other",
48 }
49 }
50
51 pub fn is_container(self) -> bool {
55 matches!(
56 self,
57 SymbolKind::Class
58 | SymbolKind::Struct
59 | SymbolKind::Enum
60 | SymbolKind::Interface
61 | SymbolKind::Protocol
62 | SymbolKind::Module
63 )
64 }
65}
66
67#[derive(Debug, Clone)]
70pub struct Symbol {
71 pub name: String,
72 pub kind: SymbolKind,
73 pub container: Option<String>,
74 pub signature: String,
75 pub start_row: u32,
76 pub start_col: u32,
77 pub end_row: u32,
78 pub end_col: u32,
79}
80
81impl Symbol {
82 pub fn to_vm_value(&self) -> VmValue {
84 let mut dict: BTreeMap<String, VmValue> = BTreeMap::new();
85 dict.insert("name".into(), VmValue::String(Rc::from(self.name.as_str())));
86 dict.insert("kind".into(), VmValue::String(Rc::from(self.kind.as_str())));
87 dict.insert(
88 "container".into(),
89 match &self.container {
90 Some(s) => VmValue::String(Rc::from(s.as_str())),
91 None => VmValue::Nil,
92 },
93 );
94 dict.insert(
95 "signature".into(),
96 VmValue::String(Rc::from(self.signature.as_str())),
97 );
98 dict.insert("start_row".into(), VmValue::Int(self.start_row as i64));
99 dict.insert("start_col".into(), VmValue::Int(self.start_col as i64));
100 dict.insert("end_row".into(), VmValue::Int(self.end_row as i64));
101 dict.insert("end_col".into(), VmValue::Int(self.end_col as i64));
102 VmValue::Dict(Rc::new(dict))
103 }
104}
105
106#[derive(Debug, Clone)]
109pub struct OutlineItem {
110 pub name: String,
111 pub kind: SymbolKind,
112 pub signature: String,
113 pub start_row: u32,
114 pub end_row: u32,
115 pub children: Vec<OutlineItem>,
116}
117
118impl OutlineItem {
119 pub fn to_vm_value(&self) -> VmValue {
120 let mut dict: BTreeMap<String, VmValue> = BTreeMap::new();
121 dict.insert("name".into(), VmValue::String(Rc::from(self.name.as_str())));
122 dict.insert("kind".into(), VmValue::String(Rc::from(self.kind.as_str())));
123 dict.insert(
124 "signature".into(),
125 VmValue::String(Rc::from(self.signature.as_str())),
126 );
127 dict.insert("start_row".into(), VmValue::Int(self.start_row as i64));
128 dict.insert("end_row".into(), VmValue::Int(self.end_row as i64));
129 let kids: Vec<VmValue> = self.children.iter().map(OutlineItem::to_vm_value).collect();
130 dict.insert("children".into(), VmValue::List(Rc::new(kids)));
131 VmValue::Dict(Rc::new(dict))
132 }
133}
134
135#[derive(Debug, Clone)]
138pub struct ParsedNode {
139 pub id: u32,
140 pub parent_id: Option<u32>,
141 pub kind: String,
142 pub is_named: bool,
143 pub start_byte: u32,
144 pub end_byte: u32,
145 pub start_row: u32,
146 pub start_col: u32,
147 pub end_row: u32,
148 pub end_col: u32,
149}
150
151impl ParsedNode {
152 pub fn to_vm_value(&self) -> VmValue {
153 let mut dict: BTreeMap<String, VmValue> = BTreeMap::new();
154 dict.insert("id".into(), VmValue::Int(self.id as i64));
155 dict.insert(
156 "parent_id".into(),
157 self.parent_id
158 .map_or(VmValue::Nil, |id| VmValue::Int(id as i64)),
159 );
160 dict.insert("kind".into(), VmValue::String(Rc::from(self.kind.as_str())));
161 dict.insert("is_named".into(), VmValue::Bool(self.is_named));
162 dict.insert("start_byte".into(), VmValue::Int(self.start_byte as i64));
163 dict.insert("end_byte".into(), VmValue::Int(self.end_byte as i64));
164 dict.insert("start_row".into(), VmValue::Int(self.start_row as i64));
165 dict.insert("start_col".into(), VmValue::Int(self.start_col as i64));
166 dict.insert("end_row".into(), VmValue::Int(self.end_row as i64));
167 dict.insert("end_col".into(), VmValue::Int(self.end_col as i64));
168 VmValue::Dict(Rc::new(dict))
169 }
170}
171
172#[derive(Debug, Clone)]
180pub struct ParseError {
181 pub start_row: u32,
182 pub start_col: u32,
183 pub end_row: u32,
184 pub end_col: u32,
185 pub start_byte: u32,
186 pub end_byte: u32,
187 pub message: String,
188 pub snippet: String,
189 pub missing: bool,
190}
191
192impl ParseError {
193 pub fn to_vm_value(&self) -> VmValue {
194 let mut dict: BTreeMap<String, VmValue> = BTreeMap::new();
195 dict.insert("start_row".into(), VmValue::Int(self.start_row as i64));
196 dict.insert("start_col".into(), VmValue::Int(self.start_col as i64));
197 dict.insert("end_row".into(), VmValue::Int(self.end_row as i64));
198 dict.insert("end_col".into(), VmValue::Int(self.end_col as i64));
199 dict.insert("start_byte".into(), VmValue::Int(self.start_byte as i64));
200 dict.insert("end_byte".into(), VmValue::Int(self.end_byte as i64));
201 dict.insert(
202 "message".into(),
203 VmValue::String(Rc::from(self.message.as_str())),
204 );
205 dict.insert(
206 "snippet".into(),
207 VmValue::String(Rc::from(self.snippet.as_str())),
208 );
209 dict.insert("missing".into(), VmValue::Bool(self.missing));
210 VmValue::Dict(Rc::new(dict))
211 }
212}
213
214#[derive(Debug, Clone)]
218pub struct UndefinedName {
219 pub name: String,
220 pub kind: &'static str,
221 pub row: u32,
222 pub column: u32,
223}
224
225impl UndefinedName {
226 pub fn to_vm_value(&self) -> VmValue {
227 let mut dict: BTreeMap<String, VmValue> = BTreeMap::new();
228 dict.insert("name".into(), VmValue::String(Rc::from(self.name.as_str())));
229 dict.insert("kind".into(), VmValue::String(Rc::from(self.kind)));
230 dict.insert("row".into(), VmValue::Int(self.row as i64));
231 dict.insert("column".into(), VmValue::Int(self.column as i64));
232 let message = format!("undefined name '{}'", self.name);
233 dict.insert(
234 "message".into(),
235 VmValue::String(Rc::from(message.as_str())),
236 );
237 VmValue::Dict(Rc::new(dict))
238 }
239}