|
17 | 17 | namespace AtomicTools |
18 | 18 | { |
19 | 19 |
|
20 | | - class AssemblyInspector |
21 | | - { |
| 20 | + class AssemblyInspector |
| 21 | + { |
22 | 22 |
|
23 | | - Dictionary<string, InspectorEnum> InspectorEnums = new Dictionary<string, InspectorEnum> (); |
24 | | - Dictionary<string, InspectorComponent> InspectorComponents = new Dictionary<string, InspectorComponent> (); |
| 23 | + Dictionary<string, InspectorEnum> InspectorEnums = new Dictionary<string, InspectorEnum>(); |
| 24 | + Dictionary<string, InspectorComponent> InspectorComponents = new Dictionary<string, InspectorComponent>(); |
25 | 25 |
|
26 | | - PEReader peFile; |
27 | | - MetadataReader metaReader; |
| 26 | + PEReader peFile; |
| 27 | + MetadataReader metaReader; |
28 | 28 |
|
29 | | - public AssemblyInspector () |
30 | | - { |
| 29 | + public AssemblyInspector() |
| 30 | + { |
31 | 31 |
|
32 | | - } |
| 32 | + } |
33 | 33 |
|
34 | | - public string DumpToJSON () |
35 | | - { |
36 | | - var dict = new Dictionary<string, object> (); |
| 34 | + public string DumpToJSON() |
| 35 | + { |
| 36 | + var dict = new Dictionary<string, object>(); |
37 | 37 |
|
38 | | - var enumList = new List<object> (); |
39 | | - var componentList = new List<object> (); |
| 38 | + var enumList = new List<object>(); |
| 39 | + var componentList = new List<object>(); |
40 | 40 |
|
41 | | - foreach (var entry in InspectorEnums) { |
42 | | - enumList.Add (entry.Value.GetJSONDict ()); |
43 | | - } |
| 41 | + foreach (var entry in InspectorEnums) |
| 42 | + { |
| 43 | + enumList.Add(entry.Value.GetJSONDict()); |
| 44 | + } |
44 | 45 |
|
45 | | - foreach (var entry in InspectorComponents) { |
46 | | - componentList.Add (entry.Value.GetJSONDict ()); |
47 | | - } |
| 46 | + foreach (var entry in InspectorComponents) |
| 47 | + { |
| 48 | + componentList.Add(entry.Value.GetJSONDict()); |
| 49 | + } |
48 | 50 |
|
49 | | - dict ["enums"] = enumList; |
50 | | - dict ["components"] = componentList; |
| 51 | + dict["enums"] = enumList; |
| 52 | + dict["components"] = componentList; |
51 | 53 |
|
52 | | - return MiniJSON.Json.Serialize (dict); |
| 54 | + return MiniJSON.Json.Serialize(dict); |
53 | 55 |
|
54 | | - } |
| 56 | + } |
55 | 57 |
|
56 | | - public void Inspect (String pathToAssembly) |
57 | | - { |
| 58 | + public void Inspect(String pathToAssembly) |
| 59 | + { |
58 | 60 |
|
59 | | - using (var stream = File.OpenRead (pathToAssembly)) |
60 | | - using (peFile = new PEReader (stream)) { |
| 61 | + using (var stream = File.OpenRead(pathToAssembly)) |
| 62 | + using (peFile = new PEReader(stream)) |
| 63 | + { |
61 | 64 |
|
62 | | - metaReader = peFile.GetMetadataReader (); |
| 65 | + metaReader = peFile.GetMetadataReader(); |
63 | 66 |
|
64 | | - ParseEnums (); |
65 | | - ParseComponents (); |
66 | | - } |
| 67 | + ParseEnums(); |
| 68 | + ParseComponents(); |
| 69 | + } |
67 | 70 |
|
68 | | - } |
| 71 | + } |
69 | 72 |
|
70 | | - void ParseComponents () |
71 | | - { |
| 73 | + void ParseComponents() |
| 74 | + { |
72 | 75 |
|
73 | | - foreach (var handle in metaReader.TypeDefinitions) { |
| 76 | + foreach (var handle in metaReader.TypeDefinitions) |
| 77 | + { |
74 | 78 |
|
75 | | - var typeDef = metaReader.GetTypeDefinition (handle); |
| 79 | + var typeDef = metaReader.GetTypeDefinition(handle); |
76 | 80 |
|
77 | | - var baseTypeHandle = typeDef.BaseType; |
| 81 | + var parentName = metaReader.GetString(typeDef.Name); |
78 | 82 |
|
79 | | - if (baseTypeHandle.Kind == HandleKind.TypeReference) { |
| 83 | + var baseTypeHandle = typeDef.BaseType; |
80 | 84 |
|
81 | | - var typeRef = metaReader.GetTypeReference ((TypeReferenceHandle)baseTypeHandle); |
| 85 | + // Work up to base reference (ie defined outside this assembly) |
| 86 | + while (baseTypeHandle.Kind == HandleKind.TypeDefinition) |
| 87 | + { |
| 88 | + var baseTypeDef = metaReader.GetTypeDefinition((TypeDefinitionHandle)baseTypeHandle); |
| 89 | + // No way to predetermine if .BaseType is valid |
| 90 | + try |
| 91 | + { |
| 92 | + baseTypeHandle = baseTypeDef.BaseType; |
| 93 | + } |
| 94 | + catch (Exception) { break; } |
| 95 | + } |
82 | 96 |
|
83 | | - var name = metaReader.GetString (typeRef.Name); |
| 97 | + if (baseTypeHandle.Kind == HandleKind.TypeReference) |
| 98 | + { |
84 | 99 |
|
85 | | - if (name != "CSComponent") |
86 | | - continue; |
| 100 | + var typeRef = metaReader.GetTypeReference((TypeReferenceHandle)baseTypeHandle); |
87 | 101 |
|
88 | | - var inspector = new CSComponentInspector (typeDef, peFile, metaReader); |
| 102 | + var name = metaReader.GetString(typeRef.Name); |
89 | 103 |
|
90 | | - var icomponent = inspector.Inspect (); |
| 104 | + if (name != "CSComponent") |
| 105 | + continue; |
91 | 106 |
|
92 | | - if (icomponent != null) |
93 | | - InspectorComponents [icomponent.Name] = icomponent; |
94 | | - } |
95 | | - } |
96 | | - } |
| 107 | + var inspector = new CSComponentInspector(typeDef, peFile, metaReader); |
97 | 108 |
|
| 109 | + var icomponent = inspector.Inspect(); |
98 | 110 |
|
99 | | - void ParseEnums () |
100 | | - { |
101 | | - foreach (var handle in metaReader.TypeDefinitions) { |
| 111 | + if (icomponent != null) |
| 112 | + InspectorComponents[icomponent.Name] = icomponent; |
| 113 | + } |
| 114 | + } |
| 115 | + } |
102 | 116 |
|
103 | | - var typeDef = metaReader.GetTypeDefinition (handle); |
104 | 117 |
|
105 | | - var baseTypeHandle = typeDef.BaseType; |
| 118 | + void ParseEnums() |
| 119 | + { |
| 120 | + foreach (var handle in metaReader.TypeDefinitions) |
| 121 | + { |
106 | 122 |
|
107 | | - if (baseTypeHandle.Kind == HandleKind.TypeReference) { |
108 | | - var typeRef = metaReader.GetTypeReference ((TypeReferenceHandle)baseTypeHandle); |
| 123 | + var typeDef = metaReader.GetTypeDefinition(handle); |
109 | 124 |
|
110 | | - if (metaReader.GetString (typeRef.Name) == "Enum") { |
111 | | - ParseEnum (typeDef); |
112 | | - } |
113 | | - } |
114 | | - } |
115 | | - } |
| 125 | + var baseTypeHandle = typeDef.BaseType; |
116 | 126 |
|
117 | | - void ParseEnum (TypeDefinition enumTypeDef) |
118 | | - { |
| 127 | + if (baseTypeHandle.Kind == HandleKind.TypeReference) |
| 128 | + { |
| 129 | + var typeRef = metaReader.GetTypeReference((TypeReferenceHandle)baseTypeHandle); |
119 | 130 |
|
120 | | - // TODO: verify that int32 is the enums storage type for constant read below |
| 131 | + if (metaReader.GetString(typeRef.Name) == "Enum") |
| 132 | + { |
| 133 | + ParseEnum(typeDef); |
| 134 | + } |
| 135 | + } |
| 136 | + } |
| 137 | + } |
121 | 138 |
|
122 | | - InspectorEnum ienum = new InspectorEnum (); |
| 139 | + void ParseEnum(TypeDefinition enumTypeDef) |
| 140 | + { |
123 | 141 |
|
124 | | - ienum.Name = metaReader.GetString (enumTypeDef.Name); |
| 142 | + // TODO: verify that int32 is the enums storage type for constant read below |
125 | 143 |
|
126 | | - InspectorEnums [ienum.Name] = ienum; |
| 144 | + InspectorEnum ienum = new InspectorEnum(); |
127 | 145 |
|
128 | | - var fields = enumTypeDef.GetFields (); |
| 146 | + ienum.Name = metaReader.GetString(enumTypeDef.Name); |
129 | 147 |
|
130 | | - foreach (var fieldHandle in fields) { |
| 148 | + InspectorEnums[ienum.Name] = ienum; |
131 | 149 |
|
132 | | - var inspectorField = new InspectorField (); |
| 150 | + var fields = enumTypeDef.GetFields(); |
133 | 151 |
|
134 | | - var fieldDef = metaReader.GetFieldDefinition (fieldHandle); |
| 152 | + foreach (var fieldHandle in fields) |
| 153 | + { |
135 | 154 |
|
136 | | - if ((fieldDef.Attributes & FieldAttributes.HasDefault) != 0) { |
| 155 | + var inspectorField = new InspectorField(); |
137 | 156 |
|
138 | | - var constantHandle = fieldDef.GetDefaultValue (); |
139 | | - var constant = metaReader.GetConstant (constantHandle); |
| 157 | + var fieldDef = metaReader.GetFieldDefinition(fieldHandle); |
140 | 158 |
|
141 | | - BlobReader constantReader = metaReader.GetBlobReader (constant.Value); |
| 159 | + if ((fieldDef.Attributes & FieldAttributes.HasDefault) != 0) |
| 160 | + { |
142 | 161 |
|
143 | | - ienum.Values [metaReader.GetString (fieldDef.Name)] = constantReader.ReadInt32 (); |
| 162 | + var constantHandle = fieldDef.GetDefaultValue(); |
| 163 | + var constant = metaReader.GetConstant(constantHandle); |
144 | 164 |
|
145 | | - } |
146 | | - } |
| 165 | + BlobReader constantReader = metaReader.GetBlobReader(constant.Value); |
147 | 166 |
|
148 | | - return; |
| 167 | + ienum.Values[metaReader.GetString(fieldDef.Name)] = constantReader.ReadInt32(); |
149 | 168 |
|
150 | | - } |
151 | | - } |
| 169 | + } |
| 170 | + } |
152 | 171 |
|
153 | | - internal class InspectorEnum |
154 | | - { |
155 | | - public String Name; |
156 | | - public Dictionary<string, int> Values = new Dictionary<string, int> (); |
| 172 | + return; |
157 | 173 |
|
158 | | - public Dictionary<string, object> GetJSONDict () |
159 | | - { |
160 | | - var dict = new Dictionary<string,object> (); |
161 | | - dict ["name"] = Name; |
162 | | - dict ["values"] = Values; |
163 | | - return dict; |
164 | | - } |
165 | | - } |
| 174 | + } |
| 175 | + } |
166 | 176 |
|
167 | | - internal class InspectorComponent |
168 | | - { |
169 | | - public String Name; |
170 | | - public String Namespace; |
171 | | - public Dictionary<string, InspectorField> Fields = new Dictionary<string, InspectorField> (); |
| 177 | + internal class InspectorEnum |
| 178 | + { |
| 179 | + public String Name; |
| 180 | + public Dictionary<string, int> Values = new Dictionary<string, int>(); |
172 | 181 |
|
173 | | - public Dictionary<string, object> GetJSONDict () |
174 | | - { |
175 | | - var dict = new Dictionary<string,object> (); |
| 182 | + public Dictionary<string, object> GetJSONDict() |
| 183 | + { |
| 184 | + var dict = new Dictionary<string, object>(); |
| 185 | + dict["name"] = Name; |
| 186 | + dict["values"] = Values; |
| 187 | + return dict; |
| 188 | + } |
| 189 | + } |
176 | 190 |
|
177 | | - dict ["name"] = Name; |
178 | | - dict ["namespace"] = Namespace; |
| 191 | + internal class InspectorComponent |
| 192 | + { |
| 193 | + public String Name; |
| 194 | + public String Namespace; |
| 195 | + public Dictionary<string, InspectorField> Fields = new Dictionary<string, InspectorField>(); |
179 | 196 |
|
180 | | - var fieldList = new List<object> (); |
| 197 | + public Dictionary<string, object> GetJSONDict() |
| 198 | + { |
| 199 | + var dict = new Dictionary<string, object>(); |
181 | 200 |
|
182 | | - foreach (var entry in Fields) { |
183 | | - fieldList.Add (entry.Value.GetJSONDict ()); |
184 | | - } |
| 201 | + dict["name"] = Name; |
| 202 | + dict["namespace"] = Namespace; |
185 | 203 |
|
186 | | - dict ["fields"] = fieldList; |
| 204 | + var fieldList = new List<object>(); |
187 | 205 |
|
188 | | - return dict; |
189 | | - } |
190 | | - } |
| 206 | + foreach (var entry in Fields) |
| 207 | + { |
| 208 | + fieldList.Add(entry.Value.GetJSONDict()); |
| 209 | + } |
191 | 210 |
|
192 | | - internal class InspectorField |
193 | | - { |
| 211 | + dict["fields"] = fieldList; |
194 | 212 |
|
195 | | - public Dictionary<string, object> GetJSONDict () |
196 | | - { |
| 213 | + return dict; |
| 214 | + } |
| 215 | + } |
197 | 216 |
|
198 | | - var dict = new Dictionary<string,object> (); |
| 217 | + internal class InspectorField |
| 218 | + { |
199 | 219 |
|
200 | | - dict ["isEnum"] = IsEnum; |
201 | | - dict ["typeName"] = TypeName; |
202 | | - dict ["name"] = Name; |
203 | | - dict ["defaultValue"] = DefaultValue; |
| 220 | + public Dictionary<string, object> GetJSONDict() |
| 221 | + { |
204 | 222 |
|
205 | | - dict ["caPos"] = CustomAttrPositionalArgs; |
206 | | - dict ["caNamed"] = CustomAttrNamedArgs; |
| 223 | + var dict = new Dictionary<string, object>(); |
207 | 224 |
|
208 | | - return dict; |
| 225 | + dict["isEnum"] = IsEnum; |
| 226 | + dict["typeName"] = TypeName; |
| 227 | + dict["name"] = Name; |
| 228 | + dict["defaultValue"] = DefaultValue; |
209 | 229 |
|
210 | | - } |
| 230 | + dict["caPos"] = CustomAttrPositionalArgs; |
| 231 | + dict["caNamed"] = CustomAttrNamedArgs; |
211 | 232 |
|
212 | | - public bool IsEnum = false; |
| 233 | + return dict; |
213 | 234 |
|
214 | | - public string TypeName; |
| 235 | + } |
215 | 236 |
|
216 | | - // the Name of the InspectorField |
217 | | - public string Name; |
218 | | - // The DefaultValue if supplied |
219 | | - public string DefaultValue; |
| 237 | + public bool IsEnum = false; |
220 | 238 |
|
221 | | - // custom attributes, positional and named |
222 | | - public List<string> CustomAttrPositionalArgs = new List<string> (); |
223 | | - public Dictionary<string, string> CustomAttrNamedArgs = new Dictionary<string, string> (); |
224 | | - } |
| 239 | + public string TypeName; |
| 240 | + |
| 241 | + // the Name of the InspectorField |
| 242 | + public string Name; |
| 243 | + // The DefaultValue if supplied |
| 244 | + public string DefaultValue; |
| 245 | + |
| 246 | + // custom attributes, positional and named |
| 247 | + public List<string> CustomAttrPositionalArgs = new List<string>(); |
| 248 | + public Dictionary<string, string> CustomAttrNamedArgs = new Dictionary<string, string>(); |
| 249 | + } |
225 | 250 |
|
226 | 251 | } |
0 commit comments