| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- using ILRuntime.Mono.Cecil.Cil;
- using System;
- namespace ILRuntime.Mono.Cecil {
- internal sealed class GenericParameterResolver {
- internal static TypeReference ResolveReturnTypeIfNeeded (MethodReference methodReference)
- {
- if (methodReference.DeclaringType.IsArray && methodReference.Name == "Get")
- return methodReference.ReturnType;
- var genericInstanceMethod = methodReference as GenericInstanceMethod;
- var declaringGenericInstanceType = methodReference.DeclaringType as GenericInstanceType;
- if (genericInstanceMethod == null && declaringGenericInstanceType == null)
- return methodReference.ReturnType;
- return ResolveIfNeeded (genericInstanceMethod, declaringGenericInstanceType, methodReference.ReturnType);
- }
- internal static TypeReference ResolveFieldTypeIfNeeded (FieldReference fieldReference)
- {
- return ResolveIfNeeded (null, fieldReference.DeclaringType as GenericInstanceType, fieldReference.FieldType);
- }
- internal static TypeReference ResolveParameterTypeIfNeeded (MethodReference method, ParameterReference parameter)
- {
- var genericInstanceMethod = method as GenericInstanceMethod;
- var declaringGenericInstanceType = method.DeclaringType as GenericInstanceType;
- if (genericInstanceMethod == null && declaringGenericInstanceType == null)
- return parameter.ParameterType;
- return ResolveIfNeeded (genericInstanceMethod, declaringGenericInstanceType, parameter.ParameterType);
- }
- internal static TypeReference ResolveVariableTypeIfNeeded (MethodReference method, VariableReference variable)
- {
- var genericInstanceMethod = method as GenericInstanceMethod;
- var declaringGenericInstanceType = method.DeclaringType as GenericInstanceType;
- if (genericInstanceMethod == null && declaringGenericInstanceType == null)
- return variable.VariableType;
- return ResolveIfNeeded (genericInstanceMethod, declaringGenericInstanceType, variable.VariableType);
- }
- private static TypeReference ResolveIfNeeded (IGenericInstance genericInstanceMethod, IGenericInstance declaringGenericInstanceType, TypeReference parameterType)
- {
- var byRefType = parameterType as ByReferenceType;
- if (byRefType != null)
- return ResolveIfNeeded (genericInstanceMethod, declaringGenericInstanceType, byRefType);
- var arrayType = parameterType as ArrayType;
- if (arrayType != null)
- return ResolveIfNeeded (genericInstanceMethod, declaringGenericInstanceType, arrayType);
- var genericInstanceType = parameterType as GenericInstanceType;
- if (genericInstanceType != null)
- return ResolveIfNeeded (genericInstanceMethod, declaringGenericInstanceType, genericInstanceType);
- var genericParameter = parameterType as GenericParameter;
- if (genericParameter != null)
- return ResolveIfNeeded (genericInstanceMethod, declaringGenericInstanceType, genericParameter);
- var requiredModifierType = parameterType as RequiredModifierType;
- if (requiredModifierType != null && ContainsGenericParameters (requiredModifierType))
- return ResolveIfNeeded (genericInstanceMethod, declaringGenericInstanceType, requiredModifierType.ElementType);
- if (ContainsGenericParameters (parameterType))
- throw new Exception ("Unexpected generic parameter.");
- return parameterType;
- }
- private static TypeReference ResolveIfNeeded (IGenericInstance genericInstanceMethod, IGenericInstance genericInstanceType, GenericParameter genericParameterElement)
- {
- return (genericParameterElement.MetadataType == MetadataType.MVar)
- ? (genericInstanceMethod != null ? genericInstanceMethod.GenericArguments[genericParameterElement.Position] : genericParameterElement)
- : genericInstanceType.GenericArguments[genericParameterElement.Position];
- }
- private static ArrayType ResolveIfNeeded (IGenericInstance genericInstanceMethod, IGenericInstance genericInstanceType, ArrayType arrayType)
- {
- return new ArrayType (ResolveIfNeeded (genericInstanceMethod, genericInstanceType, arrayType.ElementType), arrayType.Rank);
- }
- private static ByReferenceType ResolveIfNeeded (IGenericInstance genericInstanceMethod, IGenericInstance genericInstanceType, ByReferenceType byReferenceType)
- {
- return new ByReferenceType (ResolveIfNeeded (genericInstanceMethod, genericInstanceType, byReferenceType.ElementType));
- }
- private static GenericInstanceType ResolveIfNeeded (IGenericInstance genericInstanceMethod, IGenericInstance genericInstanceType, GenericInstanceType genericInstanceType1)
- {
- if (!ContainsGenericParameters (genericInstanceType1))
- return genericInstanceType1;
- var newGenericInstance = new GenericInstanceType (genericInstanceType1.ElementType);
- foreach (var genericArgument in genericInstanceType1.GenericArguments) {
- if (!genericArgument.IsGenericParameter) {
- newGenericInstance.GenericArguments.Add (ResolveIfNeeded (genericInstanceMethod, genericInstanceType, genericArgument));
- continue;
- }
- var genParam = (GenericParameter)genericArgument;
- switch (genParam.Type) {
- case GenericParameterType.Type: {
- if (genericInstanceType == null)
- throw new NotSupportedException ();
- newGenericInstance.GenericArguments.Add (genericInstanceType.GenericArguments[genParam.Position]);
- }
- break;
- case GenericParameterType.Method: {
- if (genericInstanceMethod == null)
- newGenericInstance.GenericArguments.Add (genParam);
- else
- newGenericInstance.GenericArguments.Add (genericInstanceMethod.GenericArguments[genParam.Position]);
- }
- break;
- }
- }
- return newGenericInstance;
- }
- private static bool ContainsGenericParameters (TypeReference typeReference)
- {
- var genericParameter = typeReference as GenericParameter;
- if (genericParameter != null)
- return true;
- var arrayType = typeReference as ArrayType;
- if (arrayType != null)
- return ContainsGenericParameters (arrayType.ElementType);
- var pointerType = typeReference as PointerType;
- if (pointerType != null)
- return ContainsGenericParameters (pointerType.ElementType);
- var byRefType = typeReference as ByReferenceType;
- if (byRefType != null)
- return ContainsGenericParameters (byRefType.ElementType);
- var sentinelType = typeReference as SentinelType;
- if (sentinelType != null)
- return ContainsGenericParameters (sentinelType.ElementType);
- var pinnedType = typeReference as PinnedType;
- if (pinnedType != null)
- return ContainsGenericParameters (pinnedType.ElementType);
- var requiredModifierType = typeReference as RequiredModifierType;
- if (requiredModifierType != null)
- return ContainsGenericParameters (requiredModifierType.ElementType);
- var genericInstance = typeReference as GenericInstanceType;
- if (genericInstance != null) {
- foreach (var genericArgument in genericInstance.GenericArguments) {
- if (ContainsGenericParameters (genericArgument))
- return true;
- }
- return false;
- }
- if (typeReference is TypeSpecification)
- throw new NotSupportedException ();
- return false;
- }
- }
- }
|