1#![allow(missing_docs)]
10
11use std::collections::BTreeMap;
12use std::sync::Arc;
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(
86 "name".into(),
87 VmValue::String(Arc::from(self.name.as_str())),
88 );
89 dict.insert(
90 "kind".into(),
91 VmValue::String(Arc::from(self.kind.as_str())),
92 );
93 dict.insert(
94 "container".into(),
95 match &self.container {
96 Some(s) => VmValue::String(Arc::from(s.as_str())),
97 None => VmValue::Nil,
98 },
99 );
100 dict.insert(
101 "signature".into(),
102 VmValue::String(Arc::from(self.signature.as_str())),
103 );
104 dict.insert("start_row".into(), VmValue::Int(self.start_row as i64));
105 dict.insert("start_col".into(), VmValue::Int(self.start_col as i64));
106 dict.insert("end_row".into(), VmValue::Int(self.end_row as i64));
107 dict.insert("end_col".into(), VmValue::Int(self.end_col as i64));
108 VmValue::Dict(Arc::new(dict))
109 }
110}
111
112#[derive(Debug, Clone)]
115pub struct OutlineItem {
116 pub name: String,
117 pub kind: SymbolKind,
118 pub signature: String,
119 pub start_row: u32,
120 pub end_row: u32,
121 pub children: Vec<OutlineItem>,
122}
123
124impl OutlineItem {
125 pub fn to_vm_value(&self) -> VmValue {
126 let mut dict: BTreeMap<String, VmValue> = BTreeMap::new();
127 dict.insert(
128 "name".into(),
129 VmValue::String(Arc::from(self.name.as_str())),
130 );
131 dict.insert(
132 "kind".into(),
133 VmValue::String(Arc::from(self.kind.as_str())),
134 );
135 dict.insert(
136 "signature".into(),
137 VmValue::String(Arc::from(self.signature.as_str())),
138 );
139 dict.insert("start_row".into(), VmValue::Int(self.start_row as i64));
140 dict.insert("end_row".into(), VmValue::Int(self.end_row as i64));
141 let kids: Vec<VmValue> = self.children.iter().map(OutlineItem::to_vm_value).collect();
142 dict.insert("children".into(), VmValue::List(Arc::new(kids)));
143 VmValue::Dict(Arc::new(dict))
144 }
145}
146
147#[derive(Debug, Clone)]
150pub struct ParsedNode {
151 pub id: u32,
152 pub parent_id: Option<u32>,
153 pub kind: String,
154 pub is_named: bool,
155 pub start_byte: u32,
156 pub end_byte: u32,
157 pub start_row: u32,
158 pub start_col: u32,
159 pub end_row: u32,
160 pub end_col: u32,
161}
162
163impl ParsedNode {
164 pub fn to_vm_value(&self) -> VmValue {
165 let mut dict: BTreeMap<String, VmValue> = BTreeMap::new();
166 dict.insert("id".into(), VmValue::Int(self.id as i64));
167 dict.insert(
168 "parent_id".into(),
169 self.parent_id
170 .map_or(VmValue::Nil, |id| VmValue::Int(id as i64)),
171 );
172 dict.insert(
173 "kind".into(),
174 VmValue::String(Arc::from(self.kind.as_str())),
175 );
176 dict.insert("is_named".into(), VmValue::Bool(self.is_named));
177 dict.insert("start_byte".into(), VmValue::Int(self.start_byte as i64));
178 dict.insert("end_byte".into(), VmValue::Int(self.end_byte as i64));
179 dict.insert("start_row".into(), VmValue::Int(self.start_row as i64));
180 dict.insert("start_col".into(), VmValue::Int(self.start_col as i64));
181 dict.insert("end_row".into(), VmValue::Int(self.end_row as i64));
182 dict.insert("end_col".into(), VmValue::Int(self.end_col as i64));
183 VmValue::Dict(Arc::new(dict))
184 }
185}
186
187#[derive(Debug, Clone)]
195pub struct ParseError {
196 pub start_row: u32,
197 pub start_col: u32,
198 pub end_row: u32,
199 pub end_col: u32,
200 pub start_byte: u32,
201 pub end_byte: u32,
202 pub message: String,
203 pub snippet: String,
204 pub missing: bool,
205}
206
207impl ParseError {
208 pub fn to_vm_value(&self) -> VmValue {
209 let mut dict: BTreeMap<String, VmValue> = BTreeMap::new();
210 dict.insert("start_row".into(), VmValue::Int(self.start_row as i64));
211 dict.insert("start_col".into(), VmValue::Int(self.start_col as i64));
212 dict.insert("end_row".into(), VmValue::Int(self.end_row as i64));
213 dict.insert("end_col".into(), VmValue::Int(self.end_col as i64));
214 dict.insert("start_byte".into(), VmValue::Int(self.start_byte as i64));
215 dict.insert("end_byte".into(), VmValue::Int(self.end_byte as i64));
216 dict.insert(
217 "message".into(),
218 VmValue::String(Arc::from(self.message.as_str())),
219 );
220 dict.insert(
221 "snippet".into(),
222 VmValue::String(Arc::from(self.snippet.as_str())),
223 );
224 dict.insert("missing".into(), VmValue::Bool(self.missing));
225 VmValue::Dict(Arc::new(dict))
226 }
227}
228
229#[derive(Debug, Clone)]
233pub struct UndefinedName {
234 pub name: String,
235 pub kind: &'static str,
236 pub row: u32,
237 pub column: u32,
238}
239
240impl UndefinedName {
241 pub fn to_vm_value(&self) -> VmValue {
242 let mut dict: BTreeMap<String, VmValue> = BTreeMap::new();
243 dict.insert(
244 "name".into(),
245 VmValue::String(Arc::from(self.name.as_str())),
246 );
247 dict.insert("kind".into(), VmValue::String(Arc::from(self.kind)));
248 dict.insert("row".into(), VmValue::Int(self.row as i64));
249 dict.insert("column".into(), VmValue::Int(self.column as i64));
250 let message = format!("undefined name '{}'", self.name);
251 dict.insert(
252 "message".into(),
253 VmValue::String(Arc::from(message.as_str())),
254 );
255 VmValue::Dict(Arc::new(dict))
256 }
257}