summaryrefslogtreecommitdiffstats
path: root/src/parsing/clang/entities.rs
diff options
context:
space:
mode:
authorMinijackson <minijackson@riseup.net>2019-12-18 20:56:53 +0100
committerMinijackson <minijackson@riseup.net>2019-12-18 20:56:53 +0100
commitde896baff7e97fac4dde79078c9a2fa1c652576b (patch)
tree512b67b91d64e51d63f7ac5ff925a5c96d9aaf3c /src/parsing/clang/entities.rs
parent860b73f1644ecd6548ae403ec483625fb7b625ea (diff)
downloadposeidoc-de896baff7e97fac4dde79078c9a2fa1c652576b.tar.gz
poseidoc-de896baff7e97fac4dde79078c9a2fa1c652576b.zip
Big refactoring
- entities should be more coherent when parsing multiple files - well defined, language agnostic entity tree - each module has its own configuration - less dead code
Diffstat (limited to 'src/parsing/clang/entities.rs')
-rw-r--r--src/parsing/clang/entities.rs369
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 @@
1use crate::types::Entity;
2
3use clang::{EntityKind, Usr};
4use thiserror::Error;
5
6use std::collections::BTreeMap;
7use std::convert::TryFrom;
8
9// TODO: factor out hardcoded strings
10
11#[derive(Debug)]
12pub(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)]
20pub(super) enum ClangEntityKind {
21 Namespace,
22 Variable(VariableKind),
23 Struct(StructKind),
24 Function(FunctionKind),
25}
26
27#[derive(Debug, Clone, PartialEq, Eq)]
28pub(super) enum VariableKind {
29 Variable,
30 Field,
31}
32
33#[derive(Debug, Clone, PartialEq, Eq)]
34pub(super) enum StructKind {
35 Struct,
36 Class,
37}
38
39#[derive(Debug, Clone, PartialEq, Eq)]
40pub(super) enum FunctionKind {
41 Function,
42 Method,
43}
44
45#[derive(Debug, Error)]
46#[error("Unsupported Clang entity kind: {:?}", _0)]
47pub(super) struct TryFromEntityKindError(String);
48
49impl 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
68pub(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/*
98pub(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
106pub(super) trait NamespaceParentManipulation<T: ClangEntity + Sized> {
107 fn get_members_mut(&mut self) -> Option<&mut BTreeMap<Usr, Described<T>>>;
108}
109
110impl<U> NamespaceParentManipulation<Namespace> for U
111where
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
119impl<U> NamespaceParentManipulation<Variable> for U
120where
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
128impl<U> NamespaceParentManipulation<Function> for U
129where
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
137impl<U> NamespaceParentManipulation<Struct> for U
138where
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
146impl<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)]
205pub(super) struct Description {
206 pub(super) name: String,
207 pub(super) brief: String,
208 pub(super) detailed: String,
209}
210
211#[derive(Debug, Clone)]
212pub(super) struct Described<T> {
213 pub(super) description: Description,
214 pub(super) entity: T,
215}
216
217#[derive(Debug, Clone)]
218pub(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
225impl 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/*
254impl 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)]
265pub(super) struct Variable {
266 pub(super) kind: VariableKind,
267 pub(super) r#type: String,
268}
269
270impl 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/*
280impl 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)]
291pub(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
299impl 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/*
328impl 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)]
339pub(super) struct Function {
340 pub(super) kind: FunctionKind,
341 pub(super) arguments: Vec<FunctionArgument>,
342 pub(super) return_type: String,
343}
344
345impl 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/*
355impl 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)]
366pub(super) struct FunctionArgument {
367 pub(super) name: String,
368 pub(super) r#type: String,
369}