Exemple #1
0
        public static FieldInfo GetField(Type type, string name, BindingFlags flags)
        {
            while (type != null && type != typeof(object))
            {
                var typeInfo = GenericInstanceFactory.GetGenericTypeInfo(type);
                var typeDef  = typeInfo != null ? typeInfo.TypeDefinition : type;

                // NOTE: doesn't throw AmbiguousMatchException
                var fields = typeDef.JavaGetDeclaredFields();

                for (int i = 0; i < fields.Length; ++i)
                {
                    if (fields[i].Name != name)
                    {
                        continue;
                    }
                    if (!TypeHelper.Matches(fields[i].Modifiers, flags))
                    {
                        continue;
                    }
                    return(new FieldInfo(fields[i], type));
                }

                if ((flags & BindingFlags.DeclaredOnly) != 0)
                {
                    break;
                }

                type = type.BaseType;
            }
            return(null);
        }
Exemple #2
0
        public static IEnumerable <MethodInfo> GetMethods(Type type, BindingFlags flags)
        {
            while (type != null)
            {
                GenericTypeInfo typeId = GenericInstanceFactory.GetGenericTypeInfo(type);

                var typeDef = typeId != null ? typeId.TypeDefinition : type;

                string possibleExplicitInterfacePrefix = typeDef.JavaIsInterface() ? typeDef.GetSimpleName() + "_" : null;

                var methods = typeDef.JavaGetDeclaredMethods();
                for (int i = 0; i < methods.Length; ++i)
                {
                    if (!TypeHelper.Matches(methods[i].Modifiers, flags))
                    {
                        continue;
                    }

                    yield return(new MethodInfo(methods[i], type, possibleExplicitInterfacePrefix));
                }

                if ((flags & BindingFlags.DeclaredOnly) != 0)
                {
                    break;
                }

                type = type.BaseType;
            }
        }
Exemple #3
0
        public static FieldInfo[] GetFields(Type type, BindingFlags flags)
        {
            List <FieldInfo> ret = new List <FieldInfo>();

            while (type != null && type != typeof(object))
            {
                GenericTypeInfo typeId = GenericInstanceFactory.GetGenericTypeInfo(type);

                var typeDef = typeId != null ? typeId.TypeDefinition : type;
                var fields  = typeDef.JavaGetDeclaredFields();

                int startIndex = ret.Count;

                for (int i = 0; i < fields.Length; ++i)
                {
                    if (!TypeHelper.Matches(fields[i].Modifiers, flags))
                    {
                        continue;
                    }

                    ret.Add(new FieldInfo(fields[i], type));
                }

                ReorderFields(typeDef, startIndex, ret);

                if ((flags & BindingFlags.DeclaredOnly) != 0)
                {
                    break;
                }

                type = type.BaseType;
            }
            return(ret.ToArray());
        }
Exemple #4
0
        /// <summary>
        /// will return null if not a generic proxy type
        /// </summary>
        public static ConstructorInfo GetConstructor(Type type, Type[] parameters)
        {
            var typeInfo = GenericInstanceFactory.GetGenericTypeInfo(type);

            if (typeInfo == null)
            {
                return(null);
            }

            Type[] trueParameters = typeInfo.AddGenericParameterTypes(parameters);

            for (int i = 0; i < parameters.Length; ++i)
            {
                trueParameters[i] = EnsureTypeDef(parameters[i]);
            }

            try
            {
                var javaContructor = typeInfo.TypeDefinition.JavaGetConstructor(trueParameters);
                return(new GenericInstanceConstructorInfo(javaContructor, type, typeInfo));
            }
            catch (NoSuchMethodException)
            {
                return(null);
            }
        }
Exemple #5
0
        /// <summary>
        /// will never return null
        /// </summary>
        public static string GetFullName(Type type)
        {
            var typeInfo = GenericInstanceFactory.GetGenericTypeInfo(type);

            if (typeInfo == null)
            {
                return(type.JavaGetName().Replace(GenericTickChar, '`'));
            }

            return(typeInfo.GetFullName());
        }
