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