diff options
Diffstat (limited to 'src/parsing/clang/entities.rs')
-rw-r--r-- | src/parsing/clang/entities.rs | 369 |
1 files changed, 369 insertions, 0 deletions
diff --git a/src/parsing/clang/entities.rs b/src/parsing/clang/entities.rs new file mode 100644 index 0000000..a8062bb --- /dev/null +++ b/src/parsing/clang/entities.rs | |||
@@ -0,0 +1,369 @@ | |||
1 | use crate::types::Entity; | ||
2 | |||
3 | use clang::{EntityKind, Usr}; | ||
4 | use thiserror::Error; | ||
5 | |||
6 | use std::collections::BTreeMap; | ||
7 | use std::convert::TryFrom; | ||
8 | |||
9 | // TODO: factor out hardcoded strings | ||
10 | |||
11 | #[derive(Debug)] | ||
12 | pub(super) struct Children { | ||
13 | namespaces: Option<BTreeMap<Usr, Described<Namespace>>>, | ||
14 | variables: Option<BTreeMap<Usr, Described<Variable>>>, | ||
15 | structs: Option<BTreeMap<Usr, Described<Struct>>>, | ||
16 | functions: Option<BTreeMap<Usr, Described<Function>>>, | ||
17 | } | ||
18 | |||
19 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
20 | pub(super) enum ClangEntityKind { | ||
21 | Namespace, | ||
22 | Variable(VariableKind), | ||
23 | Struct(StructKind), | ||
24 | Function(FunctionKind), | ||
25 | } | ||
26 | |||
27 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
28 | pub(super) enum VariableKind { | ||
29 | Variable, | ||
30 | Field, | ||
31 | } | ||
32 | |||
33 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
34 | pub(super) enum StructKind { | ||
35 | Struct, | ||
36 | Class, | ||
37 | } | ||
38 | |||
39 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
40 | pub(super) enum FunctionKind { | ||
41 | Function, | ||
42 | Method, | ||
43 | } | ||
44 | |||
45 | #[derive(Debug, Error)] | ||
46 | #[error("Unsupported Clang entity kind: {:?}", _0)] | ||
47 | pub(super) struct TryFromEntityKindError(String); | ||
48 | |||
49 | impl TryFrom<EntityKind> for ClangEntityKind { | ||
50 | type Error = TryFromEntityKindError; | ||
51 | |||
52 | fn try_from(kind: EntityKind) -> Result<ClangEntityKind, TryFromEntityKindError> { | ||
53 | Ok(match kind { | ||
54 | EntityKind::Namespace => ClangEntityKind::Namespace, | ||
55 | EntityKind::VarDecl => ClangEntityKind::Variable(VariableKind::Variable), | ||
56 | EntityKind::FieldDecl => ClangEntityKind::Variable(VariableKind::Field), | ||
57 | EntityKind::FunctionDecl => ClangEntityKind::Function(FunctionKind::Function), | ||
58 | EntityKind::Method | EntityKind::Constructor => { | ||
59 | ClangEntityKind::Function(FunctionKind::Method) | ||
60 | } | ||
61 | EntityKind::StructDecl => ClangEntityKind::Struct(StructKind::Struct), | ||
62 | EntityKind::ClassDecl => ClangEntityKind::Struct(StructKind::Class), | ||
63 | kind => return Err(TryFromEntityKindError(format!("{:?}", kind))), | ||
64 | }) | ||
65 | } | ||
66 | } | ||
67 | |||
68 | pub(super) trait ClangEntity { | ||
69 | fn kind(&self) -> &'static str; | ||
70 | |||
71 | fn get_member_namespaces(&mut self) -> Option<&mut BTreeMap<Usr, Described<Namespace>>> { | ||
72 | None | ||
73 | } | ||
74 | fn get_member_variables(&mut self) -> Option<&mut BTreeMap<Usr, Described<Variable>>> { | ||
75 | None | ||
76 | } | ||
77 | fn get_member_structs(&mut self) -> Option<&mut BTreeMap<Usr, Described<Struct>>> { | ||
78 | None | ||
79 | } | ||
80 | fn get_member_functions(&mut self) -> Option<&mut BTreeMap<Usr, Described<Function>>> { | ||
81 | None | ||
82 | } | ||
83 | |||
84 | fn into_children(self) -> Children | ||
85 | where | ||
86 | Self: Sized, | ||
87 | { | ||
88 | Children { | ||
89 | namespaces: None, | ||
90 | variables: None, | ||
91 | structs: None, | ||
92 | functions: None, | ||
93 | } | ||
94 | } | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | pub(super) trait FromNamespaceParent: ClangEntity + Sized { | ||
99 | fn from_namespace_parent<'a>( | ||
100 | parent: &'a mut Described<Namespace>, | ||
101 | name: &Usr, | ||
102 | ) -> Option<&'a mut Described<Self>>; | ||
103 | } | ||
104 | */ | ||
105 | |||
106 | pub(super) trait NamespaceParentManipulation<T: ClangEntity + Sized> { | ||
107 | fn get_members_mut(&mut self) -> Option<&mut BTreeMap<Usr, Described<T>>>; | ||
108 | } | ||
109 | |||
110 | impl<U> NamespaceParentManipulation<Namespace> for U | ||
111 | where | ||
112 | U: ClangEntity, | ||
113 | { | ||
114 | fn get_members_mut(&mut self) -> Option<&mut BTreeMap<Usr, Described<Namespace>>> { | ||
115 | self.get_member_namespaces() | ||
116 | } | ||
117 | } | ||
118 | |||
119 | impl<U> NamespaceParentManipulation<Variable> for U | ||
120 | where | ||
121 | U: ClangEntity, | ||
122 | { | ||
123 | fn get_members_mut(&mut self) -> Option<&mut BTreeMap<Usr, Described<Variable>>> { | ||
124 | self.get_member_variables() | ||
125 | } | ||
126 | } | ||
127 | |||
128 | impl<U> NamespaceParentManipulation<Function> for U | ||
129 | where | ||
130 | U: ClangEntity, | ||
131 | { | ||
132 | fn get_members_mut(&mut self) -> Option<&mut BTreeMap<Usr, Described<Function>>> { | ||
133 | self.get_member_functions() | ||
134 | } | ||
135 | } | ||
136 | |||
137 | impl<U> NamespaceParentManipulation<Struct> for U | ||
138 | where | ||
139 | U: ClangEntity, | ||
140 | { | ||
141 | fn get_members_mut(&mut self) -> Option<&mut BTreeMap<Usr, Described<Struct>>> { | ||
142 | self.get_member_structs() | ||
143 | } | ||
144 | } | ||
145 | |||
146 | impl<T: ClangEntity> From<Described<T>> for Entity { | ||
147 | fn from(entity: Described<T>) -> Self { | ||
148 | let mut children = BTreeMap::new(); | ||
149 | |||
150 | let kind = String::from(entity.entity.kind()); | ||
151 | let clang_children = entity.entity.into_children(); | ||
152 | |||
153 | if let Some(namespaces) = clang_children.namespaces { | ||
154 | children.insert( | ||
155 | String::from("namespace"), | ||
156 | namespaces | ||
157 | .into_iter() | ||
158 | .map(|(usr, namespace)| (usr.0, namespace.into())) | ||
159 | .collect(), | ||
160 | ); | ||
161 | } | ||
162 | |||
163 | if let Some(variables) = clang_children.variables { | ||
164 | children.insert( | ||
165 | String::from("variable"), | ||
166 | variables | ||
167 | .into_iter() | ||
168 | .map(|(usr, variable)| (usr.0, variable.into())) | ||
169 | .collect(), | ||
170 | ); | ||
171 | } | ||
172 | |||
173 | if let Some(structs) = clang_children.structs { | ||
174 | children.insert( | ||
175 | String::from("struct"), | ||
176 | structs | ||
177 | .into_iter() | ||
178 | .map(|(usr, the_struct)| (usr.0, the_struct.into())) | ||
179 | .collect(), | ||
180 | ); | ||
181 | } | ||
182 | |||
183 | if let Some(functions) = clang_children.functions { | ||
184 | children.insert( | ||
185 | String::from("function"), | ||
186 | functions | ||
187 | .into_iter() | ||
188 | .map(|(usr, function)| (usr.0, function.into())) | ||
189 | .collect(), | ||
190 | ); | ||
191 | } | ||
192 | |||
193 | Entity { | ||
194 | name: entity.description.name, | ||
195 | language: String::from("clang"), | ||
196 | kind, | ||
197 | brief_description: entity.description.brief, | ||
198 | documentation: entity.description.detailed, | ||
199 | children, | ||
200 | } | ||
201 | } | ||
202 | } | ||
203 | |||
204 | #[derive(Debug, Clone, Default)] | ||
205 | pub(super) struct Description { | ||
206 | pub(super) name: String, | ||
207 | pub(super) brief: String, | ||
208 | pub(super) detailed: String, | ||
209 | } | ||
210 | |||
211 | #[derive(Debug, Clone)] | ||
212 | pub(super) struct Described<T> { | ||
213 | pub(super) description: Description, | ||
214 | pub(super) entity: T, | ||
215 | } | ||
216 | |||
217 | #[derive(Debug, Clone)] | ||
218 | pub(super) struct Namespace { | ||
219 | pub(super) member_namespaces: BTreeMap<Usr, Described<Namespace>>, | ||
220 | pub(super) member_variables: BTreeMap<Usr, Described<Variable>>, | ||
221 | pub(super) member_structs: BTreeMap<Usr, Described<Struct>>, | ||
222 | pub(super) member_functions: BTreeMap<Usr, Described<Function>>, | ||
223 | } | ||
224 | |||
225 | impl ClangEntity for Namespace { | ||
226 | fn kind(&self) -> &'static str { | ||
227 | "namespace" | ||
228 | } | ||
229 | |||
230 | fn get_member_namespaces(&mut self) -> Option<&mut BTreeMap<Usr, Described<Namespace>>> { | ||
231 | Some(&mut self.member_namespaces) | ||
232 | } | ||
233 | fn get_member_variables(&mut self) -> Option<&mut BTreeMap<Usr, Described<Variable>>> { | ||
234 | Some(&mut self.member_variables) | ||
235 | } | ||
236 | fn get_member_structs(&mut self) -> Option<&mut BTreeMap<Usr, Described<Struct>>> { | ||
237 | Some(&mut self.member_structs) | ||
238 | } | ||
239 | fn get_member_functions(&mut self) -> Option<&mut BTreeMap<Usr, Described<Function>>> { | ||
240 | Some(&mut self.member_functions) | ||
241 | } | ||
242 | |||
243 | fn into_children(self) -> Children { | ||
244 | Children { | ||
245 | namespaces: Some(self.member_namespaces), | ||
246 | variables: Some(self.member_variables), | ||
247 | structs: Some(self.member_structs), | ||
248 | functions: Some(self.member_functions), | ||
249 | } | ||
250 | } | ||
251 | } | ||
252 | |||
253 | /* | ||
254 | impl FromNamespaceParent for Namespace { | ||
255 | fn from_namespace_parent<'a>( | ||
256 | parent: &'a mut Described<Namespace>, | ||
257 | name: &Usr, | ||
258 | ) -> Option<&'a mut Described<Self>> { | ||
259 | parent.entity.member_namespaces.get_mut(name) | ||
260 | } | ||
261 | } | ||
262 | */ | ||
263 | |||
264 | #[derive(Debug, Clone)] | ||
265 | pub(super) struct Variable { | ||
266 | pub(super) kind: VariableKind, | ||
267 | pub(super) r#type: String, | ||
268 | } | ||
269 | |||
270 | impl ClangEntity for Variable { | ||
271 | fn kind(&self) -> &'static str { | ||
272 | match self.kind { | ||
273 | VariableKind::Variable => "variable", | ||
274 | VariableKind::Field => "field", | ||
275 | } | ||
276 | } | ||
277 | } | ||
278 | |||
279 | /* | ||
280 | impl FromNamespaceParent for Variable { | ||
281 | fn from_namespace_parent<'a>( | ||
282 | parent: &'a mut Described<Namespace>, | ||
283 | name: &Usr, | ||
284 | ) -> Option<&'a mut Described<Self>> { | ||
285 | parent.entity.member_variables.get_mut(name) | ||
286 | } | ||
287 | } | ||
288 | */ | ||
289 | |||
290 | #[derive(Debug, Clone)] | ||
291 | pub(super) struct Struct { | ||
292 | //pub(super) member_types: Vec<Usr>, | ||
293 | pub(super) kind: StructKind, | ||
294 | pub(super) member_variables: BTreeMap<Usr, Described<Variable>>, | ||
295 | pub(super) member_structs: BTreeMap<Usr, Described<Struct>>, | ||
296 | pub(super) member_functions: BTreeMap<Usr, Described<Function>>, | ||
297 | } | ||
298 | |||
299 | impl ClangEntity for Struct { | ||
300 | fn kind(&self) -> &'static str { | ||
301 | match self.kind { | ||
302 | StructKind::Struct => "struct", | ||
303 | StructKind::Class => "class", | ||
304 | } | ||
305 | } | ||
306 | |||
307 | fn get_member_variables(&mut self) -> Option<&mut BTreeMap<Usr, Described<Variable>>> { | ||
308 | Some(&mut self.member_variables) | ||
309 | } | ||
310 | fn get_member_structs(&mut self) -> Option<&mut BTreeMap<Usr, Described<Struct>>> { | ||
311 | Some(&mut self.member_structs) | ||
312 | } | ||
313 | fn get_member_functions(&mut self) -> Option<&mut BTreeMap<Usr, Described<Function>>> { | ||
314 | Some(&mut self.member_functions) | ||
315 | } | ||
316 | |||
317 | fn into_children(self) -> Children { | ||
318 | Children { | ||
319 | namespaces: None, | ||
320 | variables: Some(self.member_variables), | ||
321 | structs: Some(self.member_structs), | ||
322 | functions: Some(self.member_functions), | ||
323 | } | ||
324 | } | ||
325 | } | ||
326 | |||
327 | /* | ||
328 | impl FromNamespaceParent for Struct { | ||
329 | fn from_namespace_parent<'a>( | ||
330 | parent: &'a mut Described<Namespace>, | ||
331 | name: &Usr, | ||
332 | ) -> Option<&'a mut Described<Self>> { | ||
333 | parent.entity.member_structs.get_mut(name) | ||
334 | } | ||
335 | } | ||
336 | */ | ||
337 | |||
338 | #[derive(Debug, Clone)] | ||
339 | pub(super) struct Function { | ||
340 | pub(super) kind: FunctionKind, | ||
341 | pub(super) arguments: Vec<FunctionArgument>, | ||
342 | pub(super) return_type: String, | ||
343 | } | ||
344 | |||
345 | impl ClangEntity for Function { | ||
346 | fn kind(&self) -> &'static str { | ||
347 | match self.kind { | ||
348 | FunctionKind::Function => "function", | ||
349 | FunctionKind::Method => "method", | ||
350 | } | ||
351 | } | ||
352 | } | ||
353 | |||
354 | /* | ||
355 | impl FromNamespaceParent for Function { | ||
356 | fn from_namespace_parent<'a>( | ||
357 | parent: &'a mut Described<Namespace>, | ||
358 | name: &Usr, | ||
359 | ) -> Option<&'a mut Described<Self>> { | ||
360 | parent.entity.member_functions.get_mut(name) | ||
361 | } | ||
362 | } | ||
363 | */ | ||
364 | |||
365 | #[derive(Debug, Clone)] | ||
366 | pub(super) struct FunctionArgument { | ||
367 | pub(super) name: String, | ||
368 | pub(super) r#type: String, | ||
369 | } | ||