예제 #1
0
파일: Resolver.cs 프로젝트: ashmind/Cilin
        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
                       ));
        }
예제 #2
0
파일: Resolver.cs 프로젝트: ashmind/Cilin
 private InterpretedType NewIntepretedArrayType(NonRuntimeType elementType, GenericScope genericScope)
 {
     return(new InterpretedArrayType(
                elementType,
                new Lazy <Type[]>(() => GetArrayInterfaces(elementType, genericScope)),
                t => Empty <ILazyMember <MemberInfo> > .Array
                ));
 }
예제 #3
0
파일: Resolver.cs 프로젝트: ashmind/Cilin
        private Type ArrayTypeUncached(Type elementType, GenericScope genericScope)
        {
            if (TypeSupport.IsRuntime(elementType))
            {
                return(elementType.MakeArrayType());
            }

            return /*new ErasedWrapperType(
                    * typeof(CilinObject).MakeArrayType(),*/
                   (NewIntepretedArrayType((NonRuntimeType)elementType, genericScope)
                    /*)*/);
        }
예제 #4
0
파일: Resolver.cs 프로젝트: ashmind/Cilin
        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));
        }
예제 #5
0
파일: Resolver.cs 프로젝트: ashmind/Cilin
        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)
            });
        }
예제 #6
0
파일: Resolver.cs 프로젝트: ashmind/Cilin
        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);
        }
예제 #7
0
파일: Resolver.cs 프로젝트: ashmind/Cilin
        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);
        }
예제 #8
0
파일: Resolver.cs 프로젝트: ashmind/Cilin
 private ParameterInfo Parameter(ParameterDefinition definition, GenericScope genericScope)
 => new InterpretedParameter(Type(definition.ParameterType, genericScope));
예제 #9
0
파일: Resolver.cs 프로젝트: ashmind/Cilin
        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
                       ));
        }
예제 #10
0
파일: Resolver.cs 프로젝트: ashmind/Cilin
        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);
        }
예제 #11
0
파일: Resolver.cs 프로젝트: ashmind/Cilin
        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));
        }
예제 #12
0
파일: Resolver.cs 프로젝트: ashmind/Cilin
        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;
            }));
        }
예제 #13
0
파일: Resolver.cs 프로젝트: ashmind/Cilin
        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
                       ));
        }
예제 #14
0
파일: Resolver.cs 프로젝트: ashmind/Cilin
        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));
        }
예제 #15
0
파일: Resolver.cs 프로젝트: ashmind/Cilin
        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);
        }
예제 #16
0
 private GenericScope(IReadOnlyCollection <GenericMap> map, GenericScope parent = null)
 {
     _parent = parent;
     _map    = map;
 }
예제 #17
0
파일: Resolver.cs 프로젝트: ashmind/Cilin
        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);
        }