public FieldInfo Field(FieldReference reference, GenericScope genericScope) { Argument.NotNull(nameof(reference), reference); var definition = reference.Resolve(); var declaringType = Type(reference.DeclaringType, genericScope); genericScope = genericScope.With(definition.DeclaringType.GenericParameters, declaringType.GenericTypeArguments); var interpretedType = declaringType as InterpretedType; if (ShouldBeRuntime(definition) && interpretedType == null) { var token = reference.MetadataToken.ToInt32(); return((FieldInfo)declaringType .GetMembers() .First(m => m.MetadataToken == token)); } if (interpretedType == null) { throw InterpretedMemberInNonInterpretedType(reference, declaringType); } return(new InterpretedField( interpretedType, definition.Name, Type(reference.FieldType, genericScope), (System.Reflection.FieldAttributes)definition.Attributes )); }
private InterpretedType NewIntepretedArrayType(NonRuntimeType elementType, GenericScope genericScope) { return(new InterpretedArrayType( elementType, new Lazy <Type[]>(() => GetArrayInterfaces(elementType, genericScope)), t => Empty <ILazyMember <MemberInfo> > .Array )); }
private Type ArrayTypeUncached(Type elementType, GenericScope genericScope) { if (TypeSupport.IsRuntime(elementType)) { return(elementType.MakeArrayType()); } return /*new ErasedWrapperType( * typeof(CilinObject).MakeArrayType(),*/ (NewIntepretedArrayType((NonRuntimeType)elementType, genericScope) /*)*/); }
public MethodBase Method(MethodReference reference, GenericScope genericScope) { Argument.NotNull(nameof(reference), reference); var definition = reference.Resolve(); if (definition == null) { throw new Exception($"Failed to resolve definition for method {reference}."); } var declaringType = Type(reference.DeclaringType, genericScope); genericScope = genericScope.With(definition.DeclaringType.GenericParameters, declaringType.GenericTypeArguments); return(Method(declaringType, definition, reference, genericScope)); }
public Type[] GetArrayInterfaces(NonRuntimeType elementType, GenericScope genericScope) { var elementTypeArray = new[] { elementType }; return(new Type[] { typeof(IEnumerable), typeof(ICollection), typeof(IList), GenericPathType(null, typeof(IEnumerable <>), TypeSupport.Definitions.IEnumerableOfT, elementTypeArray, false, genericScope), GenericPathType(null, typeof(IReadOnlyCollection <>), TypeSupport.Definitions.IReadOnlyCollectionOfT, elementTypeArray, false, genericScope), GenericPathType(null, typeof(ICollection <>), TypeSupport.Definitions.ICollectionOfT, elementTypeArray, false, genericScope), GenericPathType(null, typeof(IReadOnlyList <>), TypeSupport.Definitions.IReadOnlyListOfT, elementTypeArray, false, genericScope), GenericPathType(null, typeof(IList <>), TypeSupport.Definitions.IListOfT, elementTypeArray, false, genericScope) }); }
public Type Type(TypeReference reference, GenericScope genericScope) { Argument.NotNull(nameof(reference), reference); var parameter = reference as GenericParameter; if (reference is GenericParameter) { return(genericScope?.Resolve(parameter) ?? new Reflection.GenericParameterType(reference.Name)); } if (reference.IsArray) { var elementType = Type(reference.GetElementType(), genericScope); Type cached; if (_arrayTypeCache.TryGetValue(elementType, out cached)) { return(cached); } var array = ArrayTypeUncached(elementType, genericScope); _arrayTypeCache.Add(elementType, array); return(array); } var definition = reference.Resolve(); var definitionType = TypeByDefinition(definition); //genericScope = declaringType != null ? WithTypeScope(genericScope, definition.DeclaringType, declaringType) : genericScope; var declaringType = reference.DeclaringType != null?Type(reference.DeclaringType, genericScope) : null; if (reference.IsGenericInstance || HasGenericPath(declaringType)) { return(GenericPathType(declaringType, definitionType, definition, reference, genericScope)); } return(definitionType); }
private GenericDetails GenericDetails(IGenericParameterProvider definition, Type[] genericArguments, GenericScope genericScope) { var genericParameters = definition.GenericParameters.Count > 0 ? definition.GenericParameters.Select(p => Type(p, genericScope)).ToArray() : null; return(genericParameters != null || genericArguments != null ? new GenericDetails(genericArguments != null, genericParameters != null, genericArguments ?? genericParameters) : null); }
private ParameterInfo Parameter(ParameterDefinition definition, GenericScope genericScope) => new InterpretedParameter(Type(definition.ParameterType, genericScope));
private MethodBase MethodUncached(Type declaringType, MethodDefinition definition, MethodReference reference, Type[] genericArguments, GenericScope genericScope) { var interpretedType = declaringType as InterpretedType; if (ShouldBeRuntime(definition) && interpretedType == null) { var token = definition.MetadataToken.ToInt32(); return((MethodBase)declaringType .GetMembers() .First(m => m.MetadataToken == token)); } if (interpretedType == null) { throw InterpretedMemberInNonInterpretedType(reference, declaringType); } var parameters = reference.Parameters.Select(p => Parameter(p, genericScope)).ToArray(); var attributes = (System.Reflection.MethodAttributes)definition.Attributes; if (definition.IsConstructor) { return(new InterpretedConstructor(interpretedType, definition.Name, parameters, attributes, _invoker, definition)); } var overrides = definition.HasOverrides ? new Lazy <MethodInfo[]>(() => definition.Overrides.Select(o => (MethodInfo)Method(o, genericScope)).ToArray()) : LazyEmptyMethods; var returnType = Type(reference.ReturnType, genericScope); return(new InterpretedMethod( Module(definition.Module), interpretedType, reference.Name, returnType, parameters, overrides, attributes, GenericDetails(definition, genericArguments, genericScope), _invoker, definition )); }
private MethodBase Method(Type declaringType, MethodDefinition definition, MethodReference reference, GenericScope genericScope) { var genericArguments = Empty <Type> .Array; var generic = reference as GenericInstanceMethod; if (generic != null) { genericArguments = generic.GenericArguments.Select(a => Type(a, genericScope)).ToArray(); genericScope = genericScope.With(definition.GenericParameters, genericArguments); } var cacheKey = new MethodKey(declaringType, definition, genericArguments); MethodBase method; if (_methodCache.TryGetValue(cacheKey, out method)) { return(method); } method = MethodUncached(declaringType, definition, reference, genericArguments, genericScope); _methodCache[cacheKey] = method; return(method); }
private Type GenericPathType(Type declaringType, Type definitionType, TypeDefinition definition, TypeReference reference, GenericScope genericScope) { var generic = reference as GenericInstanceType; var arguments = generic != null ? new Type[generic.GenericArguments.Count] : System.Type.EmptyTypes; var allArgumentsAreRuntime = true; if (generic != null) { for (var i = 0; i < generic.GenericArguments.Count; i++) { var resolved = Type(generic.GenericArguments[i], genericScope); allArgumentsAreRuntime = allArgumentsAreRuntime && TypeSupport.IsRuntime(resolved); arguments[i] = resolved; } } var cacheKey = new GenericTypeKey(declaringType, definitionType, arguments); Type cached; if (_genericTypeCache.TryGetValue(cacheKey, out cached)) { return(cached); } var resultType = GenericPathTypeUncached(declaringType, definitionType, definition, arguments, allArgumentsAreRuntime, genericScope); _genericTypeCache.Add(cacheKey, resultType); return(GenericPathType(declaringType, definitionType, definition, arguments, allArgumentsAreRuntime, genericScope)); }
private Lazy <Type[]> LazyInterfacesOf(TypeDefinition definition, Lazy <Type> lazyBaseType, GenericScope genericScope) { return(new Lazy <Type[]>(() => { var baseInterfaces = lazyBaseType.Value?.GetInterfaces() ?? System.Type.EmptyTypes; if (baseInterfaces.Length == 0 && definition.Interfaces.Count == 0) { return System.Type.EmptyTypes; } var interfaces = new Type[baseInterfaces.Length + definition.Interfaces.Count]; Array.Copy(baseInterfaces, interfaces, baseInterfaces.Length); for (var i = 0; i < definition.Interfaces.Count; i++) { interfaces[baseInterfaces.Length + i] = Type(definition.Interfaces[i], genericScope); } return interfaces; })); }
private InterpretedType NewInterpretedGenericPathType(Type declaringType, Type definitionType, TypeDefinition definition, Type[] genericArguments, GenericScope genericScope) { genericScope = genericScope.With(definition.GenericParameters, genericArguments); var lazyBaseType = definition.BaseType != null ? new Lazy <Type>(() => Type(definition.BaseType, genericScope)) : LazyNullType; return(new InterpretedGenericPathType( definitionType, lazyBaseType, LazyInterfacesOf(definition, lazyBaseType, genericScope), t => LazyMembersOf(t, definition, genericScope), genericArguments )); }
private Type GenericPathTypeUncached(Type declaringType, Type definitionType, TypeDefinition definition, Type[] arguments, bool allArgumentsAreRuntime, GenericScope genericScope) { if (!TypeSupport.IsRuntime(definitionType)) { return(NewInterpretedGenericPathType(declaringType, definitionType, definition, arguments, genericScope)); } if (arguments.Length == 0) { return(declaringType.GetNestedType(definitionType.Name)); } if (allArgumentsAreRuntime) { return(definitionType.MakeGenericType(arguments)); } return(NewInterpretedGenericPathType(declaringType, definitionType, definition, arguments, genericScope)); //var erased = new Type[arguments.Length]; //for (var i = 0; i < arguments.Length; i++) { // erased[i] = TypeSupport.IsRuntime(arguments[i]) ? arguments[i] : typeof(CilinObject); //} //var erasedFull = definitionType.MakeGenericType(erased); //return new ErasedWrapperType(erasedFull, NewInterpretedGenericPathType(declaringType, definitionType, definition, arguments, genericScope)); }
private Type GenericPathType(Type declaringType, Type definitionType, TypeDefinition definition, Type[] arguments, bool allArgumentsAreRuntime, GenericScope genericScope) { var cacheKey = new GenericTypeKey(declaringType, definitionType, arguments); Type cached; if (_genericTypeCache.TryGetValue(cacheKey, out cached)) { return(cached); } var resultType = GenericPathTypeUncached(declaringType, definitionType, definition, arguments, allArgumentsAreRuntime, genericScope); _genericTypeCache.Add(cacheKey, resultType); return(resultType); }
private GenericScope(IReadOnlyCollection <GenericMap> map, GenericScope parent = null) { _parent = parent; _map = map; }
private IReadOnlyCollection <ILazyMember <MemberInfo> > LazyMembersOf(Type type, TypeDefinition definition, GenericScope genericScope) { var members = new List <ILazyMember <MemberInfo> >(); foreach (var nestedType in definition.NestedTypes) { members.Add(new LazyMember <Type>(nestedType.Name, true, nestedType.IsNestedPublic, () => Type(nestedType, genericScope))); } foreach (var method in definition.Methods) { if (method.IsConstructor) { members.Add(new LazyMember <ConstructorInfo>(method.Name, method.IsStatic, method.IsPublic, () => (ConstructorInfo)Method(type, method, method, genericScope))); } else { members.Add(new LazyMember <MethodInfo>(method.Name, method.IsStatic, method.IsPublic, () => (MethodInfo)Method(type, method, method, genericScope))); } } foreach (var field in definition.Fields) { members.Add(new LazyMember <FieldInfo>(field.Name, field.IsStatic, field.IsPublic, () => Field(field, genericScope))); } if (type.BaseType != null) { AddMembersFrom(type.BaseType, members); } if (type.IsInterface) { foreach (var @interface in type.GetInterfaces()) { AddMembersFrom(@interface, members); } } return(members); }