public DmdType Create(CorType type) { if (type == null) { throw new ArgumentNullException(nameof(type)); } if (recursionCounter++ > 100) { throw new InvalidOperationException(); } DmdType result; List <DmdType> types; switch (type.ElementType) { case CorElementType.Void: result = reflectionAppDomain.System_Void; break; case CorElementType.Boolean: result = reflectionAppDomain.System_Boolean; break; case CorElementType.Char: result = reflectionAppDomain.System_Char; break; case CorElementType.I1: result = reflectionAppDomain.System_SByte; break; case CorElementType.U1: result = reflectionAppDomain.System_Byte; break; case CorElementType.I2: result = reflectionAppDomain.System_Int16; break; case CorElementType.U2: result = reflectionAppDomain.System_UInt16; break; case CorElementType.I4: result = reflectionAppDomain.System_Int32; break; case CorElementType.U4: result = reflectionAppDomain.System_UInt32; break; case CorElementType.I8: result = reflectionAppDomain.System_Int64; break; case CorElementType.U8: result = reflectionAppDomain.System_UInt64; break; case CorElementType.R4: result = reflectionAppDomain.System_Single; break; case CorElementType.R8: result = reflectionAppDomain.System_Double; break; case CorElementType.String: result = reflectionAppDomain.System_String; break; case CorElementType.TypedByRef: result = reflectionAppDomain.System_TypedReference; break; case CorElementType.I: result = reflectionAppDomain.System_IntPtr; break; case CorElementType.U: result = reflectionAppDomain.System_UIntPtr; break; case CorElementType.Object: result = reflectionAppDomain.System_Object; break; case CorElementType.Ptr: result = Create(type.FirstTypeParameter).MakePointerType(); break; case CorElementType.ByRef: result = Create(type.FirstTypeParameter).MakeByRefType(); break; case CorElementType.SZArray: result = Create(type.FirstTypeParameter).MakeArrayType(); break; case CorElementType.Array: result = Create(type.FirstTypeParameter).MakeArrayType((int)type.Rank); break; case CorElementType.ValueType: case CorElementType.Class: var cl = type.Class ?? throw new InvalidOperationException(); var module = engine.TryGetModule(cl.Module)?.GetReflectionModule() ?? throw new InvalidOperationException(); var reflectionType = module.ResolveType((int)cl.Token, DmdResolveOptions.ThrowOnError); if (reflectionType.GetGenericArguments().Count != 0) { types = GetTypesList(); foreach (var t in type.TypeParameters) { types.Add(Create(t)); } Debug.Assert(types.Count == 0 || reflectionType.GetGenericArguments().Count == types.Count); if (types.Count != 0) { reflectionType = reflectionType.MakeGenericType(types.ToArray()); } FreeTypesList(ref types); } result = reflectionType; break; case CorElementType.FnPtr: DmdType returnType = null; types = null; foreach (var t in type.TypeParameters) { if ((object)returnType == null) { returnType = Create(t); } else { if (types == null) { types = GetTypesList(); } types.Add(Create(t)); } } if ((object)returnType == null) { throw new InvalidOperationException(); } //TODO: Guessing FnPtr calling convention const DmdSignatureCallingConvention fnPtrCallingConvention = DmdSignatureCallingConvention.C; //TODO: We're assuming varArgsParameterTypes is empty result = reflectionAppDomain.MakeFunctionPointerType(fnPtrCallingConvention, 0, returnType, types?.ToArray() ?? Array.Empty <DmdType>(), Array.Empty <DmdType>(), null); FreeTypesList(ref types); break; case CorElementType.GenericInst: case CorElementType.Var: case CorElementType.MVar: case CorElementType.End: case CorElementType.ValueArray: case CorElementType.R: case CorElementType.CModReqd: case CorElementType.CModOpt: case CorElementType.Internal: case CorElementType.Module: case CorElementType.Sentinel: case CorElementType.Pinned: default: Debug.Fail($"Unsupported element type: {type.ElementType}"); throw new InvalidOperationException(); } recursionCounter--; return(result); }
public override DmdType WithCustomModifiers(IList <DmdCustomModifier> customModifiers) => AppDomain.MakeFunctionPointerType(methodSignature.Flags, methodSignature.GenericParameterCount, methodSignature.ReturnType, methodSignature.GetParameterTypes(), methodSignature.GetVarArgsParameterTypes(), customModifiers);