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); }
/// <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); } }
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()); }
public static Type MakeGenericType(Type baseType, Type[] types) { // emulate Nullable<T> if (baseType == typeof(Nullable <>)) { if (types.Length != 1) { ThrowHelper.ThrowArgumentException(ExceptionResource.WrongNumberOfArguments); } var ret = NullableReflection.GetNullableTFromUnterlyingType(types[0]); if (ret != null) { return(ret); } // can't create a nullable instance of non-predifined nullable, // because of all the compiler-voodoo around Nullables. return(null); } var expected = GetGenericArgumentCount(baseType); if (types.Length != expected) { throw new ArgumentOutOfRangeException("types", string.Format("exected {0} generic arguments, got {1} for type {2}", expected, types.Length, baseType.FullName)); } return(GenericInstanceFactory.GetOrMakeGenericInstanceType(baseType, types)); }
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; } }
public static Type GetReflectionSafeType(Type type, object obj) { if (!(obj is IGenericTypeDefinition)) // fast path { return(type); } // Note: If java had ephemerons, we could cache the return value. // Without ephemerons, this doesn't seem to be a good idea. // We could though create an extra field in each generic type // to hold the cached value. This would only pay off if // GetTypeReflectionSafe is actually called multiple times // on the same object. var info = GetOrCreateGenericsInfo(type); Field[] genericsFields = info.GenericInstanceFields; int length; if (genericsFields == null || (length = genericsFields.Length) == 0) { return(type); } Type[] genericParameters; if (info.GenericInstanceFieldIsTypeArray) { genericParameters = (Type[])genericsFields[0].Get(obj); return(GenericInstanceFactory.GetOrMakeGenericInstanceType(type, genericParameters)); } if (length > 4) { // This can not happen with the current compiler. genericParameters = genericsFields.Select(f => (Type)f.Get(obj)); return(GenericInstanceFactory.GetOrMakeGenericInstanceType(type, genericParameters)); } Type p1 = (Type)genericsFields[0].Get(obj); Type p2 = null, p3 = null, p4 = null; if (length > 1) { p2 = (Type)genericsFields[1].Get(obj); if (length > 2) { p3 = (Type)genericsFields[2].Get(obj); if (length > 3) { p4 = (Type)genericsFields[3].Get(obj); } } } return(GenericInstanceFactory.GetOrMakeGenericInstanceType(type, p1, p2, p3, p4)); }
/// <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()); }
/// <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))); }
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); }
/// <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); }
private static GenericsInfo CreateGenericsInfo(Type type) { var info = new GenericsInfo(); if (NullableReflection.TreatAsSystemNullableT(type)) { info.GenericArgumentCount = -1; } else if (GenericInstanceFactory.IsGenericInstanceType(type)) { info.GenericArgumentCount = -1; } else { var annotation = type.GetAnnotation <ITypeReflectionInfo>(typeof(ITypeReflectionInfo)); var args = annotation != null?annotation.GenericArgumentCount() : 0; if (args > 0) { var fieldNames = annotation.GenericArgumentsFields(); if (fieldNames.Length > 0) { var fields = type.JavaGetDeclaredFields(); info.GenericInstanceFields = fieldNames.Select(name => { var field = fields.FirstOrDefault(f => f.Name == name); field.IsAccessible = true; return(field); }); info.GenericInstanceFieldIsTypeArray = info.GenericInstanceFields.Length == 1 && info.GenericInstanceFields[0].Type == typeof(Type[]); } } info.GenericArgumentCount = args == 0 ? -1 : args; } return(info); }
public static Type GetGenericTypeDefinition(Type type) { // emulate Nullable<T> if (NullableReflection.TreatAsSystemNullableT(type)) { return(typeof(Nullable <>)); } // is generic proxy? var ret = GenericInstanceFactory.GetGenericTypeDefinition(type); if (ret != null) { return(ret); } // is generic type? just return itself. if (!IsGenericType(type)) { ThrowHelper.ThrowInvalidOperationException(ExceptionResource.NotAGenericType); } return(type); }
public static bool IsGenericType(Type type) { // Java generic type? // this call makes Json.NET deserialization about 2.5 times as slow. // If Java generics have any meanings to us, we would need to cache the // return value. //bool hasTypeParameters = type.GetTypeParameters().Length > 0; //if (hasTypeParameters) return true; // Nullable<T>? if (NullableReflection.TreatAsSystemNullableT(type)) { return(true); } // generic proxy? if (GenericInstanceFactory.IsGenericInstanceType(type)) { return(true); } // .NET generic type definition? return(IsGenericTypeDefinition(type)); }
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 }); }
/// <summary> /// return the generic type definition if, any or type itself. /// </summary> /// <param name="type"></param> /// <returns></returns> public static Type EnsureTypeDef(Type type) { return(GenericInstanceFactory.GetGenericTypeDefinition(type) ?? type); }
/// <summary> /// will never return null /// </summary> public static string GetName(Type type) { var baseType = GenericInstanceFactory.GetGenericTypeDefinition(type) ?? type; return(baseType.GetSimpleName().Replace(GenericTickChar, '`')); }
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); }