Exemple #6
0
        /// <summary>
        /// will return null if not a generic proxy type
        /// </summary>
        public static ConstructorInfo[] GetConstructors(Type type, BindingFlags flags)
        {
            var typeInfo = GenericInstanceFactory.GetGenericTypeInfo(type);

            if (typeInfo == null)
            {
                return(null);
            }

            return(typeInfo.TypeDefinition.JavaGetDeclaredConstructors()
                   .Select(p => (ConstructorInfo) new GenericInstanceConstructorInfo(p, type, typeInfo))
                   .Where(ctor => Type.IsMatch(ctor, flags)));
        }
Exemple #7
0
        public static Type[] GetGenericArguments(Type type)
        {
            Type[] ret;

            // generic instance proxy?
            var genericTypeInfo = GenericInstanceFactory.GetGenericTypeInfo(type);

            if (genericTypeInfo != null)
            {
                return((Type[])genericTypeInfo.AddOrGetGenericParameters(createTypeArray: true));
            }

            // Nullable<T>?
            Type nullableUnderlying = NullableReflection.GetUnderlyingType(type);

            if (nullableUnderlying != null)
            {
                return(new[] { nullableUnderlying });
            }

            // java generic type?
            var javaTypeParam = type.GetTypeParameters();

            if (javaTypeParam.Length != 0)
            {
                // java generic type. provide some emulation.
                ret = new Type[javaTypeParam.Length];
                for (int i = 0; i < javaTypeParam.Length; ++i)
                {
                    ret[i] = typeof(object);
                }
                return(ret);
            }

            var info = GetOrCreateGenericsInfo(type);

            if (info.GenericArgumentCount > 0)
            {
                // generic definition? We can only return the number of objects.
                ret = new Type[info.GenericArgumentCount];
                for (int i = 0; i < ret.Length; ++i)
                {
                    ret[i] = typeof(object);
                }
                return(ret);
            }

            throw new InvalidOperationException("not a generic type: " + type.FullName);
        }
Exemple #8
0
        /// <summary>
        /// will never return null.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static Type GetBaseType(Type type)
        {
            if (type == typeof(object))
            {
                return(null);
            }

            var genericTypeInfo = GenericInstanceFactory.GetGenericTypeInfo(type);

            if (genericTypeInfo == null)
            {
                return(type.GetSuperclass());
            }

            var baseType = BaseTypeCache.Get(type);

            if (baseType != null)
            {
                return(baseType == typeof(NullBaseType) ? null : baseType);
            }

            var typeDef = genericTypeInfo.TypeDefinition;

            baseType = typeDef.GetSuperclass();

            var annotation = typeDef.GetAnnotation <ITypeReflectionInfo>(typeof(ITypeReflectionInfo));

            if (annotation != null)
            {
                var def = annotation.GenericDefinitions().Select(DefinitionParser.Parse);
                if (def.Length > 0)
                {
                    baseType = ToMatchedGenericInstanceType(baseType, type, def);
                }
            }

            BaseTypeCache.PutIfAbsent(type, baseType ?? typeof(NullBaseType));
            return(baseType);
        }
