diff options
-rw-r--r-- | src/parser/clang/entities.rs | 84 | ||||
-rw-r--r-- | src/parser/clang/parsing.rs | 86 |
2 files changed, 168 insertions, 2 deletions
diff --git a/src/parser/clang/entities.rs b/src/parser/clang/entities.rs index 8da85d9..0e9305b 100644 --- a/src/parser/clang/entities.rs +++ b/src/parser/clang/entities.rs | |||
@@ -16,6 +16,8 @@ pub(super) enum ClangEntityKind { | |||
16 | Struct(StructKind), | 16 | Struct(StructKind), |
17 | Function(FunctionKind), | 17 | Function(FunctionKind), |
18 | Typedef, | 18 | Typedef, |
19 | Enum, | ||
20 | EnumConstant, | ||
19 | } | 21 | } |
20 | 22 | ||
21 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 23 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
@@ -47,6 +49,8 @@ impl ClangEntityKind { | |||
47 | ClangEntityKind::Function(FunctionKind::Function) => "function", | 49 | ClangEntityKind::Function(FunctionKind::Function) => "function", |
48 | ClangEntityKind::Function(FunctionKind::Method) => "method", | 50 | ClangEntityKind::Function(FunctionKind::Method) => "method", |
49 | ClangEntityKind::Typedef => "typedef", | 51 | ClangEntityKind::Typedef => "typedef", |
52 | ClangEntityKind::Enum => "enum", | ||
53 | ClangEntityKind::EnumConstant => "enum-constant", | ||
50 | } | 54 | } |
51 | } | 55 | } |
52 | 56 | ||
@@ -60,6 +64,8 @@ impl ClangEntityKind { | |||
60 | ClangEntityKind::Function(FunctionKind::Function) => "functions", | 64 | ClangEntityKind::Function(FunctionKind::Function) => "functions", |
61 | ClangEntityKind::Function(FunctionKind::Method) => "methods", | 65 | ClangEntityKind::Function(FunctionKind::Method) => "methods", |
62 | ClangEntityKind::Typedef => "typedefs", | 66 | ClangEntityKind::Typedef => "typedefs", |
67 | ClangEntityKind::Enum => "enums", | ||
68 | ClangEntityKind::EnumConstant => "enum-constants", | ||
63 | } | 69 | } |
64 | } | 70 | } |
65 | } | 71 | } |
@@ -89,6 +95,8 @@ impl TryFrom<EntityKind> for ClangEntityKind { | |||
89 | EntityKind::TypedefDecl | 95 | EntityKind::TypedefDecl |
90 | | EntityKind::TypeAliasDecl | 96 | | EntityKind::TypeAliasDecl |
91 | | EntityKind::TypeAliasTemplateDecl => ClangEntityKind::Typedef, | 97 | | EntityKind::TypeAliasTemplateDecl => ClangEntityKind::Typedef, |
98 | EntityKind::EnumDecl => ClangEntityKind::Enum, | ||
99 | EntityKind::EnumConstantDecl => ClangEntityKind::EnumConstant, | ||
92 | kind => return Err(TryFromEntityKindError(format!("{:?}", kind))), | 100 | kind => return Err(TryFromEntityKindError(format!("{:?}", kind))), |
93 | }) | 101 | }) |
94 | } | 102 | } |
@@ -118,6 +126,9 @@ pub(super) trait ClangEntity { | |||
118 | fn get_member_typedefs(&mut self) -> Option<&mut BTreeMap<Usr, Described<Typedef>>> { | 126 | fn get_member_typedefs(&mut self) -> Option<&mut BTreeMap<Usr, Described<Typedef>>> { |
119 | None | 127 | None |
120 | } | 128 | } |
129 | fn get_member_enums(&mut self) -> Option<&mut BTreeMap<Usr, Described<Enum>>> { | ||
130 | None | ||
131 | } | ||
121 | } | 132 | } |
122 | 133 | ||
123 | /* | 134 | /* |
@@ -178,6 +189,15 @@ where | |||
178 | } | 189 | } |
179 | } | 190 | } |
180 | 191 | ||
192 | impl<U> NamespaceParentManipulation<Enum> for U | ||
193 | where | ||
194 | U: ClangEntity, | ||
195 | { | ||
196 | fn get_members_mut(&mut self) -> Option<&mut BTreeMap<Usr, Described<Enum>>> { | ||
197 | self.get_member_enums() | ||
198 | } | ||
199 | } | ||
200 | |||
181 | fn entity_id(usr: Usr) -> EntityId { | 201 | fn entity_id(usr: Usr) -> EntityId { |
182 | // This is a somewhat ugly workaround, because Pandoc parses markdown identifiers as alphanum | 202 | // This is a somewhat ugly workaround, because Pandoc parses markdown identifiers as alphanum |
183 | // or one of "-_:.", which means Pandoc can't parse libclang's USRs in title ids and related. | 203 | // or one of "-_:.", which means Pandoc can't parse libclang's USRs in title ids and related. |
@@ -236,6 +256,7 @@ pub(super) struct Namespace { | |||
236 | pub(super) member_structs: BTreeMap<Usr, Described<Struct>>, | 256 | pub(super) member_structs: BTreeMap<Usr, Described<Struct>>, |
237 | pub(super) member_functions: BTreeMap<Usr, Described<Function>>, | 257 | pub(super) member_functions: BTreeMap<Usr, Described<Function>>, |
238 | pub(super) member_typedefs: BTreeMap<Usr, Described<Typedef>>, | 258 | pub(super) member_typedefs: BTreeMap<Usr, Described<Typedef>>, |
259 | pub(super) member_enums: BTreeMap<Usr, Described<Enum>>, | ||
239 | } | 260 | } |
240 | 261 | ||
241 | impl ClangEntity for Namespace { | 262 | impl ClangEntity for Namespace { |
@@ -258,6 +279,9 @@ impl ClangEntity for Namespace { | |||
258 | fn get_member_typedefs(&mut self) -> Option<&mut BTreeMap<Usr, Described<Typedef>>> { | 279 | fn get_member_typedefs(&mut self) -> Option<&mut BTreeMap<Usr, Described<Typedef>>> { |
259 | Some(&mut self.member_typedefs) | 280 | Some(&mut self.member_typedefs) |
260 | } | 281 | } |
282 | fn get_member_enums(&mut self) -> Option<&mut BTreeMap<Usr, Described<Enum>>> { | ||
283 | Some(&mut self.member_enums) | ||
284 | } | ||
261 | } | 285 | } |
262 | 286 | ||
263 | /* | 287 | /* |
@@ -279,6 +303,8 @@ impl From<Namespace> for PartialEntity { | |||
279 | append_children(&mut children, entity.member_structs); | 303 | append_children(&mut children, entity.member_structs); |
280 | append_children(&mut children, entity.member_functions); | 304 | append_children(&mut children, entity.member_functions); |
281 | append_children(&mut children, entity.member_typedefs); | 305 | append_children(&mut children, entity.member_typedefs); |
306 | append_children(&mut children, entity.member_enums); | ||
307 | |||
282 | PartialEntity { | 308 | PartialEntity { |
283 | properties: Default::default(), | 309 | properties: Default::default(), |
284 | children, | 310 | children, |
@@ -328,6 +354,7 @@ pub(super) struct Struct { | |||
328 | pub(super) member_structs: BTreeMap<Usr, Described<Struct>>, | 354 | pub(super) member_structs: BTreeMap<Usr, Described<Struct>>, |
329 | pub(super) member_functions: BTreeMap<Usr, Described<Function>>, | 355 | pub(super) member_functions: BTreeMap<Usr, Described<Function>>, |
330 | pub(super) member_typedefs: BTreeMap<Usr, Described<Typedef>>, | 356 | pub(super) member_typedefs: BTreeMap<Usr, Described<Typedef>>, |
357 | pub(super) member_enums: BTreeMap<Usr, Described<Enum>>, | ||
331 | } | 358 | } |
332 | 359 | ||
333 | impl ClangEntity for Struct { | 360 | impl ClangEntity for Struct { |
@@ -347,6 +374,9 @@ impl ClangEntity for Struct { | |||
347 | fn get_member_typedefs(&mut self) -> Option<&mut BTreeMap<Usr, Described<Typedef>>> { | 374 | fn get_member_typedefs(&mut self) -> Option<&mut BTreeMap<Usr, Described<Typedef>>> { |
348 | Some(&mut self.member_typedefs) | 375 | Some(&mut self.member_typedefs) |
349 | } | 376 | } |
377 | fn get_member_enums(&mut self) -> Option<&mut BTreeMap<Usr, Described<Enum>>> { | ||
378 | Some(&mut self.member_enums) | ||
379 | } | ||
350 | } | 380 | } |
351 | 381 | ||
352 | impl From<Struct> for PartialEntity { | 382 | impl From<Struct> for PartialEntity { |
@@ -356,6 +386,7 @@ impl From<Struct> for PartialEntity { | |||
356 | append_children(&mut children, entity.member_structs); | 386 | append_children(&mut children, entity.member_structs); |
357 | append_children(&mut children, entity.member_functions); | 387 | append_children(&mut children, entity.member_functions); |
358 | append_children(&mut children, entity.member_typedefs); | 388 | append_children(&mut children, entity.member_typedefs); |
389 | append_children(&mut children, entity.member_enums); | ||
359 | 390 | ||
360 | PartialEntity { | 391 | PartialEntity { |
361 | properties: Default::default(), | 392 | properties: Default::default(), |
@@ -455,3 +486,56 @@ impl From<Typedef> for PartialEntity { | |||
455 | } | 486 | } |
456 | } | 487 | } |
457 | } | 488 | } |
489 | |||
490 | #[derive(Debug, Clone)] | ||
491 | pub(super) struct Enum { | ||
492 | pub(super) underlying_type: String, | ||
493 | pub(super) constants: BTreeMap<Usr, Described<EnumConstant>>, | ||
494 | } | ||
495 | |||
496 | impl ClangEntity for Enum { | ||
497 | fn kind(&self) -> ClangEntityKind { | ||
498 | ClangEntityKind::Enum | ||
499 | } | ||
500 | } | ||
501 | |||
502 | impl From<Enum> for PartialEntity { | ||
503 | fn from(entity: Enum) -> Self { | ||
504 | let mut properties = Map::with_capacity(1); | ||
505 | properties.insert( | ||
506 | String::from("underlying-type"), | ||
507 | JSONValue::String(entity.underlying_type), | ||
508 | ); | ||
509 | |||
510 | let mut children = Default::default(); | ||
511 | append_children(&mut children, entity.constants); | ||
512 | |||
513 | PartialEntity { | ||
514 | properties, | ||
515 | children, | ||
516 | } | ||
517 | } | ||
518 | } | ||
519 | |||
520 | #[derive(Debug, Clone)] | ||
521 | pub(super) struct EnumConstant { | ||
522 | pub(super) value: String, | ||
523 | } | ||
524 | |||
525 | impl ClangEntity for EnumConstant { | ||
526 | fn kind(&self) -> ClangEntityKind { | ||
527 | ClangEntityKind::EnumConstant | ||
528 | } | ||
529 | } | ||
530 | |||
531 | impl From<EnumConstant> for PartialEntity { | ||
532 | fn from(entity: EnumConstant) -> Self { | ||
533 | let mut properties = Map::with_capacity(1); | ||
534 | properties.insert(String::from("value"), JSONValue::String(entity.value)); | ||
535 | |||
536 | PartialEntity { | ||
537 | properties, | ||
538 | children: Default::default(), | ||
539 | } | ||
540 | } | ||
541 | } | ||
diff --git a/src/parser/clang/parsing.rs b/src/parser/clang/parsing.rs index 1f1691f..251aefa 100644 --- a/src/parser/clang/parsing.rs +++ b/src/parser/clang/parsing.rs | |||
@@ -20,6 +20,7 @@ struct TopLevel { | |||
20 | structs: BTreeMap<Usr, Described<Struct>>, | 20 | structs: BTreeMap<Usr, Described<Struct>>, |
21 | functions: BTreeMap<Usr, Described<Function>>, | 21 | functions: BTreeMap<Usr, Described<Function>>, |
22 | typedefs: BTreeMap<Usr, Described<Typedef>>, | 22 | typedefs: BTreeMap<Usr, Described<Typedef>>, |
23 | enums: BTreeMap<Usr, Described<Enum>>, | ||
23 | } | 24 | } |
24 | 25 | ||
25 | /* | 26 | /* |
@@ -88,6 +89,10 @@ impl TopLevel { | |||
88 | ClangEntityKind::Typedef => { | 89 | ClangEntityKind::Typedef => { |
89 | &mut parent.get_member_typedefs()?.get_mut(&usr)?.entity | 90 | &mut parent.get_member_typedefs()?.get_mut(&usr)?.entity |
90 | } | 91 | } |
92 | ClangEntityKind::Enum => &mut parent.get_member_enums()?.get_mut(&usr)?.entity, | ||
93 | ClangEntityKind::EnumConstant => { | ||
94 | panic!("enum variant getting"); | ||
95 | } | ||
91 | }) | 96 | }) |
92 | } else { | 97 | } else { |
93 | Some(match path.get_kind().try_into().ok()? { | 98 | Some(match path.get_kind().try_into().ok()? { |
@@ -96,6 +101,8 @@ impl TopLevel { | |||
96 | ClangEntityKind::Struct(_) => &mut self.structs.get_mut(&usr)?.entity, | 101 | ClangEntityKind::Struct(_) => &mut self.structs.get_mut(&usr)?.entity, |
97 | ClangEntityKind::Function(_) => &mut self.functions.get_mut(&usr)?.entity, | 102 | ClangEntityKind::Function(_) => &mut self.functions.get_mut(&usr)?.entity, |
98 | ClangEntityKind::Typedef => &mut self.typedefs.get_mut(&usr)?.entity, | 103 | ClangEntityKind::Typedef => &mut self.typedefs.get_mut(&usr)?.entity, |
104 | ClangEntityKind::Enum => &mut self.enums.get_mut(&usr)?.entity, | ||
105 | ClangEntityKind::EnumConstant => panic!("enum variant getting"), | ||
99 | }) | 106 | }) |
100 | } | 107 | } |
101 | } | 108 | } |
@@ -191,6 +198,12 @@ impl TopLevelManipulation<Typedef> for TopLevel { | |||
191 | } | 198 | } |
192 | } | 199 | } |
193 | 200 | ||
201 | impl TopLevelManipulation<Enum> for TopLevel { | ||
202 | fn insert_toplevel(&mut self, usr: Usr, entity: Described<Enum>) { | ||
203 | self.enums.insert(usr, entity); | ||
204 | } | ||
205 | } | ||
206 | |||
194 | /* | 207 | /* |
195 | trait FromTopLevel: ClangEntity + Sized { | 208 | trait FromTopLevel: ClangEntity + Sized { |
196 | fn from_toplevel<'a>(toplevel: &'a mut TopLevel, usr: &Usr) -> Option<&'a mut Described<Self>>; | 209 | fn from_toplevel<'a>(toplevel: &'a mut TopLevel, usr: &Usr) -> Option<&'a mut Described<Self>>; |
@@ -526,7 +539,10 @@ fn add_entity( | |||
526 | ClangEntityKind::Function(_) => Described::<Function>::try_from(libclang_entity) | 539 | ClangEntityKind::Function(_) => Described::<Function>::try_from(libclang_entity) |
527 | .and_then(|function| toplevel.insert(libclang_entity, function)), | 540 | .and_then(|function| toplevel.insert(libclang_entity, function)), |
528 | ClangEntityKind::Typedef => Described::<Typedef>::try_from(libclang_entity) | 541 | ClangEntityKind::Typedef => Described::<Typedef>::try_from(libclang_entity) |
529 | .and_then(|function| toplevel.insert(libclang_entity, function)), | 542 | .and_then(|typedef| toplevel.insert(libclang_entity, typedef)), |
543 | ClangEntityKind::Enum => Described::<Enum>::try_from(libclang_entity) | ||
544 | .and_then(|r#enum| toplevel.insert(libclang_entity, r#enum)), | ||
545 | ClangEntityKind::EnumConstant => panic!("Enum variant encountered not within an enum"), | ||
530 | }; | 546 | }; |
531 | // TODO: check result | 547 | // TODO: check result |
532 | 548 | ||
@@ -611,6 +627,7 @@ impl<'a> TryFrom<clang::Entity<'a>> for Namespace { | |||
611 | member_structs: Default::default(), | 627 | member_structs: Default::default(), |
612 | member_functions: Default::default(), | 628 | member_functions: Default::default(), |
613 | member_typedefs: Default::default(), | 629 | member_typedefs: Default::default(), |
630 | member_enums: Default::default(), | ||
614 | }) | 631 | }) |
615 | } | 632 | } |
616 | } | 633 | } |
@@ -655,6 +672,7 @@ impl<'a> TryFrom<clang::Entity<'a>> for Struct { | |||
655 | let mut member_structs = BTreeMap::new(); | 672 | let mut member_structs = BTreeMap::new(); |
656 | let mut member_functions = BTreeMap::new(); | 673 | let mut member_functions = BTreeMap::new(); |
657 | let mut member_typedefs = BTreeMap::new(); | 674 | let mut member_typedefs = BTreeMap::new(); |
675 | let mut member_enums = BTreeMap::new(); | ||
658 | 676 | ||
659 | for child in entity.get_children() { | 677 | for child in entity.get_children() { |
660 | trace!("Struct has child: {:?}", child); | 678 | trace!("Struct has child: {:?}", child); |
@@ -694,6 +712,12 @@ impl<'a> TryFrom<clang::Entity<'a>> for Struct { | |||
694 | .ok_or_else(|| anyhow!("no usr for: {:?}", child))?; | 712 | .ok_or_else(|| anyhow!("no usr for: {:?}", child))?; |
695 | member_typedefs.insert(child_usr, Described::<Typedef>::try_from(child)?); | 713 | member_typedefs.insert(child_usr, Described::<Typedef>::try_from(child)?); |
696 | } | 714 | } |
715 | Ok(ClangEntityKind::Enum) => { | ||
716 | let child_usr = child | ||
717 | .get_usr() | ||
718 | .ok_or_else(|| anyhow!("no usr for: {:?}", child))?; | ||
719 | member_enums.insert(child_usr, Described::<Enum>::try_from(child)?); | ||
720 | } | ||
697 | Ok(other) => warn!("Unsupported child of struct {:?}: {:?}", other, child), | 721 | Ok(other) => warn!("Unsupported child of struct {:?}: {:?}", other, child), |
698 | Err(err) => info!("Error while parsing entity {:?}: {}", child, err), | 722 | Err(err) => info!("Error while parsing entity {:?}: {}", child, err), |
699 | } | 723 | } |
@@ -715,6 +739,7 @@ impl<'a> TryFrom<clang::Entity<'a>> for Struct { | |||
715 | member_structs, | 739 | member_structs, |
716 | member_variables, | 740 | member_variables, |
717 | member_typedefs, | 741 | member_typedefs, |
742 | member_enums, | ||
718 | }) | 743 | }) |
719 | } | 744 | } |
720 | } | 745 | } |
@@ -768,7 +793,6 @@ impl<'a> TryFrom<clang::Entity<'a>> for Typedef { | |||
768 | } | 793 | } |
769 | debug!("Parsing typedef: {:?}", entity); | 794 | debug!("Parsing typedef: {:?}", entity); |
770 | 795 | ||
771 | // TODO: unwrap (and unwrap in other similar places too) | ||
772 | let referee = entity | 796 | let referee = entity |
773 | .get_typedef_underlying_type() | 797 | .get_typedef_underlying_type() |
774 | .ok_or_else(|| anyhow!("No underlying type"))? | 798 | .ok_or_else(|| anyhow!("No underlying type"))? |
@@ -778,6 +802,64 @@ impl<'a> TryFrom<clang::Entity<'a>> for Typedef { | |||
778 | } | 802 | } |
779 | } | 803 | } |
780 | 804 | ||
805 | impl<'a> TryFrom<clang::Entity<'a>> for Enum { | ||
806 | type Error = Error; | ||
807 | |||
808 | fn try_from(entity: clang::Entity) -> Result<Self, Error> { | ||
809 | match entity.get_kind().try_into() { | ||
810 | Ok(ClangEntityKind::Enum) => {} | ||
811 | _ => panic!("Trying to parse a non-enum into a enum"), | ||
812 | } | ||
813 | debug!("Parsing enum: {:?}", entity); | ||
814 | |||
815 | let underlying_type = entity | ||
816 | .get_enum_underlying_type() | ||
817 | .ok_or_else(|| anyhow!("No enum underlying type"))? | ||
818 | .get_display_name(); | ||
819 | |||
820 | let mut constants = BTreeMap::new(); | ||
821 | for child in entity.get_children() { | ||
822 | trace!("Enum has child: {:?}", child); | ||
823 | match child.get_kind().try_into() { | ||
824 | Ok(ClangEntityKind::EnumConstant) => { | ||
825 | let child_usr = child | ||
826 | .get_usr() | ||
827 | .ok_or_else(|| anyhow!("no usr for: {:?}", child))?; | ||
828 | constants.insert(child_usr, Described::<EnumConstant>::try_from(child)?); | ||
829 | } | ||
830 | Ok(other) => warn!("Unsupported child of enum {:?}: {:?}", other, child), | ||
831 | Err(err) => info!("Error while parsing entity {:?}: {}", child, err), | ||
832 | } | ||
833 | } | ||
834 | |||
835 | Ok(Enum { | ||
836 | underlying_type, | ||
837 | constants, | ||
838 | }) | ||
839 | } | ||
840 | } | ||
841 | |||
842 | impl<'a> TryFrom<clang::Entity<'a>> for EnumConstant { | ||
843 | type Error = Error; | ||
844 | |||
845 | fn try_from(entity: clang::Entity) -> Result<Self, Error> { | ||
846 | match entity.get_kind().try_into() { | ||
847 | Ok(ClangEntityKind::EnumConstant) => {} | ||
848 | _ => panic!("Trying to parse a non-enum constant into a enum constant"), | ||
849 | } | ||
850 | debug!("Parsing enum: {:?}", entity); | ||
851 | |||
852 | let value = entity | ||
853 | .get_enum_constant_value() | ||
854 | .ok_or_else(|| anyhow!("No enum constant value"))?; | ||
855 | dbg!(value); | ||
856 | |||
857 | Ok(EnumConstant { | ||
858 | value: String::from(""), | ||
859 | }) | ||
860 | } | ||
861 | } | ||
862 | |||
781 | fn get_description(entity: clang::Entity) -> Result<Description> { | 863 | fn get_description(entity: clang::Entity) -> Result<Description> { |
782 | let name = entity | 864 | let name = entity |
783 | .get_display_name() | 865 | .get_display_name() |