1 | use super::*; |
2 | |
3 | impl 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 | |
9 | impl 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 | |