25using System.Collections.Generic;
26using System.Diagnostics;
27using System.Reflection.Metadata;
28using System.Reflection.Metadata.Ecma335;
29using System.Runtime.InteropServices;
37 internal sealed class TypeBuilder : TypeInfo,
ITypeOwner
40 public const int UnspecifiedTypeSize = 0;
46 readonly StringHandle typeName;
47 readonly StringHandle typeNameSpace;
50 readonly List<MethodBuilder> methods =
new List<MethodBuilder>();
51 readonly List<FieldBuilder> fields =
new List<FieldBuilder>();
52 List<PropertyBuilder> properties;
53 List<EventBuilder> events;
54 TypeAttributes attribs;
55 GenericTypeParameterBuilder[] gtpb;
56 List<CustomAttributeBuilder> declarativeSecurity;
57 List<Type> interfaces;
68 internal TypeBuilder(
ITypeOwner owner,
string ns,
string name)
71 this.token = ModuleBuilder.TypeDefTable.AllocToken();
74 this.typeNameSpace = ns ==
null ? default : ModuleBuilder.GetOrAddString(ns);
75 this.typeName = ModuleBuilder.GetOrAddString(name);
76 MarkKnownType(ns, name);
79 public ConstructorBuilder DefineDefaultConstructor(MethodAttributes attributes)
81 var cb = DefineConstructor(attributes, CallingConventions.Standard,
Type.EmptyTypes);
82 var ilgen = cb.GetILGenerator();
83 ilgen.Emit(OpCodes.Ldarg_0);
84 ilgen.Emit(OpCodes.Call, BaseType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
null,
Type.EmptyTypes,
null));
85 ilgen.Emit(OpCodes.Ret);
89 public ConstructorBuilder DefineConstructor(MethodAttributes attribs, CallingConventions callConv,
Type[] parameterTypes)
91 return DefineConstructor(attribs, callConv, parameterTypes,
null,
null);
94 public ConstructorBuilder DefineConstructor(MethodAttributes attribs, CallingConventions callingConvention,
Type[] parameterTypes,
Type[][] requiredCustomModifiers,
Type[][] optionalCustomModifiers)
96 attribs |= MethodAttributes.RTSpecialName | MethodAttributes.SpecialName;
98 var mb = DefineMethod(name, attribs, callingConvention,
null,
null,
null, parameterTypes, requiredCustomModifiers, optionalCustomModifiers);
99 return new ConstructorBuilder(mb);
102 public ConstructorBuilder DefineTypeInitializer()
104 var mb = DefineMethod(
ConstructorInfo.TypeConstructorName, MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName,
null,
Type.EmptyTypes);
105 return new ConstructorBuilder(mb);
108 private MethodBuilder CreateMethodBuilder(
string name, MethodAttributes attributes, CallingConventions callingConvention)
110 ModuleBuilder.MethodDefTable.AddVirtualRecord();
111 var mb =
new MethodBuilder(
this, name, attributes, callingConvention);
116 public MethodBuilder DefineMethod(
string name, MethodAttributes attribs)
118 return DefineMethod(name, attribs, CallingConventions.Standard);
121 public MethodBuilder DefineMethod(
string name, MethodAttributes attribs, CallingConventions callingConvention)
123 return CreateMethodBuilder(name, attribs, callingConvention);
126 public MethodBuilder DefineMethod(
string name, MethodAttributes attribs,
Type returnType,
Type[] parameterTypes)
128 return DefineMethod(name, attribs, CallingConventions.Standard, returnType,
null,
null, parameterTypes,
null,
null);
131 public MethodBuilder DefineMethod(
string name, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType,
Type[] parameterTypes)
133 return DefineMethod(name, attributes, callingConvention, returnType,
null,
null, parameterTypes,
null,
null);
136 public MethodBuilder DefineMethod(
string name, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType,
Type[] returnTypeRequiredCustomModifiers,
Type[] returnTypeOptionalCustomModifiers,
Type[] parameterTypes,
Type[][] parameterTypeRequiredCustomModifiers,
Type[][] parameterTypeOptionalCustomModifiers)
138 var mb = CreateMethodBuilder(name, attributes, callingConvention);
139 mb.SetSignature(returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
143 public MethodBuilder DefinePInvokeMethod(
string name,
string dllName, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType,
Type[] parameterTypes,
CallingConvention nativeCallConv, CharSet nativeCharSet)
145 return DefinePInvokeMethod(name, dllName,
null, attributes, callingConvention, returnType,
null,
null, parameterTypes,
null,
null, nativeCallConv, nativeCharSet);
148 public MethodBuilder DefinePInvokeMethod(
string name,
string dllName,
string entryName, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType,
Type[] parameterTypes,
CallingConvention nativeCallConv, CharSet nativeCharSet)
150 return DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType,
null,
null, parameterTypes,
null,
null, nativeCallConv, nativeCharSet);
153 public MethodBuilder 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)
155 var mb = DefineMethod(name, attributes | MethodAttributes.PinvokeImpl, callingConvention, returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
156 mb.SetDllImportPseudoCustomAttribute(dllName, entryName, nativeCallConv, nativeCharSet,
null,
null,
null,
null,
null);
164 rec.MethodBody = this.ModuleBuilder.GetMethodToken(methodInfoBody).Token;
165 rec.MethodDeclaration = this.ModuleBuilder.GetMethodTokenWinRT(methodInfoDeclaration);
166 ModuleBuilder.MethodImplTable.AddRecord(rec);
169 public FieldBuilder DefineField(
string name,
Type fieldType, FieldAttributes attribs)
171 return DefineField(name, fieldType,
null,
null, attribs);
174 public FieldBuilder DefineField(
string fieldName,
Type type,
Type[] requiredCustomModifiers,
Type[] optionalCustomModifiers, FieldAttributes attributes)
176 return __DefineField(fieldName, type, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers), attributes);
179 public FieldBuilder __DefineField(
string fieldName,
Type type, CustomModifiers customModifiers, FieldAttributes attributes)
181 var fb =
new FieldBuilder(
this, fieldName, type, customModifiers, attributes);
186 public PropertyBuilder DefineProperty(
string name, PropertyAttributes attributes,
Type returnType,
Type[] parameterTypes)
188 return DefineProperty(name, attributes, returnType,
null,
null, parameterTypes,
null,
null);
191 public PropertyBuilder DefineProperty(
string name, PropertyAttributes attributes, CallingConventions callingConvention,
Type returnType,
Type[] parameterTypes)
193 return DefineProperty(name, attributes, callingConvention, returnType,
null,
null, parameterTypes,
null,
null);
196 public PropertyBuilder DefineProperty(
string name, PropertyAttributes attributes,
Type returnType,
Type[] returnTypeRequiredCustomModifiers,
Type[] returnTypeOptionalCustomModifiers,
Type[] parameterTypes,
Type[][] parameterTypeRequiredCustomModifiers,
Type[][] parameterTypeOptionalCustomModifiers)
198 return DefinePropertyImpl(name, attributes, CallingConventions.Standard,
true, returnType, parameterTypes,
PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers,
Util.NullSafeLength(parameterTypes)));
201 public PropertyBuilder DefineProperty(
string name, PropertyAttributes attributes, CallingConventions callingConvention,
Type returnType,
Type[] returnTypeRequiredCustomModifiers,
Type[] returnTypeOptionalCustomModifiers,
Type[] parameterTypes,
Type[][] parameterTypeRequiredCustomModifiers,
Type[][] parameterTypeOptionalCustomModifiers)
203 return DefinePropertyImpl(name, attributes, callingConvention,
false, returnType, parameterTypes,
PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers,
Util.NullSafeLength(parameterTypes)));
206 public PropertyBuilder __DefineProperty(
string name, PropertyAttributes attributes, CallingConventions callingConvention,
Type returnType, CustomModifiers returnTypeCustomModifiers,
Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
208 return DefinePropertyImpl(name, attributes, callingConvention,
false, returnType, parameterTypes,
PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers,
Util.NullSafeLength(parameterTypes)));
211 private PropertyBuilder DefinePropertyImpl(
string name, PropertyAttributes attributes, CallingConventions callingConvention,
bool patchCallingConvention,
Type returnType,
Type[] parameterTypes,
PackedCustomModifiers customModifiers)
213 properties ??=
new List<PropertyBuilder>();
214 var sig =
PropertySignature.Create(callingConvention, returnType, parameterTypes, customModifiers);
215 var pb =
new PropertyBuilder(
this, name, attributes, sig, patchCallingConvention);
220 public EventBuilder DefineEvent(
string name, EventAttributes attributes,
Type eventtype)
222 events ??=
new List<EventBuilder>();
223 var eb =
new EventBuilder(
this, name, attributes, eventtype);
228 public TypeBuilder DefineNestedType(
string name)
230 return DefineNestedType(name, TypeAttributes.Class | TypeAttributes.NestedPrivate);
233 public TypeBuilder DefineNestedType(
string name, TypeAttributes attribs)
235 return DefineNestedType(name, attribs,
null);
238 public TypeBuilder DefineNestedType(
string name, TypeAttributes attr,
Type parent,
Type[] interfaces)
240 var tb = DefineNestedType(name, attr, parent);
241 if (interfaces !=
null)
242 foreach (
Type iface
in interfaces)
243 tb.AddInterfaceImplementation(iface);
248 public TypeBuilder DefineNestedType(
string name, TypeAttributes attr,
Type parent)
250 return DefineNestedType(name, attr, parent, 0);
253 public TypeBuilder DefineNestedType(
string name, TypeAttributes attr,
Type parent,
int typeSize)
255 return DefineNestedType(name, attr, parent, PackingSize.Unspecified, typeSize);
258 public TypeBuilder DefineNestedType(
string name, TypeAttributes attr,
Type parent, PackingSize packSize)
260 return DefineNestedType(name, attr, parent, packSize, 0);
263 public TypeBuilder DefineNestedType(
string name, TypeAttributes attr,
Type parent, PackingSize packSize,
int typeSize)
266 var lastdot = name.LastIndexOf(
'.');
269 ns = name.Substring(0, lastdot);
270 name = name.Substring(lastdot + 1);
273 var typeBuilder = __DefineNestedType(ns, name);
274 typeBuilder.__SetAttributes(attr);
275 typeBuilder.SetParent(parent);
276 if (packSize != PackingSize.Unspecified || typeSize != 0)
277 typeBuilder.__SetLayout((
int)packSize, typeSize);
282 public TypeBuilder __DefineNestedType(
string ns,
string name)
284 typeFlags |= TypeFlags.HasNestedTypes;
285 var typeBuilder = ModuleBuilder.DefineType(
this, ns, name);
287 rec.NestedClass = typeBuilder.MetadataToken;
288 rec.EnclosingClass = MetadataToken;
289 ModuleBuilder.NestedClassTable.AddRecord(rec);
293 public void SetParent(
Type parent)
295 lazyBaseType = parent;
298 public void AddInterfaceImplementation(
Type interfaceType)
300 interfaces ??=
new List<Type>();
301 interfaces.Add(interfaceType);
304 public void __SetInterfaceImplementationCustomAttribute(
Type interfaceType, CustomAttributeBuilder cab)
306 ModuleBuilder.SetInterfaceImplementationCustomAttribute(
this, interfaceType, cab);
314 public PackingSize PackingSize
316 get {
return (PackingSize)packingSize; }
319 public override bool __GetLayout(out
int packingSize, out
int size)
321 packingSize = this.packingSize;
326 public void __SetLayout(
int packingSize,
int size)
328 this.packingSize = (short)packingSize;
333 void SetStructLayoutPseudoCustomAttribute(CustomAttributeBuilder customBuilder)
335 var val = customBuilder.GetConstructorArgument(0);
336 var layout = val is
short v ? (LayoutKind)v : (LayoutKind)val;
337 packingSize = (short)((
int?)customBuilder.GetFieldValue(
"Pack") ?? 0);
338 size = (
int?)customBuilder.GetFieldValue(
"Size") ?? 0;
340 attribs &= ~TypeAttributes.LayoutMask;
343 case LayoutKind.Auto:
344 attribs |= TypeAttributes.AutoLayout;
346 case LayoutKind.Explicit:
347 attribs |= TypeAttributes.ExplicitLayout;
349 case LayoutKind.Sequential:
350 attribs |= TypeAttributes.SequentialLayout;
354 attribs &= ~TypeAttributes.StringFormatMask;
356 switch (customBuilder.GetFieldValue<CharSet>(
"CharSet") ?? CharSet.None)
360 attribs |= TypeAttributes.AnsiClass;
363 attribs |= TypeAttributes.AutoClass;
365 case CharSet.Unicode:
366 attribs |= TypeAttributes.UnicodeClass;
370 hasLayout = packingSize != 0 || size != 0;
373 public void SetCustomAttribute(
ConstructorInfo con,
byte[] binaryAttribute)
375 SetCustomAttribute(
new CustomAttributeBuilder(con, binaryAttribute));
378 public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
380 switch (customBuilder.KnownCA)
382 case KnownCA.StructLayoutAttribute:
383 SetStructLayoutPseudoCustomAttribute(customBuilder.DecodeBlob(
this.Assembly));
385 case KnownCA.SerializableAttribute:
386 attribs |= TypeAttributes.Serializable;
388 case KnownCA.ComImportAttribute:
389 attribs |= TypeAttributes.Import;
391 case KnownCA.SpecialNameAttribute:
392 attribs |= TypeAttributes.SpecialName;
394 case KnownCA.SuppressUnmanagedCodeSecurityAttribute:
395 attribs |= TypeAttributes.HasSecurity;
398 ModuleBuilder.SetCustomAttribute(token, customBuilder);
403 public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder)
405 attribs |= TypeAttributes.HasSecurity;
406 declarativeSecurity ??=
new List<CustomAttributeBuilder>();
407 declarativeSecurity.Add(customBuilder);
410 public void AddDeclarativeSecurity(
System.Security.Permissions.SecurityAction securityAction,
System.Security.PermissionSet permissionSet)
412 ModuleBuilder.AddDeclarativeSecurity(token, securityAction, permissionSet);
413 attribs |= TypeAttributes.HasSecurity;
416 public GenericTypeParameterBuilder[] DefineGenericParameters(params
string[] names)
418 typeFlags |= TypeFlags.IsGenericTypeDefinition;
419 gtpb =
new GenericTypeParameterBuilder[names.Length];
420 for (
int i = 0; i < names.Length; i++)
421 gtpb[i] =
new GenericTypeParameterBuilder(names[i],
this, i);
423 return (GenericTypeParameterBuilder[])gtpb.Clone();
426 public override Type[] GetGenericArguments()
428 return Util.Copy(gtpb);
431 public override CustomModifiers[] __GetGenericArgumentsCustomModifiers()
433 return gtpb ==
null ? Array.Empty<CustomModifiers>() : new CustomModifiers[gtpb.Length];
436 internal override Type GetGenericTypeArgument(
int index)
441 public override bool ContainsGenericParameters
443 get {
return gtpb !=
null; }
446 public override Type GetGenericTypeDefinition()
451 public TypeInfo CreateTypeInfo()
454 if ((typeFlags & TypeFlags.Baked) != 0)
455 throw new NotImplementedException();
457 typeFlags |= TypeFlags.Baked;
461 rec.PackingSize = packingSize;
462 rec.ClassSize = size;
464 ModuleBuilder.ClassLayoutTable.AddRecord(rec);
467 var hasConstructor =
false;
468 foreach (var mb
in methods)
470 hasConstructor |= mb.IsSpecialName && mb.Name ==
ConstructorInfo.ConstructorName;
474 if (!hasConstructor && !IsModulePseudoType && !IsInterface && !IsValueType && !(IsAbstract && IsSealed) && Universe.AutomaticallyProvideDefaultConstructor)
475 ((MethodBuilder)DefineDefaultConstructor(MethodAttributes.Public).GetMethodInfo()).Bake();
477 if (declarativeSecurity !=
null)
478 ModuleBuilder.AddDeclarativeSecurity(token, declarativeSecurity);
480 if (!IsModulePseudoType)
482 var baseType = BaseType;
483 if (baseType !=
null)
484 extends = ModuleBuilder.GetTypeToken(baseType).Token;
487 if (interfaces !=
null)
489 foreach (var interfaceType
in interfaces)
493 rec.Interface = ModuleBuilder.GetTypeToken(interfaceType).Token;
494 ModuleBuilder.InterfaceImplTable.AddRecord(rec);
498 return new BakedType(
this);
501 public Type CreateType()
503 return CreateTypeInfo();
506 internal void PopulatePropertyAndEventTables()
508 if (properties !=
null)
512 rec.PropertyList = MetadataTokens.GetToken(MetadataTokens.PropertyDefinitionHandle(ModuleBuilder.PropertyTable.RowCount + 1));
513 ModuleBuilder.PropertyMapTable.AddRecord(rec);
514 foreach (var pb
in properties)
522 rec.EventList = MetadataTokens.GetToken(MetadataTokens.EventDefinitionHandle(ModuleBuilder.EventTable.RowCount + 1));
523 ModuleBuilder.EventMapTable.AddRecord(rec);
524 foreach (var eb
in events)
529 public override Type BaseType
533 if (lazyBaseType ==
null && !IsInterface)
535 var obj =
Module.Universe.System_Object;
544 public override string FullName
549 return DeclaringType.FullName +
"+" +
TypeNameParser.Escape(name);
560 get {
return new TypeName(ns, name); }
563 public override string Name
569 public override string Namespace
579 public override TypeAttributes Attributes
581 get {
return attribs; }
584 public void __SetAttributes(TypeAttributes attributes)
586 attribs = attributes;
589 public override Type[] __GetDeclaredInterfaces()
591 return Util.ToArray(interfaces,
Type.EmptyTypes);
594 public override MethodBase[] __GetDeclaredMethods()
596 var methods =
new MethodBase[this.methods.Count];
597 for (
int i = 0; i < methods.Length; i++)
599 var mb = this.methods[i];
606 public override Type DeclaringType
608 get {
return owner as TypeBuilder; }
611 public override bool IsGenericType
613 get {
return IsGenericTypeDefinition; }
616 public override bool IsGenericTypeDefinition
618 get {
return (typeFlags & TypeFlags.IsGenericTypeDefinition) != 0; }
621 public override int MetadataToken
623 get {
return token; }
626 public FieldBuilder DefineUninitializedData(
string name,
int size, FieldAttributes attributes)
628 return DefineInitializedData(name,
new byte[size], attributes);
631 public FieldBuilder DefineInitializedData(
string name,
byte[] data, FieldAttributes attributes)
633 throw new NotImplementedException();
668 public TypeToken TypeToken
670 get {
return new TypeToken(token); }
673 internal void WriteTypeDefRecord(
ref int fieldList,
ref int methodList)
675 var h = ModuleBuilder.Metadata.AddTypeDefinition(
676 (
System.Reflection.TypeAttributes)attribs,
679 MetadataTokens.EntityHandle(extends),
680 MetadataTokens.FieldDefinitionHandle(fieldList),
681 MetadataTokens.MethodDefinitionHandle(methodList));
683 Debug.Assert(h == MetadataTokens.TypeDefinitionHandle(token));
686 fieldList += fields.Count;
687 methodList += methods.Count;
690 internal void WriteMethodDefRecords(
ref int paramList)
692 foreach (var mb
in methods)
693 mb.WriteMetadata(
ref paramList);
696 internal void ResolveMethodAndFieldTokens(
ref int methodToken,
ref int fieldToken,
ref int parameterToken)
698 foreach (var method
in methods)
699 method.FixupToken(methodToken++,
ref parameterToken);
700 foreach (var field
in fields)
701 field.FixupToken(fieldToken++);
704 internal void WriteParamRecords()
706 foreach (var mb
in methods)
707 mb.WriteParamRecords();
710 internal void WriteFieldRecords()
712 foreach (var fb
in fields)
713 fb.WriteFieldRecords();
716 internal ModuleBuilder ModuleBuilder
721 ModuleBuilder ITypeOwner.ModuleBuilder
726 internal override int GetModuleBuilderToken()
731 internal bool HasNestedTypes
733 get {
return (typeFlags & TypeFlags.HasNestedTypes) != 0; }
743 foreach (var method
in methods)
744 if (method.MetadataToken == token)
750 public bool IsCreated()
752 return (typeFlags & TypeFlags.Baked) != 0;
755 internal override void CheckBaked()
757 if ((typeFlags & TypeFlags.Baked) == 0)
758 throw new NotSupportedException();
761 public override Type[] __GetDeclaredTypes()
765 var types =
new List<Type>();
766 var classes = ModuleBuilder.NestedClassTable.GetNestedClasses(token);
767 foreach (var nestedClass
in classes)
768 types.Add(ModuleBuilder.ResolveType(nestedClass));
770 return types.ToArray();
774 return Type.EmptyTypes;
778 public override FieldInfo[] __GetDeclaredFields()
783 public override EventInfo[] __GetDeclaredEvents()
788 public override PropertyInfo[] __GetDeclaredProperties()
793 internal override bool IsModulePseudoType
795 get {
return token == 0x02000001; }
798 internal override bool IsBaked
800 get {
return IsCreated(); }
803 protected override bool IsValueTypeImpl
807 var baseType = this.BaseType;
808 if (baseType !=
null && baseType.IsEnumOrValueType && !
this.IsEnumOrValueType)
811 typeFlags |= TypeFlags.ValueType;
818 typeFlags |= TypeFlags.NotValueType;
IKVM.Reflection.Module Module
IKVM.Reflection.Type Type
IKVM.Reflection.ConstructorInfo ConstructorInfo
IKVM.Reflection.EventInfo EventInfo
IKVM.Reflection.FieldInfo FieldInfo
IKVM.Reflection.PropertyInfo PropertyInfo
IKVM.Reflection.MethodInfo MethodInfo
IKVM.Reflection.MethodBase MethodBase
global::java.lang.invoke.LambdaForm.Name Name
System.Runtime.InteropServices.CallingConvention CallingConvention
ModuleBuilder ModuleBuilder
KnownCA
These are the pseudo-custom attributes that are recognized by name by the runtime (i....