protected static void WriteType(ModuleBuilder module, ByteBuffer bb, Type type)
{
while (type.HasElementType)
{
if (type.__IsVector)
{
bb.Write(ELEMENT_TYPE_SZARRAY);
}
else if (type.IsArray)
{
int rank = type.GetArrayRank();
bb.Write(ELEMENT_TYPE_ARRAY);
// LAMESPEC the Type production (23.2.12) doesn't include CustomMod* for arrays, but the verifier allows it and ildasm also supports it
WriteCustomModifiers(module, bb, ELEMENT_TYPE_CMOD_REQD, type.__GetRequiredCustomModifiers());
WriteCustomModifiers(module, bb, ELEMENT_TYPE_CMOD_OPT, type.__GetOptionalCustomModifiers());
WriteType(module, bb, type.GetElementType());
bb.WriteCompressedInt(rank);
// since a Type doesn't contain the lower/upper bounds
// (they act like a custom modifier, so they are part of the signature, but not of the Type),
// we set them to the C# compatible values and hope for the best
bb.WriteCompressedInt(0); // boundsCount
bb.WriteCompressedInt(rank); // loCount
for (int i = 0; i < rank; i++)
{
bb.WriteCompressedInt(0);
}
return;
}
else if (type.IsByRef)
{
bb.Write(ELEMENT_TYPE_BYREF);
}
else if (type.IsPointer)
{
bb.Write(ELEMENT_TYPE_PTR);
}
WriteCustomModifiers(module, bb, ELEMENT_TYPE_CMOD_REQD, type.__GetRequiredCustomModifiers());
WriteCustomModifiers(module, bb, ELEMENT_TYPE_CMOD_OPT, type.__GetOptionalCustomModifiers());
type = type.GetElementType();
}
Universe u = module.universe;
if (type == u.System_Void)
{
bb.Write(ELEMENT_TYPE_VOID);
}
else if (type == u.System_Int32)
{
bb.Write(ELEMENT_TYPE_I4);
}
else if (type == u.System_Boolean)
{
bb.Write(ELEMENT_TYPE_BOOLEAN);
}
else if (type == u.System_String)
{
bb.Write(ELEMENT_TYPE_STRING);
}
else if (type == u.System_Char)
{
bb.Write(ELEMENT_TYPE_CHAR);
}
else if (type == u.System_SByte)
{
bb.Write(ELEMENT_TYPE_I1);
}
else if (type == u.System_Byte)
{
bb.Write(ELEMENT_TYPE_U1);
}
else if (type == u.System_Int16)
{
bb.Write(ELEMENT_TYPE_I2);
}
else if (type == u.System_UInt16)
{
bb.Write(ELEMENT_TYPE_U2);
}
else if (type == u.System_UInt32)
{
bb.Write(ELEMENT_TYPE_U4);
}
else if (type == u.System_Int64)
{
bb.Write(ELEMENT_TYPE_I8);
}
else if (type == u.System_UInt64)
{
bb.Write(ELEMENT_TYPE_U8);
}
else if (type == u.System_Single)
{
bb.Write(ELEMENT_TYPE_R4);
}
else if (type == u.System_Double)
{
bb.Write(ELEMENT_TYPE_R8);
}
else if (type == u.System_IntPtr)
{
bb.Write(ELEMENT_TYPE_I);
}
else if (type == u.System_UIntPtr)
{
bb.Write(ELEMENT_TYPE_U);
}
else if (type == u.System_TypedReference)
{
bb.Write(ELEMENT_TYPE_TYPEDBYREF);
}
else if (type == u.System_Object)
{
bb.Write(ELEMENT_TYPE_OBJECT);
}
else if (type.IsGenericParameter)
{
if (type is UnboundGenericMethodParameter || type.DeclaringMethod != null)
{
bb.Write(ELEMENT_TYPE_MVAR);
}
else
{
bb.Write(ELEMENT_TYPE_VAR);
}
bb.WriteCompressedInt(type.GenericParameterPosition);
}
else if (type.IsGenericType)
{
WriteGenericSignature(module, bb, type);
}
else
{
if (type.IsValueType)
{
bb.Write(ELEMENT_TYPE_VALUETYPE);
}
else
{
bb.Write(ELEMENT_TYPE_CLASS);
}
bb.WriteTypeDefOrRefEncoded(module.GetTypeToken(type).Token);
}
}