1 // 2 // System.Reflection.Emit.TypeBuilder.cs 3 // 4 // Author: 5 // Paolo Molaro (lupus@ximian.com) 6 // Marek Safar (marek.safar@gmail.com) 7 // 8 // (C) 2001 Ximian, Inc. http://www.ximian.com 9 // 10 11 // 12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com) 13 // 14 // Permission is hereby granted, free of charge, to any person obtaining 15 // a copy of this software and associated documentation files (the 16 // "Software"), to deal in the Software without restriction, including 17 // without limitation the rights to use, copy, modify, merge, publish, 18 // distribute, sublicense, and/or sell copies of the Software, and to 19 // permit persons to whom the Software is furnished to do so, subject to 20 // the following conditions: 21 // 22 // The above copyright notice and this permission notice shall be 23 // included in all copies or substantial portions of the Software. 24 // 25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 // 33 34 #if !FULL_AOT_RUNTIME 35 using System; 36 using System.Text; 37 using System.Reflection; 38 using System.Reflection.Emit; 39 using System.Runtime.CompilerServices; 40 using System.Runtime.InteropServices; 41 using System.Globalization; 42 using System.Collections; 43 using System.Collections.Generic; 44 using System.Security; 45 using System.Security.Permissions; 46 using System.Diagnostics.SymbolStore; 47 48 49 namespace System.Reflection.Emit 50 { 51 [ComVisible (true)] 52 [ComDefaultInterface (typeof (_TypeBuilder))] 53 [ClassInterface (ClassInterfaceType.None)] 54 [StructLayout (LayoutKind.Sequential)] 55 public sealed class TypeBuilder : TypeInfo, _TypeBuilder 56 { 57 #pragma warning disable 169 58 #region Sync with reflection.h 59 private string tname; // name in internal form 60 private string nspace; // namespace in internal form 61 private Type parent; 62 private Type nesting_type; 63 internal Type[] interfaces; 64 internal int num_methods; 65 internal MethodBuilder[] methods; 66 internal ConstructorBuilder[] ctors; 67 internal PropertyBuilder[] properties; 68 internal int num_fields; 69 internal FieldBuilder[] fields; 70 internal EventBuilder[] events; 71 private CustomAttributeBuilder[] cattrs; 72 internal TypeBuilder[] subtypes; 73 internal TypeAttributes attrs; 74 private int table_idx; 75 private ModuleBuilder pmodule; 76 private int class_size; 77 private PackingSize packing_size; 78 private IntPtr generic_container; 79 private GenericTypeParameterBuilder[] generic_params; 80 private RefEmitPermissionSet[] permissions; 81 private TypeInfo created; 82 private int state; 83 #endregion 84 #pragma warning restore 169 85 86 TypeName fullname; 87 bool createTypeCalled; 88 private Type underlying_type; 89 90 public const int UnspecifiedTypeSize = 0; 91 GetAttributeFlagsImpl()92 protected override TypeAttributes GetAttributeFlagsImpl () 93 { 94 return attrs; 95 } 96 TypeBuilder(ModuleBuilder mb, TypeAttributes attr, int table_idx)97 internal TypeBuilder (ModuleBuilder mb, TypeAttributes attr, int table_idx) 98 { 99 this.parent = null; 100 this.attrs = attr; 101 this.class_size = UnspecifiedTypeSize; 102 this.table_idx = table_idx; 103 this.tname = table_idx == 1 ? "<Module>" : "type_" + table_idx.ToString (); 104 this.nspace = String.Empty; 105 this.fullname = TypeIdentifiers.WithoutEscape(this.tname); 106 pmodule = mb; 107 } 108 TypeBuilder(ModuleBuilder mb, string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packing_size, int type_size, Type nesting_type)109 internal TypeBuilder (ModuleBuilder mb, string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packing_size, int type_size, Type nesting_type) 110 { 111 int sep_index; 112 this.parent = ResolveUserType (parent); 113 this.attrs = attr; 114 this.class_size = type_size; 115 this.packing_size = packing_size; 116 this.nesting_type = nesting_type; 117 118 check_name ("fullname", name); 119 120 if (parent == null && (attr & TypeAttributes.Interface) != 0 && (attr & TypeAttributes.Abstract) == 0) 121 throw new InvalidOperationException ("Interface must be declared abstract."); 122 123 sep_index = name.LastIndexOf('.'); 124 if (sep_index != -1) { 125 this.tname = name.Substring (sep_index + 1); 126 this.nspace = name.Substring (0, sep_index); 127 } else { 128 this.tname = name; 129 this.nspace = String.Empty; 130 } 131 if (interfaces != null) { 132 this.interfaces = new Type[interfaces.Length]; 133 System.Array.Copy (interfaces, this.interfaces, interfaces.Length); 134 } 135 pmodule = mb; 136 137 if (((attr & TypeAttributes.Interface) == 0) && (parent == null)) 138 this.parent = typeof (object); 139 140 // skip .<Module> ? 141 table_idx = mb.get_next_table_index (this, 0x02, true); 142 fullname = GetFullName (); 143 } 144 145 public override Assembly Assembly { 146 get {return pmodule.Assembly;} 147 } 148 149 public override string AssemblyQualifiedName { 150 get { 151 return fullname.DisplayName + ", " + Assembly.FullName; 152 } 153 } 154 155 public override Type BaseType { 156 get { 157 return parent; 158 } 159 } 160 161 public override Type DeclaringType { 162 get { return nesting_type; } 163 } 164 165 [ComVisible (true)] IsSubclassOf(Type c)166 public override bool IsSubclassOf (Type c) 167 { 168 Type t; 169 if (c == null) 170 return false; 171 if (c == this) 172 return false; 173 t = parent; 174 while (t != null) { 175 if (c == t) 176 return true; 177 t = t.BaseType; 178 } 179 return false; 180 } 181 182 public override Type UnderlyingSystemType { 183 get { 184 if (is_created) 185 return created.UnderlyingSystemType; 186 187 if (IsEnum) { 188 if (underlying_type != null) 189 return underlying_type; 190 throw new InvalidOperationException ( 191 "Enumeration type is not defined."); 192 } 193 194 return this; 195 } 196 } 197 GetFullName()198 TypeName GetFullName () 199 { 200 TypeIdentifier ident = TypeIdentifiers.FromInternal (tname); 201 if (nesting_type != null) 202 return TypeNames.FromDisplay (nesting_type.FullName).NestedName (ident); 203 if ((nspace != null) && (nspace.Length > 0)) 204 return TypeIdentifiers.FromInternal (nspace, ident); 205 return ident; 206 } 207 208 public override string FullName { 209 get { 210 return fullname.DisplayName; 211 } 212 } 213 214 public override Guid GUID { 215 get { 216 check_created (); 217 return created.GUID; 218 } 219 } 220 221 public override Module Module { 222 get {return pmodule;} 223 } 224 225 public override string Name { 226 get {return tname;} 227 } 228 229 public override string Namespace { 230 get {return nspace;} 231 } 232 233 public PackingSize PackingSize { 234 get {return packing_size;} 235 } 236 237 public int Size { 238 get { return class_size; } 239 } 240 241 public override Type ReflectedType { 242 get { return nesting_type; } 243 } 244 AddDeclarativeSecurity(SecurityAction action, PermissionSet pset)245 public void AddDeclarativeSecurity (SecurityAction action, PermissionSet pset) 246 { 247 #if !MOBILE 248 if (pset == null) 249 throw new ArgumentNullException ("pset"); 250 if ((action == SecurityAction.RequestMinimum) || 251 (action == SecurityAction.RequestOptional) || 252 (action == SecurityAction.RequestRefuse)) 253 throw new ArgumentOutOfRangeException ("Request* values are not permitted", "action"); 254 255 check_not_created (); 256 257 if (permissions != null) { 258 /* Check duplicate actions */ 259 foreach (RefEmitPermissionSet set in permissions) 260 if (set.action == action) 261 throw new InvalidOperationException ("Multiple permission sets specified with the same SecurityAction."); 262 263 RefEmitPermissionSet[] new_array = new RefEmitPermissionSet [permissions.Length + 1]; 264 permissions.CopyTo (new_array, 0); 265 permissions = new_array; 266 } 267 else 268 permissions = new RefEmitPermissionSet [1]; 269 270 permissions [permissions.Length - 1] = new RefEmitPermissionSet (action, pset.ToXml ().ToString ()); 271 attrs |= TypeAttributes.HasSecurity; 272 #endif 273 } 274 275 [ComVisible (true)] AddInterfaceImplementation(Type interfaceType)276 public void AddInterfaceImplementation (Type interfaceType) 277 { 278 if (interfaceType == null) 279 throw new ArgumentNullException ("interfaceType"); 280 check_not_created (); 281 282 if (interfaces != null) { 283 // Check for duplicates 284 foreach (Type t in interfaces) 285 if (t == interfaceType) 286 return; 287 288 Type[] ifnew = new Type [interfaces.Length + 1]; 289 interfaces.CopyTo (ifnew, 0); 290 ifnew [interfaces.Length] = interfaceType; 291 interfaces = ifnew; 292 } else { 293 interfaces = new Type [1]; 294 interfaces [0] = interfaceType; 295 } 296 } 297 GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)298 protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr, Binder binder, 299 CallingConventions callConvention, Type[] types, 300 ParameterModifier[] modifiers) 301 { 302 check_created (); 303 304 if (created == typeof (object)) { 305 /* 306 * This happens when building corlib. Calling created.GetConstructor 307 * would return constructors from the real mscorlib, instead of the 308 * newly built one. 309 */ 310 311 if (ctors == null) 312 return null; 313 314 ConstructorBuilder found = null; 315 int count = 0; 316 317 foreach (ConstructorBuilder cb in ctors) { 318 if (callConvention != CallingConventions.Any && cb.CallingConvention != callConvention) 319 continue; 320 found = cb; 321 count++; 322 } 323 324 if (count == 0) 325 return null; 326 if (types == null) { 327 if (count > 1) 328 throw new AmbiguousMatchException (); 329 return found; 330 } 331 MethodBase[] match = new MethodBase [count]; 332 if (count == 1) 333 match [0] = found; 334 else { 335 count = 0; 336 foreach (ConstructorInfo m in ctors) { 337 if (callConvention != CallingConventions.Any && m.CallingConvention != callConvention) 338 continue; 339 match [count++] = m; 340 } 341 } 342 if (binder == null) 343 binder = DefaultBinder; 344 return (ConstructorInfo) binder.SelectMethod (bindingAttr, match, 345 types, modifiers); 346 } 347 348 return created.GetConstructor (bindingAttr, binder, 349 callConvention, types, modifiers); 350 } 351 IsDefined(Type attributeType, bool inherit)352 public override bool IsDefined (Type attributeType, bool inherit) 353 { 354 if (!is_created) 355 throw new NotSupportedException (); 356 /* 357 * MS throws NotSupported here, but we can't because some corlib 358 * classes make calls to IsDefined. 359 */ 360 return MonoCustomAttrs.IsDefined (this, attributeType, inherit); 361 } 362 GetCustomAttributes(bool inherit)363 public override object[] GetCustomAttributes(bool inherit) 364 { 365 check_created (); 366 367 return created.GetCustomAttributes (inherit); 368 } 369 GetCustomAttributes(Type attributeType, bool inherit)370 public override object[] GetCustomAttributes(Type attributeType, bool inherit) 371 { 372 check_created (); 373 374 return created.GetCustomAttributes (attributeType, inherit); 375 } 376 DefineNestedType(string name)377 public TypeBuilder DefineNestedType (string name) 378 { 379 return DefineNestedType (name, TypeAttributes.NestedPrivate, 380 pmodule.assemblyb.corlib_object_type, null); 381 } 382 DefineNestedType(string name, TypeAttributes attr)383 public TypeBuilder DefineNestedType (string name, TypeAttributes attr) 384 { 385 return DefineNestedType (name, attr, pmodule.assemblyb.corlib_object_type, null); 386 } 387 DefineNestedType(string name, TypeAttributes attr, Type parent)388 public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent) 389 { 390 return DefineNestedType (name, attr, parent, null); 391 } 392 DefineNestedType(string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packSize, int typeSize)393 private TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, Type[] interfaces, 394 PackingSize packSize, int typeSize) 395 { 396 // Visibility must be NestedXXX 397 /* This breaks mcs 398 if (((attrs & TypeAttributes.VisibilityMask) == TypeAttributes.Public) || 399 ((attrs & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic)) 400 throw new ArgumentException ("attr", "Bad type flags for nested type."); 401 */ 402 if (interfaces != null) 403 foreach (Type iface in interfaces) 404 if (iface == null) 405 throw new ArgumentNullException ("interfaces"); 406 407 TypeBuilder res = new TypeBuilder (pmodule, name, attr, parent, interfaces, packSize, typeSize, this); 408 res.fullname = res.GetFullName (); 409 pmodule.RegisterTypeName (res, res.fullname); 410 if (subtypes != null) { 411 TypeBuilder[] new_types = new TypeBuilder [subtypes.Length + 1]; 412 System.Array.Copy (subtypes, new_types, subtypes.Length); 413 new_types [subtypes.Length] = res; 414 subtypes = new_types; 415 } else { 416 subtypes = new TypeBuilder [1]; 417 subtypes [0] = res; 418 } 419 return res; 420 } 421 422 [ComVisible (true)] DefineNestedType(string name, TypeAttributes attr, Type parent, Type[] interfaces)423 public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, Type[] interfaces) 424 { 425 return DefineNestedType (name, attr, parent, interfaces, PackingSize.Unspecified, UnspecifiedTypeSize); 426 } 427 DefineNestedType(string name, TypeAttributes attr, Type parent, int typeSize)428 public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, int typeSize) 429 { 430 return DefineNestedType (name, attr, parent, null, PackingSize.Unspecified, typeSize); 431 } 432 DefineNestedType(string name, TypeAttributes attr, Type parent, PackingSize packSize)433 public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, PackingSize packSize) 434 { 435 return DefineNestedType (name, attr, parent, null, packSize, UnspecifiedTypeSize); 436 } 437 DefineNestedType(string name, TypeAttributes attr, Type parent, PackingSize packSize, int typeSize)438 public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, PackingSize packSize, 439 int typeSize) 440 { 441 return DefineNestedType (name, attr, parent, null, packSize, typeSize); 442 } 443 444 [ComVisible (true)] DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes)445 public ConstructorBuilder DefineConstructor (MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes) 446 { 447 return DefineConstructor (attributes, callingConvention, parameterTypes, null, null); 448 } 449 450 [ComVisible (true)] DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)451 public ConstructorBuilder DefineConstructor (MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers) 452 { 453 check_not_created (); 454 ConstructorBuilder cb = new ConstructorBuilder (this, attributes, 455 callingConvention, parameterTypes, requiredCustomModifiers, 456 optionalCustomModifiers); 457 if (ctors != null) { 458 ConstructorBuilder[] new_ctors = new ConstructorBuilder [ctors.Length+1]; 459 System.Array.Copy (ctors, new_ctors, ctors.Length); 460 new_ctors [ctors.Length] = cb; 461 ctors = new_ctors; 462 } else { 463 ctors = new ConstructorBuilder [1]; 464 ctors [0] = cb; 465 } 466 return cb; 467 } 468 469 [ComVisible (true)] DefineDefaultConstructor(MethodAttributes attributes)470 public ConstructorBuilder DefineDefaultConstructor (MethodAttributes attributes) 471 { 472 Type parent_type, old_parent_type; 473 474 if (parent != null) 475 parent_type = parent; 476 else 477 parent_type = pmodule.assemblyb.corlib_object_type; 478 479 old_parent_type = parent_type; 480 parent_type = parent_type.InternalResolve (); 481 /*This avoids corlib to have self references.*/ 482 if (parent_type == typeof (object) || parent_type == typeof (ValueType)) 483 parent_type = old_parent_type; 484 485 ConstructorInfo parent_constructor = 486 parent_type.GetConstructor ( 487 BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, 488 null, Type.EmptyTypes, null); 489 if (parent_constructor == null) { 490 throw new NotSupportedException ("Parent does" 491 + " not have a default constructor." 492 + " The default constructor must be" 493 + " explicitly defined."); 494 } 495 496 ConstructorBuilder cb = DefineConstructor (attributes, 497 CallingConventions.Standard, Type.EmptyTypes); 498 ILGenerator ig = cb.GetILGenerator (); 499 ig.Emit (OpCodes.Ldarg_0); 500 ig.Emit (OpCodes.Call, parent_constructor); 501 ig.Emit (OpCodes.Ret); 502 return cb; 503 } 504 append_method(MethodBuilder mb)505 private void append_method (MethodBuilder mb) 506 { 507 if (methods != null) { 508 if (methods.Length == num_methods) { 509 MethodBuilder[] new_methods = new MethodBuilder [methods.Length * 2]; 510 System.Array.Copy (methods, new_methods, num_methods); 511 methods = new_methods; 512 } 513 } else { 514 methods = new MethodBuilder [1]; 515 } 516 methods [num_methods] = mb; 517 num_methods ++; 518 } 519 DefineMethod(string name, MethodAttributes attributes, Type returnType, Type[] parameterTypes)520 public MethodBuilder DefineMethod (string name, MethodAttributes attributes, Type returnType, Type[] parameterTypes) 521 { 522 return DefineMethod (name, attributes, CallingConventions.Standard, 523 returnType, parameterTypes); 524 } 525 DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)526 public MethodBuilder DefineMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) 527 { 528 return DefineMethod (name, attributes, callingConvention, returnType, 529 null, null, parameterTypes, null, null); 530 } 531 DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)532 public MethodBuilder DefineMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) 533 { 534 check_name ("name", name); 535 check_not_created (); 536 if (IsInterface && ( 537 !((attributes & MethodAttributes.Abstract) != 0) || 538 !((attributes & MethodAttributes.Virtual) != 0)) && 539 !(((attributes & MethodAttributes.Static) != 0))) 540 throw new ArgumentException ("Interface method must be abstract and virtual."); 541 542 if (returnType == null) 543 returnType = pmodule.assemblyb.corlib_void_type; 544 MethodBuilder res = new MethodBuilder (this, name, attributes, 545 callingConvention, returnType, 546 returnTypeRequiredCustomModifiers, 547 returnTypeOptionalCustomModifiers, parameterTypes, 548 parameterTypeRequiredCustomModifiers, 549 parameterTypeOptionalCustomModifiers); 550 append_method (res); 551 return res; 552 } 553 DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet)554 public MethodBuilder DefinePInvokeMethod (string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) 555 { 556 return DefinePInvokeMethod (name, dllName, entryName, attributes, 557 callingConvention, returnType, null, null, parameterTypes, 558 null, null, nativeCallConv, nativeCharSet); 559 } 560 DefinePInvokeMethod( string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers, CallingConvention nativeCallConv, CharSet nativeCharSet)561 public MethodBuilder DefinePInvokeMethod ( 562 string name, 563 string dllName, 564 string entryName, MethodAttributes attributes, 565 CallingConventions callingConvention, 566 Type returnType, 567 Type[] returnTypeRequiredCustomModifiers, 568 Type[] returnTypeOptionalCustomModifiers, 569 Type[] parameterTypes, 570 Type[][] parameterTypeRequiredCustomModifiers, 571 Type[][] parameterTypeOptionalCustomModifiers, 572 CallingConvention nativeCallConv, 573 CharSet nativeCharSet) 574 { 575 check_name ("name", name); 576 check_name ("dllName", dllName); 577 check_name ("entryName", entryName); 578 if ((attributes & MethodAttributes.Abstract) != 0) 579 throw new ArgumentException ("PInvoke methods must be static and native and cannot be abstract."); 580 if (IsInterface) 581 throw new ArgumentException ("PInvoke methods cannot exist on interfaces."); 582 check_not_created (); 583 584 MethodBuilder res 585 = new MethodBuilder ( 586 this, 587 name, 588 attributes, 589 callingConvention, 590 returnType, 591 returnTypeRequiredCustomModifiers, 592 returnTypeOptionalCustomModifiers, 593 parameterTypes, 594 parameterTypeRequiredCustomModifiers, 595 parameterTypeOptionalCustomModifiers, 596 dllName, 597 entryName, 598 nativeCallConv, 599 nativeCharSet); 600 append_method (res); 601 return res; 602 } 603 DefinePInvokeMethod(string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet)604 public MethodBuilder DefinePInvokeMethod (string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) { 605 return DefinePInvokeMethod (name, dllName, name, attributes, callingConvention, returnType, parameterTypes, 606 nativeCallConv, nativeCharSet); 607 } 608 DefineMethod(string name, MethodAttributes attributes)609 public MethodBuilder DefineMethod (string name, MethodAttributes attributes) 610 { 611 return DefineMethod (name, attributes, CallingConventions.Standard); 612 } 613 DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention)614 public MethodBuilder DefineMethod (string name, MethodAttributes attributes, CallingConventions callingConvention) 615 { 616 return DefineMethod (name, attributes, callingConvention, null, null); 617 } 618 DefineMethodOverride(MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration)619 public void DefineMethodOverride (MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration) 620 { 621 if (methodInfoBody == null) 622 throw new ArgumentNullException ("methodInfoBody"); 623 if (methodInfoDeclaration == null) 624 throw new ArgumentNullException ("methodInfoDeclaration"); 625 check_not_created (); 626 if (methodInfoBody.DeclaringType != this) 627 throw new ArgumentException ("method body must belong to this type"); 628 629 if (methodInfoBody is MethodBuilder) { 630 MethodBuilder mb = (MethodBuilder)methodInfoBody; 631 mb.set_override (methodInfoDeclaration); 632 } 633 } 634 DefineField(string fieldName, Type type, FieldAttributes attributes)635 public FieldBuilder DefineField (string fieldName, Type type, FieldAttributes attributes) 636 { 637 return DefineField (fieldName, type, null, null, attributes); 638 } 639 DefineField(string fieldName, Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, FieldAttributes attributes)640 public FieldBuilder DefineField (string fieldName, Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, FieldAttributes attributes) 641 { 642 check_name ("fieldName", fieldName); 643 if (type == typeof (void)) 644 throw new ArgumentException ("Bad field type in defining field."); 645 check_not_created (); 646 647 FieldBuilder res = new FieldBuilder (this, fieldName, type, attributes, requiredCustomModifiers, optionalCustomModifiers); 648 if (fields != null) { 649 if (fields.Length == num_fields) { 650 FieldBuilder[] new_fields = new FieldBuilder [fields.Length * 2]; 651 System.Array.Copy (fields, new_fields, num_fields); 652 fields = new_fields; 653 } 654 fields [num_fields] = res; 655 num_fields ++; 656 } else { 657 fields = new FieldBuilder [1]; 658 fields [0] = res; 659 num_fields ++; 660 } 661 662 if (IsEnum) { 663 if (underlying_type == null && (attributes & FieldAttributes.Static) == 0) 664 underlying_type = type; 665 } 666 667 return res; 668 } 669 DefineProperty(string name, PropertyAttributes attributes, Type returnType, Type[] parameterTypes)670 public PropertyBuilder DefineProperty (string name, PropertyAttributes attributes, Type returnType, Type[] parameterTypes) 671 { 672 return DefineProperty (name, attributes, 0, returnType, null, null, parameterTypes, null, null); 673 } 674 DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)675 public PropertyBuilder DefineProperty (string name, PropertyAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) 676 { 677 return DefineProperty (name, attributes, callingConvention, returnType , null, null, parameterTypes, null, null); 678 } 679 DefineProperty(string name, PropertyAttributes attributes, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)680 public PropertyBuilder DefineProperty (string name, PropertyAttributes attributes, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) 681 { 682 return DefineProperty (name, attributes, 0, returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers); 683 } 684 DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)685 public PropertyBuilder DefineProperty (string name, PropertyAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) 686 { 687 check_name ("name", name); 688 if (parameterTypes != null) 689 foreach (Type param in parameterTypes) 690 if (param == null) 691 throw new ArgumentNullException ("parameterTypes"); 692 check_not_created (); 693 694 PropertyBuilder res = new PropertyBuilder (this, name, attributes, callingConvention, returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers); 695 696 if (properties != null) { 697 Array.Resize (ref properties, properties.Length + 1); 698 properties [properties.Length - 1] = res; 699 } else { 700 properties = new PropertyBuilder [1] { res }; 701 } 702 return res; 703 } 704 705 [ComVisible (true)] DefineTypeInitializer()706 public ConstructorBuilder DefineTypeInitializer() 707 { 708 return DefineConstructor (MethodAttributes.Public | 709 MethodAttributes.Static | MethodAttributes.SpecialName | 710 MethodAttributes.RTSpecialName, CallingConventions.Standard, 711 null); 712 } 713 714 [MethodImplAttribute(MethodImplOptions.InternalCall)] create_runtime_class()715 private extern TypeInfo create_runtime_class (); 716 is_nested_in(Type t)717 private bool is_nested_in (Type t) 718 { 719 while (t != null) { 720 if (t == this) 721 return true; 722 else 723 t = t.DeclaringType; 724 } 725 return false; 726 } 727 728 // Return whenever this type has a ctor defined using DefineMethod () has_ctor_method()729 private bool has_ctor_method () { 730 MethodAttributes ctor_attrs = MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; 731 732 for (int i = 0; i < num_methods; ++i) { 733 MethodBuilder mb = (MethodBuilder)(methods[i]); 734 735 if (mb.Name == ConstructorInfo.ConstructorName && (mb.Attributes & ctor_attrs) == ctor_attrs) 736 return true; 737 } 738 739 return false; 740 } 741 CreateType()742 public Type CreateType () 743 { 744 return CreateTypeInfo (); 745 } 746 747 public CreateTypeInfo()748 TypeInfo CreateTypeInfo () 749 { 750 /* handle nesting_type */ 751 if (createTypeCalled) 752 return created; 753 754 if (!IsInterface && (parent == null) && (this != pmodule.assemblyb.corlib_object_type) && (FullName != "<Module>")) { 755 SetParent (pmodule.assemblyb.corlib_object_type); 756 } 757 758 // Fire TypeResolve events for fields whose type is an unfinished 759 // value type. 760 if (fields != null) { 761 foreach (FieldBuilder fb in fields) { 762 if (fb == null) 763 continue; 764 Type ft = fb.FieldType; 765 if (!fb.IsStatic && (ft is TypeBuilder) && ft.IsValueType && (ft != this) && is_nested_in (ft)) { 766 TypeBuilder tb = (TypeBuilder)ft; 767 if (!tb.is_created) { 768 AppDomain.CurrentDomain.DoTypeResolve (tb); 769 if (!tb.is_created) { 770 // FIXME: We should throw an exception here, 771 // but mcs expects that the type is created 772 // even if the exception is thrown 773 //throw new TypeLoadException ("Could not load type " + tb); 774 } 775 } 776 } 777 } 778 } 779 780 // 781 // On classes, define a default constructor if not provided 782 // 783 if (!(IsInterface || IsValueType) && (ctors == null) && (tname != "<Module>") && 784 (GetAttributeFlagsImpl () & TypeAttributes.Abstract | TypeAttributes.Sealed) != (TypeAttributes.Abstract | TypeAttributes.Sealed) && !has_ctor_method ()) 785 DefineDefaultConstructor (MethodAttributes.Public); 786 787 createTypeCalled = true; 788 789 if ((parent != null) && parent.IsSealed) 790 throw new TypeLoadException ("Could not load type '" + FullName + "' from assembly '" + Assembly + "' because the parent type is sealed."); 791 792 if (parent == pmodule.assemblyb.corlib_enum_type && methods != null) 793 throw new TypeLoadException ("Could not load type '" + FullName + "' from assembly '" + Assembly + "' because it is an enum with methods."); 794 if (interfaces != null) { 795 foreach (var iface in interfaces) { 796 if (iface.IsNestedPrivate && iface.Assembly != Assembly) 797 throw new TypeLoadException ("Could not load type '" + FullName + "' from assembly '" + Assembly + "' because it is implements the inaccessible interface '" + iface.FullName + "'."); 798 } 799 } 800 801 if (methods != null) { 802 bool is_concrete = !IsAbstract; 803 for (int i = 0; i < num_methods; ++i) { 804 MethodBuilder mb = (MethodBuilder)(methods[i]); 805 if (is_concrete && mb.IsAbstract) 806 throw new InvalidOperationException ("Type is concrete but has abstract method " + mb); 807 mb.check_override (); 808 mb.fixup (); 809 } 810 } 811 812 if (ctors != null){ 813 foreach (ConstructorBuilder ctor in ctors) 814 ctor.fixup (); 815 } 816 817 ResolveUserTypes (); 818 819 created = create_runtime_class (); 820 if (created != null) 821 return created; 822 return this; 823 } 824 ResolveUserTypes()825 void ResolveUserTypes () { 826 parent = ResolveUserType (parent); 827 ResolveUserTypes (interfaces); 828 if (fields != null) { 829 foreach (var fb in fields) { 830 if (fb != null) 831 fb.ResolveUserTypes (); 832 } 833 } 834 if (methods != null) { 835 foreach (var mb in methods) { 836 if (mb != null) 837 mb.ResolveUserTypes (); 838 } 839 } 840 if (ctors != null) { 841 foreach (var cb in ctors) { 842 if (cb != null) 843 cb.ResolveUserTypes (); 844 } 845 } 846 } 847 ResolveUserTypes(Type[] types)848 static internal void ResolveUserTypes (Type[] types) { 849 if (types != null) 850 for (int i = 0; i < types.Length; ++i) 851 types [i] = ResolveUserType (types [i]); 852 } 853 ResolveUserType(Type t)854 static internal Type ResolveUserType (Type t) { 855 if (t != null && ((t.GetType ().Assembly != typeof (int).Assembly) || (t is TypeDelegator))) { 856 t = t.UnderlyingSystemType; 857 if (t != null && ((t.GetType ().Assembly != typeof (int).Assembly) || (t is TypeDelegator))) 858 throw new NotSupportedException ("User defined subclasses of System.Type are not yet supported."); 859 return t; 860 } else { 861 return t; 862 } 863 } 864 FixupTokens(Dictionary<int, int> token_map, Dictionary<int, MemberInfo> member_map)865 internal void FixupTokens (Dictionary<int, int> token_map, Dictionary<int, MemberInfo> member_map) { 866 if (methods != null) { 867 for (int i = 0; i < num_methods; ++i) 868 methods[i].FixupTokens (token_map, member_map); 869 } 870 if (ctors != null) { 871 foreach (var cb in ctors) 872 cb.FixupTokens (token_map, member_map); 873 } 874 if (subtypes != null) { 875 foreach (var tb in subtypes) 876 tb.FixupTokens (token_map, member_map); 877 } 878 } 879 GenerateDebugInfo(ISymbolWriter symbolWriter)880 internal void GenerateDebugInfo (ISymbolWriter symbolWriter) 881 { 882 symbolWriter.OpenNamespace (this.Namespace); 883 884 if (methods != null) { 885 for (int i = 0; i < num_methods; ++i) { 886 MethodBuilder metb = (MethodBuilder) methods[i]; 887 metb.GenerateDebugInfo (symbolWriter); 888 } 889 } 890 891 if (ctors != null) { 892 foreach (ConstructorBuilder ctor in ctors) 893 ctor.GenerateDebugInfo (symbolWriter); 894 } 895 896 symbolWriter.CloseNamespace (); 897 898 if (subtypes != null) { 899 for (int i = 0; i < subtypes.Length; ++i) 900 subtypes [i].GenerateDebugInfo (symbolWriter); 901 } 902 } 903 904 [ComVisible (true)] GetConstructors(BindingFlags bindingAttr)905 public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr) 906 { 907 if (is_created) 908 return created.GetConstructors (bindingAttr); 909 910 throw new NotSupportedException (); 911 } 912 GetConstructorsInternal(BindingFlags bindingAttr)913 internal ConstructorInfo[] GetConstructorsInternal (BindingFlags bindingAttr) 914 { 915 if (ctors == null) 916 return new ConstructorInfo [0]; 917 ArrayList l = new ArrayList (); 918 bool match; 919 MethodAttributes mattrs; 920 921 foreach (ConstructorBuilder c in ctors) { 922 match = false; 923 mattrs = c.Attributes; 924 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) { 925 if ((bindingAttr & BindingFlags.Public) != 0) 926 match = true; 927 } else { 928 if ((bindingAttr & BindingFlags.NonPublic) != 0) 929 match = true; 930 } 931 if (!match) 932 continue; 933 match = false; 934 if ((mattrs & MethodAttributes.Static) != 0) { 935 if ((bindingAttr & BindingFlags.Static) != 0) 936 match = true; 937 } else { 938 if ((bindingAttr & BindingFlags.Instance) != 0) 939 match = true; 940 } 941 if (!match) 942 continue; 943 l.Add (c); 944 } 945 ConstructorInfo[] result = new ConstructorInfo [l.Count]; 946 l.CopyTo (result); 947 return result; 948 } 949 GetElementType()950 public override Type GetElementType () 951 { 952 throw new NotSupportedException (); 953 } 954 GetEvent(string name, BindingFlags bindingAttr)955 public override EventInfo GetEvent (string name, BindingFlags bindingAttr) 956 { 957 check_created (); 958 return created.GetEvent (name, bindingAttr); 959 } 960 961 /* Needed to keep signature compatibility with MS.NET */ GetEvents()962 public override EventInfo[] GetEvents () 963 { 964 const BindingFlags DefaultBindingFlags = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance; 965 return GetEvents (DefaultBindingFlags); 966 } 967 GetEvents(BindingFlags bindingAttr)968 public override EventInfo[] GetEvents (BindingFlags bindingAttr) 969 { 970 if (is_created) 971 return created.GetEvents (bindingAttr); 972 throw new NotSupportedException (); 973 } 974 GetField(string name, BindingFlags bindingAttr)975 public override FieldInfo GetField (string name, BindingFlags bindingAttr) 976 { 977 if (created != null) 978 return created.GetField (name, bindingAttr); 979 980 if (fields == null) 981 return null; 982 983 bool match; 984 FieldAttributes mattrs; 985 986 foreach (FieldInfo c in fields) { 987 if (c == null) 988 continue; 989 if (c.Name != name) 990 continue; 991 match = false; 992 mattrs = c.Attributes; 993 if ((mattrs & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) { 994 if ((bindingAttr & BindingFlags.Public) != 0) 995 match = true; 996 } else { 997 if ((bindingAttr & BindingFlags.NonPublic) != 0) 998 match = true; 999 } 1000 if (!match) 1001 continue; 1002 match = false; 1003 if ((mattrs & FieldAttributes.Static) != 0) { 1004 if ((bindingAttr & BindingFlags.Static) != 0) 1005 match = true; 1006 } else { 1007 if ((bindingAttr & BindingFlags.Instance) != 0) 1008 match = true; 1009 } 1010 if (!match) 1011 continue; 1012 return c; 1013 } 1014 return null; 1015 } 1016 GetFields(BindingFlags bindingAttr)1017 public override FieldInfo[] GetFields (BindingFlags bindingAttr) 1018 { 1019 if (created != null) 1020 return created.GetFields (bindingAttr); 1021 1022 if (fields == null) 1023 return new FieldInfo [0]; 1024 ArrayList l = new ArrayList (); 1025 bool match; 1026 FieldAttributes mattrs; 1027 1028 foreach (FieldInfo c in fields) { 1029 if (c == null) 1030 continue; 1031 match = false; 1032 mattrs = c.Attributes; 1033 if ((mattrs & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) { 1034 if ((bindingAttr & BindingFlags.Public) != 0) 1035 match = true; 1036 } else { 1037 if ((bindingAttr & BindingFlags.NonPublic) != 0) 1038 match = true; 1039 } 1040 if (!match) 1041 continue; 1042 match = false; 1043 if ((mattrs & FieldAttributes.Static) != 0) { 1044 if ((bindingAttr & BindingFlags.Static) != 0) 1045 match = true; 1046 } else { 1047 if ((bindingAttr & BindingFlags.Instance) != 0) 1048 match = true; 1049 } 1050 if (!match) 1051 continue; 1052 l.Add (c); 1053 } 1054 FieldInfo[] result = new FieldInfo [l.Count]; 1055 l.CopyTo (result); 1056 return result; 1057 } 1058 GetInterface(string name, bool ignoreCase)1059 public override Type GetInterface (string name, bool ignoreCase) 1060 { 1061 check_created (); 1062 return created.GetInterface (name, ignoreCase); 1063 } 1064 GetInterfaces()1065 public override Type[] GetInterfaces () 1066 { 1067 if (is_created) 1068 return created.GetInterfaces (); 1069 1070 if (interfaces != null) { 1071 Type[] ret = new Type [interfaces.Length]; 1072 interfaces.CopyTo (ret, 0); 1073 return ret; 1074 } else { 1075 return Type.EmptyTypes; 1076 } 1077 } 1078 GetMember(string name, MemberTypes type, BindingFlags bindingAttr)1079 public override MemberInfo[] GetMember (string name, MemberTypes type, 1080 BindingFlags bindingAttr) 1081 { 1082 check_created (); 1083 return created.GetMember (name, type, bindingAttr); 1084 } 1085 GetMembers(BindingFlags bindingAttr)1086 public override MemberInfo[] GetMembers (BindingFlags bindingAttr) 1087 { 1088 check_created (); 1089 return created.GetMembers (bindingAttr); 1090 } 1091 GetMethodsByName(string name, BindingFlags bindingAttr, bool ignoreCase, Type reflected_type)1092 private MethodInfo[] GetMethodsByName (string name, BindingFlags bindingAttr, bool ignoreCase, Type reflected_type) 1093 { 1094 MethodInfo[] candidates; 1095 bool match; 1096 MethodAttributes mattrs; 1097 1098 if (((bindingAttr & BindingFlags.DeclaredOnly) == 0) && (parent != null)) { 1099 MethodInfo [] parent_methods = parent.GetMethods (bindingAttr); 1100 ArrayList parent_candidates = new ArrayList (parent_methods.Length); 1101 1102 bool flatten = (bindingAttr & BindingFlags.FlattenHierarchy) != 0; 1103 1104 for (int i = 0; i < parent_methods.Length; i++) { 1105 MethodInfo m = parent_methods [i]; 1106 1107 mattrs = m.Attributes; 1108 1109 if (m.IsStatic && !flatten) 1110 continue; 1111 1112 switch (mattrs & MethodAttributes.MemberAccessMask) { 1113 case MethodAttributes.Public: 1114 match = (bindingAttr & BindingFlags.Public) != 0; 1115 break; 1116 case MethodAttributes.Assembly: 1117 match = (bindingAttr & BindingFlags.NonPublic) != 0; 1118 break; 1119 case MethodAttributes.Private: 1120 match = false; 1121 break; 1122 default: 1123 match = (bindingAttr & BindingFlags.NonPublic) != 0; 1124 break; 1125 } 1126 1127 if (match) 1128 parent_candidates.Add (m); 1129 } 1130 1131 if (methods == null) { 1132 candidates = new MethodInfo [parent_candidates.Count]; 1133 parent_candidates.CopyTo (candidates); 1134 } else { 1135 candidates = new MethodInfo [methods.Length + parent_candidates.Count]; 1136 parent_candidates.CopyTo (candidates, 0); 1137 methods.CopyTo (candidates, parent_candidates.Count); 1138 } 1139 } 1140 else 1141 candidates = methods; 1142 1143 if (candidates == null) 1144 return new MethodInfo [0]; 1145 1146 ArrayList l = new ArrayList (); 1147 1148 foreach (MethodInfo c in candidates) { 1149 if (c == null) 1150 continue; 1151 if (name != null) { 1152 if (String.Compare (c.Name, name, ignoreCase) != 0) 1153 continue; 1154 } 1155 match = false; 1156 mattrs = c.Attributes; 1157 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) { 1158 if ((bindingAttr & BindingFlags.Public) != 0) 1159 match = true; 1160 } else { 1161 if ((bindingAttr & BindingFlags.NonPublic) != 0) 1162 match = true; 1163 } 1164 if (!match) 1165 continue; 1166 match = false; 1167 if ((mattrs & MethodAttributes.Static) != 0) { 1168 if ((bindingAttr & BindingFlags.Static) != 0) 1169 match = true; 1170 } else { 1171 if ((bindingAttr & BindingFlags.Instance) != 0) 1172 match = true; 1173 } 1174 if (!match) 1175 continue; 1176 l.Add (c); 1177 } 1178 1179 MethodInfo[] result = new MethodInfo [l.Count]; 1180 l.CopyTo (result); 1181 return result; 1182 } 1183 GetMethods(BindingFlags bindingAttr)1184 public override MethodInfo[] GetMethods (BindingFlags bindingAttr) 1185 { 1186 return GetMethodsByName (null, bindingAttr, false, this); 1187 } 1188 GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)1189 protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, 1190 Binder binder, 1191 CallingConventions callConvention, 1192 Type[] types, ParameterModifier[] modifiers) 1193 { 1194 check_created (); 1195 1196 if (types == null) 1197 return created.GetMethod (name, bindingAttr); 1198 1199 return created.GetMethod (name, bindingAttr, binder, callConvention, types, modifiers); 1200 } 1201 GetNestedType(string name, BindingFlags bindingAttr)1202 public override Type GetNestedType (string name, BindingFlags bindingAttr) 1203 { 1204 check_created (); 1205 1206 if (subtypes == null) 1207 return null; 1208 1209 foreach (TypeBuilder t in subtypes) { 1210 if (!t.is_created) 1211 continue; 1212 if ((t.attrs & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic) { 1213 if ((bindingAttr & BindingFlags.Public) == 0) 1214 continue; 1215 } else { 1216 if ((bindingAttr & BindingFlags.NonPublic) == 0) 1217 continue; 1218 } 1219 if (t.Name == name) 1220 return t.created; 1221 } 1222 1223 return null; 1224 } 1225 GetNestedTypes(BindingFlags bindingAttr)1226 public override Type[] GetNestedTypes (BindingFlags bindingAttr) 1227 { 1228 if (!is_created) 1229 throw new NotSupportedException (); 1230 1231 bool match; 1232 ArrayList result = new ArrayList (); 1233 1234 if (subtypes == null) 1235 return Type.EmptyTypes; 1236 foreach (TypeBuilder t in subtypes) { 1237 match = false; 1238 if ((t.attrs & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic) { 1239 if ((bindingAttr & BindingFlags.Public) != 0) 1240 match = true; 1241 } else { 1242 if ((bindingAttr & BindingFlags.NonPublic) != 0) 1243 match = true; 1244 } 1245 if (!match) 1246 continue; 1247 result.Add (t); 1248 } 1249 Type[] r = new Type [result.Count]; 1250 result.CopyTo (r); 1251 return r; 1252 } 1253 GetProperties(BindingFlags bindingAttr)1254 public override PropertyInfo[] GetProperties (BindingFlags bindingAttr) 1255 { 1256 if (is_created) 1257 return created.GetProperties (bindingAttr); 1258 1259 if (properties == null) 1260 return new PropertyInfo [0]; 1261 ArrayList l = new ArrayList (); 1262 bool match; 1263 MethodAttributes mattrs; 1264 MethodInfo accessor; 1265 1266 foreach (PropertyInfo c in properties) { 1267 match = false; 1268 accessor = c.GetGetMethod (true); 1269 if (accessor == null) 1270 accessor = c.GetSetMethod (true); 1271 if (accessor == null) 1272 continue; 1273 mattrs = accessor.Attributes; 1274 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) { 1275 if ((bindingAttr & BindingFlags.Public) != 0) 1276 match = true; 1277 } else { 1278 if ((bindingAttr & BindingFlags.NonPublic) != 0) 1279 match = true; 1280 } 1281 if (!match) 1282 continue; 1283 match = false; 1284 if ((mattrs & MethodAttributes.Static) != 0) { 1285 if ((bindingAttr & BindingFlags.Static) != 0) 1286 match = true; 1287 } else { 1288 if ((bindingAttr & BindingFlags.Instance) != 0) 1289 match = true; 1290 } 1291 if (!match) 1292 continue; 1293 l.Add (c); 1294 } 1295 PropertyInfo[] result = new PropertyInfo [l.Count]; 1296 l.CopyTo (result); 1297 return result; 1298 } 1299 GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)1300 protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) 1301 { 1302 throw not_supported (); 1303 } 1304 HasElementTypeImpl()1305 protected override bool HasElementTypeImpl () 1306 { 1307 // a TypeBuilder can never represent an array, pointer 1308 if (!is_created) 1309 return false; 1310 1311 return created.HasElementType; 1312 } 1313 InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)1314 public override object InvokeMember (string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) 1315 { 1316 check_created (); 1317 return created.InvokeMember (name, invokeAttr, binder, target, args, modifiers, culture, namedParameters); 1318 } 1319 IsArrayImpl()1320 protected override bool IsArrayImpl () 1321 { 1322 return false; /*A TypeBuilder never represents a non typedef type.*/ 1323 } 1324 IsByRefImpl()1325 protected override bool IsByRefImpl () 1326 { 1327 return false; /*A TypeBuilder never represents a non typedef type.*/ 1328 } 1329 IsCOMObjectImpl()1330 protected override bool IsCOMObjectImpl () 1331 { 1332 return ((GetAttributeFlagsImpl () & TypeAttributes.Import) != 0); 1333 } 1334 IsPointerImpl()1335 protected override bool IsPointerImpl () 1336 { 1337 return false; /*A TypeBuilder never represents a non typedef type.*/ 1338 } 1339 IsPrimitiveImpl()1340 protected override bool IsPrimitiveImpl () 1341 { 1342 // FIXME 1343 return false; 1344 } 1345 1346 // FIXME: I doubt just removing this still works. IsValueTypeImpl()1347 protected override bool IsValueTypeImpl () 1348 { 1349 if (this == pmodule.assemblyb.corlib_value_type || this == pmodule.assemblyb.corlib_enum_type) 1350 return false; 1351 Type parent_type = parent; 1352 while (parent_type != null) { 1353 if (parent_type == pmodule.assemblyb.corlib_value_type) 1354 return true; 1355 parent_type = parent_type.BaseType; 1356 } 1357 return false; 1358 } 1359 MakeArrayType()1360 public override Type MakeArrayType () 1361 { 1362 return new ArrayType (this, 0); 1363 } 1364 MakeArrayType(int rank)1365 public override Type MakeArrayType (int rank) 1366 { 1367 if (rank < 1) 1368 throw new IndexOutOfRangeException (); 1369 return new ArrayType (this, rank); 1370 } 1371 MakeByRefType()1372 public override Type MakeByRefType () 1373 { 1374 return new ByRefType (this); 1375 } 1376 MakeGenericType(params Type [] typeArguments)1377 public override Type MakeGenericType (params Type [] typeArguments) 1378 { 1379 //return base.MakeGenericType (typeArguments); 1380 1381 if (!IsGenericTypeDefinition) 1382 throw new InvalidOperationException ("not a generic type definition"); 1383 if (typeArguments == null) 1384 throw new ArgumentNullException ("typeArguments"); 1385 1386 if (generic_params.Length != typeArguments.Length) 1387 throw new ArgumentException (String.Format ("The type or method has {0} generic parameter(s) but {1} generic argument(s) where provided. A generic argument must be provided for each generic parameter.", generic_params.Length, typeArguments.Length), "typeArguments"); 1388 1389 foreach (Type t in typeArguments) { 1390 if (t == null) 1391 throw new ArgumentNullException ("typeArguments"); 1392 } 1393 1394 Type[] copy = new Type [typeArguments.Length]; 1395 typeArguments.CopyTo (copy, 0); 1396 return pmodule.assemblyb.MakeGenericType (this, copy); 1397 } 1398 MakePointerType()1399 public override Type MakePointerType () 1400 { 1401 return new PointerType (this); 1402 } 1403 1404 public override RuntimeTypeHandle TypeHandle { 1405 get { 1406 check_created (); 1407 return created.TypeHandle; 1408 } 1409 } 1410 SetCustomAttribute(CustomAttributeBuilder customBuilder)1411 public void SetCustomAttribute (CustomAttributeBuilder customBuilder) 1412 { 1413 if (customBuilder == null) 1414 throw new ArgumentNullException ("customBuilder"); 1415 1416 string attrname = customBuilder.Ctor.ReflectedType.FullName; 1417 if (attrname == "System.Runtime.InteropServices.StructLayoutAttribute") { 1418 byte[] data = customBuilder.Data; 1419 int layout_kind; /* the (stupid) ctor takes a short or an int ... */ 1420 layout_kind = (int)data [2]; 1421 layout_kind |= ((int)data [3]) << 8; 1422 attrs &= ~TypeAttributes.LayoutMask; 1423 switch ((LayoutKind)layout_kind) { 1424 case LayoutKind.Auto: 1425 attrs |= TypeAttributes.AutoLayout; 1426 break; 1427 case LayoutKind.Explicit: 1428 attrs |= TypeAttributes.ExplicitLayout; 1429 break; 1430 case LayoutKind.Sequential: 1431 attrs |= TypeAttributes.SequentialLayout; 1432 break; 1433 default: 1434 // we should ignore it since it can be any value anyway... 1435 throw new Exception ("Error in customattr"); 1436 } 1437 1438 var ctor_type = customBuilder.Ctor is ConstructorBuilder ? ((ConstructorBuilder)customBuilder.Ctor).parameters[0] : customBuilder.Ctor.GetParametersInternal()[0].ParameterType; 1439 int pos = 6; 1440 if (ctor_type.FullName == "System.Int16") 1441 pos = 4; 1442 int nnamed = (int)data [pos++]; 1443 nnamed |= ((int)data [pos++]) << 8; 1444 for (int i = 0; i < nnamed; ++i) { 1445 //byte named_type = data [pos++]; 1446 pos ++; 1447 byte type = data [pos++]; 1448 int len; 1449 string named_name; 1450 1451 if (type == 0x55) { 1452 len = CustomAttributeBuilder.decode_len (data, pos, out pos); 1453 //string named_typename = 1454 CustomAttributeBuilder.string_from_bytes (data, pos, len); 1455 pos += len; 1456 // FIXME: Check that 'named_type' and 'named_typename' match, etc. 1457 // See related code/FIXME in mono/mono/metadata/reflection.c 1458 } 1459 1460 len = CustomAttributeBuilder.decode_len (data, pos, out pos); 1461 named_name = CustomAttributeBuilder.string_from_bytes (data, pos, len); 1462 pos += len; 1463 /* all the fields are integers in StructLayout */ 1464 int value = (int)data [pos++]; 1465 value |= ((int)data [pos++]) << 8; 1466 value |= ((int)data [pos++]) << 16; 1467 value |= ((int)data [pos++]) << 24; 1468 switch (named_name) { 1469 case "CharSet": 1470 switch ((CharSet)value) { 1471 case CharSet.None: 1472 case CharSet.Ansi: 1473 attrs &= ~(TypeAttributes.UnicodeClass | TypeAttributes.AutoClass); 1474 break; 1475 case CharSet.Unicode: 1476 attrs &= ~TypeAttributes.AutoClass; 1477 attrs |= TypeAttributes.UnicodeClass; 1478 break; 1479 case CharSet.Auto: 1480 attrs &= ~TypeAttributes.UnicodeClass; 1481 attrs |= TypeAttributes.AutoClass; 1482 break; 1483 default: 1484 break; // error out... 1485 } 1486 break; 1487 case "Pack": 1488 packing_size = (PackingSize)value; 1489 break; 1490 case "Size": 1491 class_size = value; 1492 break; 1493 default: 1494 break; // error out... 1495 } 1496 } 1497 return; 1498 } else if (attrname == "System.Runtime.CompilerServices.SpecialNameAttribute") { 1499 attrs |= TypeAttributes.SpecialName; 1500 return; 1501 } else if (attrname == "System.SerializableAttribute") { 1502 attrs |= TypeAttributes.Serializable; 1503 return; 1504 } else if (attrname == "System.Runtime.InteropServices.ComImportAttribute") { 1505 attrs |= TypeAttributes.Import; 1506 return; 1507 } else if (attrname == "System.Security.SuppressUnmanagedCodeSecurityAttribute") { 1508 attrs |= TypeAttributes.HasSecurity; 1509 } 1510 1511 if (cattrs != null) { 1512 CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1]; 1513 cattrs.CopyTo (new_array, 0); 1514 new_array [cattrs.Length] = customBuilder; 1515 cattrs = new_array; 1516 } else { 1517 cattrs = new CustomAttributeBuilder [1]; 1518 cattrs [0] = customBuilder; 1519 } 1520 } 1521 1522 [ComVisible (true)] SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)1523 public void SetCustomAttribute (ConstructorInfo con, byte[] binaryAttribute) 1524 { 1525 SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute)); 1526 } 1527 DefineEvent(string name, EventAttributes attributes, Type eventtype)1528 public EventBuilder DefineEvent (string name, EventAttributes attributes, Type eventtype) 1529 { 1530 check_name ("name", name); 1531 if (eventtype == null) 1532 throw new ArgumentNullException ("type"); 1533 check_not_created (); 1534 1535 EventBuilder res = new EventBuilder (this, name, attributes, eventtype); 1536 if (events != null) { 1537 EventBuilder[] new_events = new EventBuilder [events.Length+1]; 1538 System.Array.Copy (events, new_events, events.Length); 1539 new_events [events.Length] = res; 1540 events = new_events; 1541 } else { 1542 events = new EventBuilder [1]; 1543 events [0] = res; 1544 } 1545 return res; 1546 } 1547 DefineInitializedData(string name, byte[] data, FieldAttributes attributes)1548 public FieldBuilder DefineInitializedData (string name, byte[] data, FieldAttributes attributes) { 1549 if (data == null) 1550 throw new ArgumentNullException ("data"); 1551 1552 FieldBuilder res = DefineUninitializedData (name, data.Length, attributes); 1553 res.SetRVAData (data); 1554 return res; 1555 } 1556 DefineUninitializedData(string name, int size, FieldAttributes attributes)1557 public FieldBuilder DefineUninitializedData (string name, int size, FieldAttributes attributes) 1558 { 1559 if (name == null) 1560 throw new ArgumentNullException ("name"); 1561 if (name.Length == 0) 1562 throw new ArgumentException ("Empty name is not legal", "name"); 1563 if ((size <= 0) || (size > 0x3f0000)) 1564 throw new ArgumentException ("Data size must be > 0 and < 0x3f0000"); 1565 check_not_created (); 1566 1567 string typeName = "$ArrayType$" + size; 1568 TypeIdentifier ident = TypeIdentifiers.WithoutEscape (typeName); 1569 Type datablobtype = pmodule.GetRegisteredType (fullname.NestedName(ident)); 1570 if (datablobtype == null) { 1571 TypeBuilder tb = DefineNestedType (typeName, 1572 TypeAttributes.NestedPrivate|TypeAttributes.ExplicitLayout|TypeAttributes.Sealed, 1573 pmodule.assemblyb.corlib_value_type, null, PackingSize.Size1, size); 1574 tb.CreateType (); 1575 datablobtype = tb; 1576 } 1577 return DefineField (name, datablobtype, attributes|FieldAttributes.Static|FieldAttributes.HasFieldRVA); 1578 } 1579 1580 public TypeToken TypeToken { 1581 get { 1582 return new TypeToken (0x02000000 | table_idx); 1583 } 1584 } 1585 SetParent(Type parent)1586 public void SetParent (Type parent) 1587 { 1588 check_not_created (); 1589 1590 if (parent == null) { 1591 if ((attrs & TypeAttributes.Interface) != 0) { 1592 if ((attrs & TypeAttributes.Abstract) == 0) 1593 throw new InvalidOperationException ("Interface must be declared abstract."); 1594 this.parent = null; 1595 } else { 1596 this.parent = typeof (object); 1597 } 1598 } else { 1599 this.parent = parent; 1600 } 1601 this.parent = ResolveUserType (this.parent); 1602 } 1603 get_next_table_index(object obj, int table, bool inc)1604 internal int get_next_table_index (object obj, int table, bool inc) { 1605 return pmodule.get_next_table_index (obj, table, inc); 1606 } 1607 1608 [ComVisible (true)] GetInterfaceMap(Type interfaceType)1609 public override InterfaceMapping GetInterfaceMap (Type interfaceType) 1610 { 1611 if (created == null) 1612 throw new NotSupportedException ("This method is not implemented for incomplete types."); 1613 1614 return created.GetInterfaceMap (interfaceType); 1615 } 1616 InternalResolve()1617 internal override Type InternalResolve () 1618 { 1619 check_created (); 1620 return created; 1621 } 1622 RuntimeResolve()1623 internal override Type RuntimeResolve () 1624 { 1625 check_created (); 1626 return created; 1627 } 1628 1629 internal bool is_created { 1630 get { 1631 return createTypeCalled; 1632 } 1633 } 1634 not_supported()1635 private Exception not_supported () 1636 { 1637 return new NotSupportedException ("The invoked member is not supported in a dynamic module."); 1638 } 1639 check_not_created()1640 private void check_not_created () 1641 { 1642 if (is_created) 1643 throw new InvalidOperationException ("Unable to change after type has been created."); 1644 } 1645 check_created()1646 private void check_created () 1647 { 1648 if (!is_created) 1649 throw not_supported (); 1650 } 1651 check_name(string argName, string name)1652 private void check_name (string argName, string name) 1653 { 1654 if (name == null) 1655 throw new ArgumentNullException (argName); 1656 if (name.Length == 0) 1657 throw new ArgumentException ("Empty name is not legal", argName); 1658 if (name [0] == ((char)0)) 1659 throw new ArgumentException ("Illegal name", argName); 1660 } 1661 ToString()1662 public override String ToString () 1663 { 1664 return FullName; 1665 } 1666 1667 [MonoTODO] IsAssignableFrom(Type c)1668 public override bool IsAssignableFrom (Type c) 1669 { 1670 return base.IsAssignableFrom (c); 1671 } 1672 1673 [MonoTODO ("arrays")] IsAssignableTo(Type c)1674 internal bool IsAssignableTo (Type c) 1675 { 1676 if (c == this) 1677 return true; 1678 1679 if (c.IsInterface) { 1680 if (parent != null && is_created) { 1681 if (c.IsAssignableFrom (parent)) 1682 return true; 1683 } 1684 1685 if (interfaces == null) 1686 return false; 1687 foreach (Type t in interfaces) 1688 if (c.IsAssignableFrom (t)) 1689 return true; 1690 if (!is_created) 1691 return false; 1692 } 1693 1694 if (parent == null) 1695 return c == typeof (object); 1696 else 1697 return c.IsAssignableFrom (parent); 1698 } 1699 IsCreated()1700 public bool IsCreated () 1701 { 1702 return is_created; 1703 } 1704 GetGenericArguments()1705 public override Type[] GetGenericArguments () 1706 { 1707 if (generic_params == null) 1708 return null; 1709 Type[] args = new Type [generic_params.Length]; 1710 generic_params.CopyTo (args, 0); 1711 return args; 1712 } 1713 GetGenericTypeDefinition()1714 public override Type GetGenericTypeDefinition () 1715 { 1716 if (generic_params == null) 1717 throw new InvalidOperationException ("Type is not generic"); 1718 return this; 1719 } 1720 1721 public override bool ContainsGenericParameters { 1722 get { 1723 return generic_params != null; 1724 } 1725 } 1726 1727 public override bool IsGenericParameter { 1728 get { 1729 return false; 1730 } 1731 } 1732 1733 public override GenericParameterAttributes GenericParameterAttributes { 1734 get { return GenericParameterAttributes.None; } 1735 } 1736 1737 public override bool IsGenericTypeDefinition { 1738 get { 1739 return generic_params != null; 1740 } 1741 } 1742 1743 public override bool IsGenericType { 1744 get { return IsGenericTypeDefinition; } 1745 } 1746 1747 [MonoTODO] 1748 public override int GenericParameterPosition { 1749 get { 1750 return 0; 1751 } 1752 } 1753 1754 public override MethodBase DeclaringMethod { 1755 get { 1756 return null; 1757 } 1758 } 1759 DefineGenericParameters(params string[] names)1760 public GenericTypeParameterBuilder[] DefineGenericParameters (params string[] names) 1761 { 1762 if (names == null) 1763 throw new ArgumentNullException ("names"); 1764 if (names.Length == 0) 1765 throw new ArgumentException ("names"); 1766 1767 generic_params = new GenericTypeParameterBuilder [names.Length]; 1768 for (int i = 0; i < names.Length; i++) { 1769 string item = names [i]; 1770 if (item == null) 1771 throw new ArgumentNullException ("names"); 1772 generic_params [i] = new GenericTypeParameterBuilder (this, null, item, i); 1773 } 1774 1775 return generic_params; 1776 } 1777 GetConstructor(Type type, ConstructorInfo constructor)1778 public static ConstructorInfo GetConstructor (Type type, ConstructorInfo constructor) 1779 { 1780 /*FIXME I would expect the same checks of GetMethod here*/ 1781 if (type == null) 1782 throw new ArgumentException ("Type is not generic", "type"); 1783 1784 if (!type.IsGenericType) 1785 throw new ArgumentException ("Type is not a generic type", "type"); 1786 1787 if (type.IsGenericTypeDefinition) 1788 throw new ArgumentException ("Type cannot be a generic type definition", "type"); 1789 1790 if (constructor == null) 1791 throw new NullReferenceException (); //MS raises this instead of an ArgumentNullException 1792 1793 if (!constructor.DeclaringType.IsGenericTypeDefinition) 1794 throw new ArgumentException ("constructor declaring type is not a generic type definition", "constructor"); 1795 if (constructor.DeclaringType != type.GetGenericTypeDefinition ()) 1796 throw new ArgumentException ("constructor declaring type is not the generic type definition of type", "constructor"); 1797 1798 ConstructorInfo res = type.GetConstructor (constructor); 1799 if (res == null) 1800 throw new ArgumentException ("constructor not found"); 1801 1802 return res; 1803 } 1804 IsValidGetMethodType(Type type)1805 static bool IsValidGetMethodType (Type type) 1806 { 1807 if (type is TypeBuilder || type is TypeBuilderInstantiation) 1808 return true; 1809 /*GetMethod() must work with TypeBuilders after CreateType() was called.*/ 1810 if (type.Module is ModuleBuilder) 1811 return true; 1812 if (type.IsGenericParameter) 1813 return false; 1814 1815 Type[] inst = type.GetGenericArguments (); 1816 if (inst == null) 1817 return false; 1818 for (int i = 0; i < inst.Length; ++i) { 1819 if (IsValidGetMethodType (inst [i])) 1820 return true; 1821 } 1822 return false; 1823 } 1824 GetMethod(Type type, MethodInfo method)1825 public static MethodInfo GetMethod (Type type, MethodInfo method) 1826 { 1827 if (!IsValidGetMethodType (type)) 1828 throw new ArgumentException ("type is not TypeBuilder but " + type.GetType (), "type"); 1829 1830 if (type is TypeBuilder && type.ContainsGenericParameters) 1831 type = type.MakeGenericType (type.GetGenericArguments ()); 1832 1833 if (!type.IsGenericType) 1834 throw new ArgumentException ("type is not a generic type", "type"); 1835 1836 if (!method.DeclaringType.IsGenericTypeDefinition) 1837 throw new ArgumentException ("method declaring type is not a generic type definition", "method"); 1838 if (method.DeclaringType != type.GetGenericTypeDefinition ()) 1839 throw new ArgumentException ("method declaring type is not the generic type definition of type", "method"); 1840 if (method == null) 1841 throw new NullReferenceException (); //MS raises this instead of an ArgumentNullException 1842 1843 MethodInfo res = type.GetMethod (method); 1844 if (res == null) 1845 throw new ArgumentException (String.Format ("method {0} not found in type {1}", method.Name, type)); 1846 1847 return res; 1848 } 1849 GetField(Type type, FieldInfo field)1850 public static FieldInfo GetField (Type type, FieldInfo field) 1851 { 1852 if (!type.IsGenericType) 1853 throw new ArgumentException ("Type is not a generic type", "type"); 1854 1855 if (type.IsGenericTypeDefinition) 1856 throw new ArgumentException ("Type cannot be a generic type definition", "type"); 1857 1858 if (field is FieldOnTypeBuilderInst) 1859 throw new ArgumentException ("The specified field must be declared on a generic type definition.", "field"); 1860 1861 if (field.DeclaringType != type.GetGenericTypeDefinition ()) 1862 throw new ArgumentException ("field declaring type is not the generic type definition of type", "method"); 1863 1864 FieldInfo res = type.GetField (field); 1865 if (res == null) 1866 throw new System.Exception ("field not found"); 1867 else 1868 return res; 1869 } 1870 1871 _TypeBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)1872 void _TypeBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) 1873 { 1874 throw new NotImplementedException (); 1875 } 1876 _TypeBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)1877 void _TypeBuilder.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo) 1878 { 1879 throw new NotImplementedException (); 1880 } 1881 _TypeBuilder.GetTypeInfoCount(out uint pcTInfo)1882 void _TypeBuilder.GetTypeInfoCount (out uint pcTInfo) 1883 { 1884 throw new NotImplementedException (); 1885 } 1886 _TypeBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)1887 void _TypeBuilder.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) 1888 { 1889 throw new NotImplementedException (); 1890 } 1891 1892 internal override bool IsUserType { 1893 get { 1894 return false; 1895 } 1896 } 1897 1898 public override bool IsConstructedGenericType { 1899 get { return false; } 1900 } 1901 IsAssignableFrom(TypeInfo typeInfo)1902 public override bool IsAssignableFrom (TypeInfo typeInfo) 1903 { 1904 return base.IsAssignableFrom (typeInfo); 1905 } 1906 } 1907 } 1908 #endif 1909