Fix type not being retrievable when field is null

This commit is contained in:
TheComputerGeek2 2017-02-16 10:42:45 -08:00
parent 1f2aecccb1
commit 94a950317a
2 changed files with 51 additions and 6 deletions

View File

@ -4,7 +4,6 @@ import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import com.massivecraft.massivecore.collections.ExceptionSet; import com.massivecraft.massivecore.collections.ExceptionSet;
@ -127,28 +126,28 @@ public class RegistryType
{ {
if (fieldType instanceof ParameterizedType) if (fieldType instanceof ParameterizedType)
{ {
Class<?> fieldClass = field.getType(); Class<?> fieldClass = field == null ? null : field.getType();
List<Type<?>> innerTypes; List<Type<?>> innerTypes;
if (List.class.isAssignableFrom(fieldClass)) if (ReflectionUtil.isRawTypeAssignableFromAny(List.class, fieldType, fieldClass))
{ {
innerTypes = getInnerTypes(field, fieldType, 1); innerTypes = getInnerTypes(field, fieldType, 1);
return TypeList.get(innerTypes.get(0)); return TypeList.get(innerTypes.get(0));
} }
if (Set.class.isAssignableFrom(fieldClass)) if (ReflectionUtil.isRawTypeAssignableFromAny(Set.class, fieldType, fieldClass))
{ {
innerTypes = getInnerTypes(field, fieldType, 1); innerTypes = getInnerTypes(field, fieldType, 1);
return TypeSet.get(innerTypes.get(0)); return TypeSet.get(innerTypes.get(0));
} }
if (Entry.class.isAssignableFrom(fieldClass)) if (ReflectionUtil.isRawTypeAssignableFromAny(Map.Entry.class, fieldType, fieldClass))
{ {
innerTypes = getInnerTypes(field, fieldType, 2); innerTypes = getInnerTypes(field, fieldType, 2);
return TypeEntry.get(innerTypes.get(0), innerTypes.get(1)); return TypeEntry.get(innerTypes.get(0), innerTypes.get(1));
} }
if (Map.class.isAssignableFrom(fieldClass)) if (ReflectionUtil.isRawTypeAssignableFromAny(Map.class, fieldType, fieldClass))
{ {
innerTypes = getInnerTypes(field, fieldType, 2); innerTypes = getInnerTypes(field, fieldType, 2);
return TypeMap.get(innerTypes.get(0), innerTypes.get(1)); return TypeMap.get(innerTypes.get(0), innerTypes.get(1));

View File

@ -3,9 +3,13 @@ package com.massivecraft.massivecore.util;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -488,4 +492,46 @@ public class ReflectionUtil
} }
} }
// -------------------------------------------- //
// TYPE CHECKS
// -------------------------------------------- //
public static boolean isRawTypeAssignableFromAny(Type goal, Type... subjects)
{
// Cache this value since it will save us calculations
Class<?> classGoal = classify(goal);
for (Type t: subjects)
{
if (isRawTypeAssignableFrom(classGoal, t)) return true;
}
return false;
}
public static boolean isRawTypeAssignableFrom(Type a, Type b)
{
if (a == null || b == null) return false;
// Yes, this is a different sense of "Classifying"
Class<?> classifiedA = classify(a);
Class<?> classifiedB = classify(b);
// In case one of the methods failed to retrieve a class
if (classifiedA == null || classifiedB == null) return a.equals(b);
return classifiedA.isAssignableFrom(classifiedB);
}
private static Class<?> classify(Type type)
{
// Use loop structure rather than recursion to avoid stack size issues
while (!(type instanceof Class))
{
// Check for parameterized type
if (!(type instanceof ParameterizedType)) return null;
type = ((ParameterizedType) type).getRawType();
}
return (Class) type;
}
} }