1use crate::clangd::ClangdUtility;
2use griff::ChunkStream;
3
4#[derive(Debug, Clone, Default, PartialEq)]
5#[repr(u8)]
6pub enum SymbolKind {
7 #[default]
8 Unknown = 0,
9
10 Module,
11 Namespace,
12 NamespaceAlias,
13 Macro,
14
15 Enum,
16 Struct,
17 Class,
18 Protocol,
19 Extension,
20 Union,
21 TypeAlias,
22
23 Function,
24 Variable,
25 Field,
26 EnumConstant,
27
28 InstanceMethod,
29 ClassMethod,
30 StaticMethod,
31 InstanceProperty,
32 ClassProperty,
33 StaticProperty,
34
35 Constructor,
36 Destructor,
37 ConversionFunction,
38
39 Parameter,
40 Using,
41 TemplateTypeParm,
42 TemplateTemplateParm,
43 NonTypeTemplateParm,
44}
45impl From<u8> for SymbolKind {
46 fn from(b: u8) -> Self {
47 use SymbolKind::*;
48 match b {
49 1 => Module,
50 2 => Namespace,
51 3 => NamespaceAlias,
52 4 => Macro,
53 5 => Enum,
54 6 => Struct,
55 7 => Class,
56 8 => Protocol,
57 9 => Extension,
58 10 => Union,
59 11 => TypeAlias,
60 12 => Function,
61 13 => Variable,
62 14 => Field,
63 15 => EnumConstant,
64 16 => InstanceMethod,
65 17 => ClassMethod,
66 18 => StaticMethod,
67 19 => InstanceProperty,
68 20 => ClassProperty,
69 21 => StaticProperty,
70 22 => Constructor,
71 23 => Destructor,
72 24 => ConversionFunction,
73 25 => Parameter,
74 26 => Using,
75 27 => TemplateTypeParm,
76 28 => TemplateTemplateParm,
77 29 => NonTypeTemplateParm,
78
79 _ => Unknown,
80 }
81 }
82}
83
84#[derive(Debug, Clone, Default)]
85#[repr(u8)]
86pub enum SymbolLanguage {
87 #[default]
88 C,
89
90 ObjC,
91 CXX,
92 Swift,
93}
94impl From<u8> for SymbolLanguage {
95 fn from(b: u8) -> Self {
96 use SymbolLanguage::*;
97
98 match b {
99 1 => ObjC,
100 2 => CXX,
101 3 => Swift,
102 _ => C,
103 }
104 }
105}
106
107#[derive(Debug, Clone, Default)]
108#[repr(u8)]
109#[allow(dead_code)]
110pub enum SymbolSubKind {
111 #[default]
112 None,
113 CXXCopyConstructor,
114 CXXMoveConstructor,
115 AccessorGetter,
116 AccessorSetter,
117 UsingTypename,
118 UsingValue,
119 UsingEnum,
120}
121
122#[derive(Debug, Clone, Default)]
123#[repr(u16)]
124#[allow(dead_code)]
125pub enum SymbolProperty {
126 #[default]
127 Unknown,
128
129 Generic = 1 << 0,
130 TemplatePartialSpecialization = 1 << 1,
131 TemplateSpecialization = 1 << 2,
132 UnitTest = 1 << 3,
133 IBAnnotated = 1 << 4,
134 IBOutletCollection = 1 << 5,
135 GKInspectable = 1 << 6,
136 Local = 1 << 7,
137}
138pub type SymbolPropertySet = u16;
139
140#[derive(Debug, Clone, Default)]
141pub struct SymbolInfo {
142 pub kind: SymbolKind,
143 pub subkind: SymbolSubKind,
144 pub lang: SymbolLanguage,
145 pub properties: SymbolPropertySet,
146}
147
148#[derive(Debug, Clone, Default)]
149pub struct SymbolLocation {
150 pub start: SymbolPosition,
151 pub end: SymbolPosition,
152 pub file_uri: String,
153}
154impl SymbolLocation {
155 pub fn get_location(buf: &[u8], string_table: &Vec<String>) -> (usize, Self) {
156 let mut loc: SymbolLocation = Default::default();
157 let mut bytes_read: usize = 0;
158 let (sz, content) = Symbol::get_string(buf, string_table);
159 loc.file_uri = content;
160 bytes_read += sz;
161
162 let (sz, content) = Symbol::get_varint(buf.get(bytes_read..).unwrap());
163 loc.start.line = content;
164 bytes_read += sz;
165 let (sz, content) = Symbol::get_varint(buf.get(bytes_read..).unwrap());
166 loc.start.column = content;
167 bytes_read += sz;
168
169 let (sz, content) = Symbol::get_varint(buf.get(bytes_read..).unwrap());
170 loc.end.line = content;
171 bytes_read += sz;
172 let (sz, content) = Symbol::get_varint(buf.get(bytes_read..).unwrap());
173 loc.end.column = content;
174 bytes_read += sz;
175
176 (bytes_read, loc)
177 }
178}
179
180#[derive(Debug, Clone, Default)]
181pub struct SymbolPosition {
182 pub line: u32,
183 pub column: u32,
184}
185
186#[derive(Debug, Clone, Default)]
187#[repr(u16)]
188#[allow(dead_code)]
189pub enum SymbolOrigin {
190 #[default]
191 Unknown = 0,
192
193 AST = 1 << 0,
194 Open = 1 << 1,
195 Static = 1 << 2,
196 Merge = 1 << 3,
197 Identifier = 1 << 4,
198 Remote = 1 << 5,
199 Preamble = 1 << 6,
200 Background = 1 << 8,
201 StdLib = 1 << 9,
202}
203
204#[derive(Debug, Clone, Default)]
205#[repr(u8)]
206pub enum SymbolFlags {
207 #[default]
208 None,
209
210 IndexedForCodeCompletion = 1 << 0,
211 Deprecated = 1 << 1,
212 ImplementationDetail = 1 << 2,
213 VisibleOutsideFile = 1 << 3,
214}
215impl From<u8> for SymbolFlags {
216 fn from(b: u8) -> Self {
217 use SymbolFlags::*;
218
219 match b {
220 1 => IndexedForCodeCompletion,
221 2 => Deprecated,
222 4 => ImplementationDetail,
223 8 => VisibleOutsideFile,
224
225 _ => None,
226 }
227 }
228}
229
230#[derive(Debug, Clone, Default)]
231pub struct SymbolIncludedHeader {
232 pub name: String,
233 pub refs: usize,
234 pub supported_directives: usize,
235}
236
237pub type SymbolId = [u8; 8];
238
239#[derive(Debug, Clone, Default)]
240pub struct Symbol {
241 pub id: SymbolId,
242 pub syminfo: SymbolInfo,
243 pub name: String,
244 pub scope: String,
245 pub definition: SymbolLocation,
246 pub canonical_declaration: SymbolLocation,
247 pub references: u32,
248 pub flags: SymbolFlags,
249 pub origin: SymbolOrigin,
250 pub signature: String,
251 pub template_specialization_args: String,
252 pub completion_snippet_suffix: String,
253 pub documentation: String,
254 pub return_t: String,
255 pub t: String,
256 pub headers: Vec<SymbolIncludedHeader>,
257}
258impl ClangdUtility for Symbol {}
259
260impl Symbol {
261 pub fn parse(stream: &ChunkStream, string_table: &Vec<String>) -> Vec<Symbol> {
262 let mut syms: Vec<Symbol> = vec![];
263 let len = stream.data.len();
264 let data = stream.data.as_slice();
265 if data.len() == 0 {
266 return syms;
267 }
268 let mut cursor: usize = 0;
269 let mut idx: u32;
270 loop {
271 let mut s: Symbol = Default::default();
272 s.id = data.get(cursor..cursor+8).unwrap().try_into().unwrap();
273 cursor += 8;
274 s.syminfo.kind = SymbolKind::from(data[cursor]);
276 cursor += 1;
277 s.syminfo.lang = SymbolLanguage::from(data[cursor]);
279 cursor += 1;
280 let (sz, content) = Self::get_string(&data.get(cursor..).unwrap(), string_table);
281 s.name = content;
282 cursor += sz;
283 let (sz, content) = Self::get_string(&data.get(cursor..).unwrap(), string_table);
285 s.scope = content;
286 cursor += sz;
287 let (sz, content) = Self::get_string(&data.get(cursor..).unwrap(), string_table);
289 s.template_specialization_args = content;
290 cursor += sz;
291 let (sz, loc) = SymbolLocation::get_location(&data.get(cursor..).unwrap(), string_table);
293 s.definition = loc;
294 cursor += sz;
295 let (sz, loc) = SymbolLocation::get_location(&data.get(cursor..).unwrap(), string_table);
297 s.canonical_declaration = loc;
298 cursor += sz;
299 let (sz, content) = Self::get_varint(&data.get(cursor..).unwrap());
301 s.references = content;
302 cursor += sz;
303 s.flags = SymbolFlags::from(*data.get(cursor).unwrap());
305 cursor += 1;
306 let (sz, content) = Self::get_string(&data.get(cursor..).unwrap(), string_table);
308 s.signature = content;
309 cursor += sz;
310 let (sz, content) = Self::get_string(&data.get(cursor..).unwrap(), string_table);
312 s.completion_snippet_suffix = content;
313 cursor += sz;
314 let (sz, content) = Self::get_string(&data.get(cursor..).unwrap(), string_table);
316 s.documentation = content;
317 cursor += sz;
318 let (sz, content) = Self::get_string(&data.get(cursor..).unwrap(), string_table);
320 s.return_t = content;
321 cursor += sz;
322 let (sz, content) = Self::get_string(&data.get(cursor..).unwrap(), string_table);
324 s.t = content;
325 cursor += sz;
326 let (sz, h_content) = Self::get_varint(&data.get(cursor..).unwrap());
328 cursor += sz;
329 idx = 0;
330 while idx < h_content {
331 let mut hdr: SymbolIncludedHeader = Default::default();
332 let (sz, content) = Self::get_string(&data.get(cursor..).unwrap(), string_table);
333 hdr.name = content;
334 cursor += sz;
335 let (sz, content) = Self::get_varint(&data.get(cursor..).unwrap());
336 hdr.refs = (content >> 2) as usize;
337 hdr.supported_directives = (content & 0x3) as usize;
338 s.headers.push(hdr);
339 cursor += sz;
340 idx += 1;
341 }
342 syms.push(s.clone());
343 if cursor >= len {
344 break;
345 }
346 }
347 syms
348 }
349}