Exemple #9
0
        private static InheritanceInfo CreateInheritanceInfo(Type type)
        {
            LinkedHashSet <Type> intf = new LinkedHashSet <Type>();

            Java.Util.HashSet <Type> baseTypes = new Java.Util.HashSet <Type>();
            baseTypes.Add(typeof(object));

            // Note that JavaGetInterfaces will only return interfaces declared by the current type,
            // while .NET returns a flattened map of all interfaces.
            // http://stackoverflow.com/questions/6616055/get-all-derived-interfaces-of-a-class
            // http://stackoverflow.com/questions/9793242/type-getinterfaces-for-declared-interfaces-only

            Java.Util.IQueue <Type> toVisit = new Java.Util.LinkedList <Type>();
            toVisit.Add(type);

            while (toVisit.Peek() != null)
            {
                var currentType = toVisit.Poll();

                var gti = GenericInstanceFactory.GetGenericTypeInfo(currentType);

                bool isInterface = gti != null?gti.TypeDefinition.JavaIsInterface() : currentType.JavaIsInterface();

                if (!isInterface)
                {
                    var baseType = currentType.BaseType;
                    if (baseType != null && baseType != typeof(object))
                    {
                        toVisit.Add(baseType);
                        baseTypes.Add(baseType);
                    }
                }

                if (gti == null)
                {
                    AddInterfaces(currentType.JavaGetInterfaces(), intf, toVisit);
                    continue;
                }

                var typeDef    = gti.TypeDefinition;
                var interfaces = typeDef.JavaGetInterfaces();

                var genericInstanceClass = typeDef.GetAnnotation <ITypeReflectionInfo>(typeof(ITypeReflectionInfo));
                if (genericInstanceClass == null)
                {
                    AddInterfaces(interfaces, intf, toVisit);
                    continue;
                }

                var def = genericInstanceClass.GenericDefinitions().Select(DefinitionParser.Parse);

                if (def.Length == 0)
                {
                    AddInterfaces(interfaces, intf, toVisit);
                    continue;
                }

                for (int i = 0; i < interfaces.Length; ++i)
                {
                    interfaces[i] = ToMatchedGenericInstanceType(interfaces[i], currentType, def);
                }

                AddInterfaces(interfaces, intf, toVisit);
            }

            return(new InheritanceInfo
            {
                Interfaces = new JavaCollectionWrapper <Type>(intf).ToArray(),
                InterfacesSet = new Java.Util.HashSet <Type>(intf),
                BaseTypes = baseTypes
            });
        }
Exemple #10
0
        public static Type ToGenericInstanceType(Type perceivedType, Type parentType, GenericDefinition m)
        {
            // is a specialized type defined?
            var genericInstanceType = m.GenericInstanceType;

            if (genericInstanceType != null)
            {
                return(genericInstanceType);
            }

            int genericParameter = -1;
            var genericArguments = m.GenericArguments;

            // is a generic type definition class defined?
            var genericTypeDef = m.GenericTypeDefinition;

            if (genericTypeDef == null)
            {
                genericTypeDef   = perceivedType;
                genericParameter = m.GenericParameter;
            }

            // retrieve generic parameters if required.
            GenericTypeInfo parentGenericArguments     = null;
            bool            needParentGenericArguments = genericParameter >= 0 ||
                                                         genericArguments.Any(a => a.FixedType == null);

            if (needParentGenericArguments)
            {
                parentGenericArguments = GenericInstanceFactory.GetGenericTypeInfo(parentType);

                if (parentGenericArguments == null)
                {
                    // Can either happen when the generics reflection annotations where not preserved
                    // (i.e. a bug),  when the user did not call GetTypeReflectionSafe() on an object,
                    // or when requesting generics info not for an instance type, e.g. typeof(List<>).
                    // As the second case can be difficult to debug, we emit a warning. TODO: we should
                    // probably not emit a warning when the user code runs in release mode.
                    Log.W("dot42", string.Format("Unable to reconstruct generic type definition for type {0}, parent type {1}. Did you use obj.GetTypeReflectionSafe()? If you are reflecting on an open generic type, i.e. typeof(List<>) you can ignore this warning.", perceivedType.FullName, parentType.FullName));
                    return(genericTypeDef);
                }
            }


            if (genericParameter != -1)
            {
                // ReSharper disable once PossibleNullReferenceException
                genericTypeDef = parentGenericArguments.GetGenericParameter(genericParameter);
            }

            if (genericArguments != null && genericArguments.Length > 0)
            {
                Type[] genericParameters = new Type[genericArguments.Length];

                for (int i = 0; i < genericArguments.Length; ++i)
                {
                    Type resolvedArg;
                    var  arg = genericArguments[i];
                    if (arg.NestedType != null)
                    {
                        resolvedArg = ToGenericInstanceType(typeof(object), parentType, arg.NestedType);
                    }
                    else if (arg.FixedType != null)
                    {
                        resolvedArg = arg.FixedType;
                    }
                    else
                    {
                        // must be an index
                        // ReSharper disable once PossibleNullReferenceException
                        resolvedArg = parentGenericArguments.GetGenericParameter(arg.ContainingTypeArgumentIndex);
                    }

                    genericParameters[i] = resolvedArg;
                }

                return(GenericInstanceFactory.GetOrMakeGenericInstanceType(genericTypeDef, genericParameters));
            }

            // return the type.
            return(genericTypeDef);
        }