1use super::*;
2
3impl std::fmt::Debug for TypeDef {
4 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5 write!(f, "TypeDef({})", self.type_name())
6 }
7}
8
9impl TypeDef {
10 pub fn flags(&self) -> TypeAttributes {
11 TypeAttributes(self.usize(0) as u32)
12 }
13
14 pub fn type_name(&self) -> TypeName {
15 TypeName(self.namespace(), self.name())
16 }
17
18 pub fn name(&self) -> &'static str {
19 trim_tick(self.str(1))
20 }
21
22 pub fn namespace(&self) -> &'static str {
23 self.str(2)
24 }
25
26 pub fn extends(&self) -> Option<TypeName> {
27 let extends = self.usize(3);
28
29 if extends == 0 {
30 return None;
31 }
32
33 Some(TypeDefOrRef::decode(self.file(), extends).type_name())
34 }
35
36 pub fn methods(&self) -> RowIterator<MethodDef> {
37 self.list(5)
38 }
39
40 pub fn fields(&self) -> RowIterator<Field> {
41 self.list(4)
42 }
43
44 pub fn generics(&self) -> Vec<Type> {
45 self.file()
46 .equal_range(2, TypeOrMethodDef::TypeDef(*self).encode())
47 .map(|generic: GenericParam| Type::Param(generic.name()))
48 .collect()
49 }
50
51 pub fn interface_impls(&self) -> RowIterator<InterfaceImpl> {
52 self.file().equal_range(0, self.index() + 1)
53 }
54
55 pub fn class_layout(&self) -> Option<ClassLayout> {
56 self.file().equal_range(2, self.index() + 1).next()
57 }
58
59 pub fn underlying_type(&self) -> Type {
60 let field = self.fields().next().unwrap();
61 if let Some(constant) = field.constant() {
62 constant.ty()
63 } else {
64 field.ty(None)
65 }
66 }
67
68 pub fn invalid_values(&self) -> Vec<i64> {
69 let mut values = Vec::new();
70 for attribute in self.attributes() {
71 if attribute.name() == "InvalidHandleValueAttribute" {
72 if let Some((_, Value::I64(value))) = attribute.args().first() {
73 values.push(*value);
74 }
75 }
76 }
77 values
78 }
79
80 pub fn free_function(&self) -> Option<CppFn> {
81 if let Some(attribute) = self.find_attribute("RAIIFreeAttribute") {
82 if let Some((_, Value::Str(name))) = attribute.args().first() {
83 if let Some(Type::CppFn(ty)) =
84 self.reader().with_full_name(self.namespace(), name).next()
85 {
86 return Some(ty);
87 }
88 }
89 }
90
91 None
92 }
93
94 pub fn is_agile(&self) -> bool {
95 for attribute in self.attributes() {
96 match attribute.name() {
97 "AgileAttribute" => return true,
98 "MarshalingBehaviorAttribute" => {
99 if let Some((_, Value::I32(2))) = attribute.args().first() {
100 return true;
101 }
102 }
103 _ => {}
104 }
105 }
106
107 self.is_async()
108 }
109
110 pub fn is_async(&self) -> bool {
111 matches!(
112 TypeName(self.namespace(), self.name()),
113 TypeName::IAsyncAction
114 | TypeName::IAsyncActionWithProgress
115 | TypeName::IAsyncOperation
116 | TypeName::IAsyncOperationWithProgress
117 )
118 }
119}
120