1 // 2 // TypeDefinition.cs 3 // 4 // Author: 5 // Jb Evain (jbevain@gmail.com) 6 // 7 // Copyright (c) 2008 - 2011 Jb Evain 8 // 9 // Permission is hereby granted, free of charge, to any person obtaining 10 // a copy of this software and associated documentation files (the 11 // "Software"), to deal in the Software without restriction, including 12 // without limitation the rights to use, copy, modify, merge, publish, 13 // distribute, sublicense, and/or sell copies of the Software, and to 14 // permit persons to whom the Software is furnished to do so, subject to 15 // the following conditions: 16 // 17 // The above copyright notice and this permission notice shall be 18 // included in all copies or substantial portions of the Software. 19 // 20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 // 28 29 using System; 30 31 using Mono.Cecil.Metadata; 32 using Mono.Collections.Generic; 33 34 namespace Mono.Cecil { 35 36 public sealed class TypeDefinition : TypeReference, IMemberDefinition, ISecurityDeclarationProvider { 37 38 uint attributes; 39 TypeReference base_type; 40 internal Range fields_range; 41 internal Range methods_range; 42 43 short packing_size = Mixin.NotResolvedMarker; 44 int class_size = Mixin.NotResolvedMarker; 45 46 Collection<TypeReference> interfaces; 47 Collection<TypeDefinition> nested_types; 48 Collection<MethodDefinition> methods; 49 Collection<FieldDefinition> fields; 50 Collection<EventDefinition> events; 51 Collection<PropertyDefinition> properties; 52 Collection<CustomAttribute> custom_attributes; 53 Collection<SecurityDeclaration> security_declarations; 54 55 public TypeAttributes Attributes { 56 get { return (TypeAttributes) attributes; } 57 set { attributes = (uint) value; } 58 } 59 60 public TypeReference BaseType { 61 get { return base_type; } 62 set { base_type = value; } 63 } 64 ResolveLayout()65 void ResolveLayout () 66 { 67 if (packing_size != Mixin.NotResolvedMarker || class_size != Mixin.NotResolvedMarker) 68 return; 69 70 if (!HasImage) { 71 packing_size = Mixin.NoDataMarker; 72 class_size = Mixin.NoDataMarker; 73 return; 74 } 75 76 var row = Module.Read (this, (type, reader) => reader.ReadTypeLayout (type)); 77 78 packing_size = row.Col1; 79 class_size = row.Col2; 80 } 81 82 public bool HasLayoutInfo { 83 get { 84 if (packing_size >= 0 || class_size >= 0) 85 return true; 86 87 ResolveLayout (); 88 89 return packing_size >= 0 || class_size >= 0; 90 } 91 } 92 93 public short PackingSize { 94 get { 95 if (packing_size >= 0) 96 return packing_size; 97 98 ResolveLayout (); 99 100 return packing_size >= 0 ? packing_size : (short) -1; 101 } 102 set { packing_size = value; } 103 } 104 105 public int ClassSize { 106 get { 107 if (class_size >= 0) 108 return class_size; 109 110 ResolveLayout (); 111 112 return class_size >= 0 ? class_size : -1; 113 } 114 set { class_size = value; } 115 } 116 117 public bool HasInterfaces { 118 get { 119 if (interfaces != null) 120 return interfaces.Count > 0; 121 122 if (HasImage) 123 return Module.Read (this, (type, reader) => reader.HasInterfaces (type)); 124 125 return false; 126 } 127 } 128 129 public Collection<TypeReference> Interfaces { 130 get { 131 if (interfaces != null) 132 return interfaces; 133 134 if (HasImage) 135 return interfaces = Module.Read (this, (type, reader) => reader.ReadInterfaces (type)); 136 137 return interfaces = new Collection<TypeReference> (); 138 } 139 } 140 141 public bool HasNestedTypes { 142 get { 143 if (nested_types != null) 144 return nested_types.Count > 0; 145 146 if (HasImage) 147 return Module.Read (this, (type, reader) => reader.HasNestedTypes (type)); 148 149 return false; 150 } 151 } 152 153 public Collection<TypeDefinition> NestedTypes { 154 get { 155 if (nested_types != null) 156 return nested_types; 157 158 if (HasImage) 159 return nested_types = Module.Read (this, (type, reader) => reader.ReadNestedTypes (type)); 160 161 return nested_types = new MemberDefinitionCollection<TypeDefinition> (this); 162 } 163 } 164 165 public bool HasMethods { 166 get { 167 if (methods != null) 168 return methods.Count > 0; 169 170 if (HasImage) 171 return methods_range.Length > 0; 172 173 return false; 174 } 175 } 176 177 public Collection<MethodDefinition> Methods { 178 get { 179 if (methods != null) 180 return methods; 181 182 if (HasImage) 183 return methods = Module.Read (this, (type, reader) => reader.ReadMethods (type)); 184 185 return methods = new MemberDefinitionCollection<MethodDefinition> (this); 186 } 187 } 188 189 public bool HasFields { 190 get { 191 if (fields != null) 192 return fields.Count > 0; 193 194 if (HasImage) 195 return fields_range.Length > 0; 196 197 return false; 198 } 199 } 200 201 public Collection<FieldDefinition> Fields { 202 get { 203 if (fields != null) 204 return fields; 205 206 if (HasImage) 207 return fields = Module.Read (this, (type, reader) => reader.ReadFields (type)); 208 209 return fields = new MemberDefinitionCollection<FieldDefinition> (this); 210 } 211 } 212 213 public bool HasEvents { 214 get { 215 if (events != null) 216 return events.Count > 0; 217 218 if (HasImage) 219 return Module.Read (this, (type, reader) => reader.HasEvents (type)); 220 221 return false; 222 } 223 } 224 225 public Collection<EventDefinition> Events { 226 get { 227 if (events != null) 228 return events; 229 230 if (HasImage) 231 return events = Module.Read (this, (type, reader) => reader.ReadEvents (type)); 232 233 return events = new MemberDefinitionCollection<EventDefinition> (this); 234 } 235 } 236 237 public bool HasProperties { 238 get { 239 if (properties != null) 240 return properties.Count > 0; 241 242 if (HasImage) 243 return Module.Read (this, (type, reader) => reader.HasProperties (type)); 244 245 return false; 246 } 247 } 248 249 public Collection<PropertyDefinition> Properties { 250 get { 251 if (properties != null) 252 return properties; 253 254 if (HasImage) 255 return properties = Module.Read (this, (type, reader) => reader.ReadProperties (type)); 256 257 return properties = new MemberDefinitionCollection<PropertyDefinition> (this); 258 } 259 } 260 261 public bool HasSecurityDeclarations { 262 get { 263 if (security_declarations != null) 264 return security_declarations.Count > 0; 265 266 return this.GetHasSecurityDeclarations (Module); 267 } 268 } 269 270 public Collection<SecurityDeclaration> SecurityDeclarations { 271 get { return security_declarations ?? (security_declarations = this.GetSecurityDeclarations (Module)); } 272 } 273 274 public bool HasCustomAttributes { 275 get { 276 if (custom_attributes != null) 277 return custom_attributes.Count > 0; 278 279 return this.GetHasCustomAttributes (Module); 280 } 281 } 282 283 public Collection<CustomAttribute> CustomAttributes { 284 get { return custom_attributes ?? (custom_attributes = this.GetCustomAttributes (Module)); } 285 } 286 287 public override bool HasGenericParameters { 288 get { 289 if (generic_parameters != null) 290 return generic_parameters.Count > 0; 291 292 return this.GetHasGenericParameters (Module); 293 } 294 } 295 296 public override Collection<GenericParameter> GenericParameters { 297 get { return generic_parameters ?? (generic_parameters = this.GetGenericParameters (Module)); } 298 } 299 300 #region TypeAttributes 301 302 public bool IsNotPublic { 303 get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic); } 304 set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic, value); } 305 } 306 307 public bool IsPublic { 308 get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public); } 309 set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public, value); } 310 } 311 312 public bool IsNestedPublic { 313 get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic); } 314 set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic, value); } 315 } 316 317 public bool IsNestedPrivate { 318 get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate); } 319 set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate, value); } 320 } 321 322 public bool IsNestedFamily { 323 get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily); } 324 set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily, value); } 325 } 326 327 public bool IsNestedAssembly { 328 get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly); } 329 set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly, value); } 330 } 331 332 public bool IsNestedFamilyAndAssembly { 333 get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem); } 334 set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem, value); } 335 } 336 337 public bool IsNestedFamilyOrAssembly { 338 get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem); } 339 set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem, value); } 340 } 341 342 public bool IsAutoLayout { 343 get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout); } 344 set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout, value); } 345 } 346 347 public bool IsSequentialLayout { 348 get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout); } 349 set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout, value); } 350 } 351 352 public bool IsExplicitLayout { 353 get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout); } 354 set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout, value); } 355 } 356 357 public bool IsClass { 358 get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class); } 359 set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class, value); } 360 } 361 362 public bool IsInterface { 363 get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface); } 364 set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface, value); } 365 } 366 367 public bool IsAbstract { 368 get { return attributes.GetAttributes ((uint) TypeAttributes.Abstract); } 369 set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Abstract, value); } 370 } 371 372 public bool IsSealed { 373 get { return attributes.GetAttributes ((uint) TypeAttributes.Sealed); } 374 set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Sealed, value); } 375 } 376 377 public bool IsSpecialName { 378 get { return attributes.GetAttributes ((uint) TypeAttributes.SpecialName); } 379 set { attributes = attributes.SetAttributes ((uint) TypeAttributes.SpecialName, value); } 380 } 381 382 public bool IsImport { 383 get { return attributes.GetAttributes ((uint) TypeAttributes.Import); } 384 set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Import, value); } 385 } 386 387 public bool IsSerializable { 388 get { return attributes.GetAttributes ((uint) TypeAttributes.Serializable); } 389 set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Serializable, value); } 390 } 391 392 public bool IsWindowsRuntime { 393 get { return attributes.GetAttributes ((uint) TypeAttributes.WindowsRuntime); } 394 set { attributes = attributes.SetAttributes ((uint) TypeAttributes.WindowsRuntime, value); } 395 } 396 397 public bool IsAnsiClass { 398 get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass); } 399 set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass, value); } 400 } 401 402 public bool IsUnicodeClass { 403 get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass); } 404 set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass, value); } 405 } 406 407 public bool IsAutoClass { 408 get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass); } 409 set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass, value); } 410 } 411 412 public bool IsBeforeFieldInit { 413 get { return attributes.GetAttributes ((uint) TypeAttributes.BeforeFieldInit); } 414 set { attributes = attributes.SetAttributes ((uint) TypeAttributes.BeforeFieldInit, value); } 415 } 416 417 public bool IsRuntimeSpecialName { 418 get { return attributes.GetAttributes ((uint) TypeAttributes.RTSpecialName); } 419 set { attributes = attributes.SetAttributes ((uint) TypeAttributes.RTSpecialName, value); } 420 } 421 422 public bool HasSecurity { 423 get { return attributes.GetAttributes ((uint) TypeAttributes.HasSecurity); } 424 set { attributes = attributes.SetAttributes ((uint) TypeAttributes.HasSecurity, value); } 425 } 426 427 #endregion 428 429 public bool IsEnum { 430 get { return base_type != null && base_type.IsTypeOf ("System", "Enum"); } 431 } 432 433 public override bool IsValueType { 434 get { 435 if (base_type == null) 436 return false; 437 438 return base_type.IsTypeOf ("System", "Enum") || (base_type.IsTypeOf ("System", "ValueType") && !this.IsTypeOf ("System", "Enum")); 439 } 440 } 441 442 public override bool IsPrimitive { 443 get { 444 ElementType primitive_etype; 445 return MetadataSystem.TryGetPrimitiveElementType (this, out primitive_etype); 446 } 447 } 448 449 public override MetadataType MetadataType { 450 get { 451 ElementType primitive_etype; 452 if (MetadataSystem.TryGetPrimitiveElementType (this, out primitive_etype)) 453 return (MetadataType) primitive_etype; 454 455 return base.MetadataType; 456 } 457 } 458 459 public override bool IsDefinition { 460 get { return true; } 461 } 462 463 public new TypeDefinition DeclaringType { 464 get { return (TypeDefinition) base.DeclaringType; } 465 set { base.DeclaringType = value; } 466 } 467 TypeDefinition(string @namespace, string name, TypeAttributes attributes)468 public TypeDefinition (string @namespace, string name, TypeAttributes attributes) 469 : base (@namespace, name) 470 { 471 this.attributes = (uint) attributes; 472 this.token = new MetadataToken (TokenType.TypeDef); 473 } 474 TypeDefinition(string @namespace, string name, TypeAttributes attributes, TypeReference baseType)475 public TypeDefinition (string @namespace, string name, TypeAttributes attributes, TypeReference baseType) : 476 this (@namespace, name, attributes) 477 { 478 this.BaseType = baseType; 479 } 480 Resolve()481 public override TypeDefinition Resolve () 482 { 483 return this; 484 } 485 } 486 487 static partial class Mixin { 488 GetEnumUnderlyingType(this TypeDefinition self)489 public static TypeReference GetEnumUnderlyingType (this TypeDefinition self) 490 { 491 var fields = self.Fields; 492 493 for (int i = 0; i < fields.Count; i++) { 494 var field = fields [i]; 495 if (!field.IsStatic) 496 return field.FieldType; 497 } 498 499 throw new ArgumentException (); 500 } 501 GetNestedType(this TypeDefinition self, string name)502 public static TypeDefinition GetNestedType (this TypeDefinition self, string name) 503 { 504 if (!self.HasNestedTypes) 505 return null; 506 507 var nested_types = self.NestedTypes; 508 509 for (int i = 0; i < nested_types.Count; i++) { 510 var nested_type = nested_types [i]; 511 if (nested_type.Name == name) 512 return nested_type; 513 } 514 515 return null; 516 } 517 } 518 } 519