Diff
checker
Texto
Texto
Imágenes
Documentos
Excel
Carpetas
Legal
Enterprise
Aplicación de escritorio
Precios
Iniciar sesión
Descargar Diffchecker Desktop
Comparar texto
Encuentra la diferencia entre dos archivos de texto
Herramientas
Historial
Editor live
Ocultar sin cambios
Sin ajuste de línea
Vista
Dividido
Unificado
Nivel de detalle
Inteligente
Palabra
Letra
Resaltado de sintaxis
Elegir sintaxis
Ignorar
Transformar texto
Ir al primer cambio
Editar entrada
Diffchecker Desktop
La forma más segura de usar Diffchecker. ¡Obtén la app de Diffchecker Desktop: tus diffs nunca salen de tu computadora!
Obtener Desktop
Untitled diff
Creado
hace 9 años
El diff nunca expira
Borrar
Exportar
Compartir
Explicar
0 eliminaciones
Líneas
Total
Eliminado
Caracteres
Total
Eliminado
Para continuar usando esta función, actualice a
Diff
checker
Pro
Ver precios
375 líneas
Copiar todo
5 adiciones
Líneas
Total
Añadido
Caracteres
Total
Añadido
Para continuar usando esta función, actualice a
Diff
checker
Pro
Ver precios
377 líneas
Copiar todo
/*
/*
* Minecraft Forge
* Minecraft Forge
* Copyright (c) 2016.
* Copyright (c) 2016.
*
*
* This library is free software; you can redistribute it and/or
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* License as published by the Free Software Foundation version 2.1
* of the License.
* of the License.
*
*
* This library is distributed in the hope that it will be useful,
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* Lesser General Public License for more details.
*
*
* You should have received a copy of the GNU Lesser General Public
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
*/
package net.minecraftforge.common.util;
package net.minecraftforge.common.util;
import java.lang.reflect.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.*;
Copiar
Copiado
Copiar
Copiado
import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
import com.google.common.collect.Lists;
import net.minecraftforge.fml.common.EnhancedRuntimeException;
import net.minecraftforge.fml.common.EnhancedRuntimeException;
import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.common.FMLLog;
import net.minecraft.block.BlockPressurePlate.Sensitivity;
import net.minecraft.block.BlockPressurePlate.Sensitivity;
import net.minecraft.block.material.Material;
import net.minecraft.block.material.Material;
import net.minecraft.enchantment.EnumEnchantmentType;
import net.minecraft.enchantment.EnumEnchantmentType;
import net.minecraft.entity.EnumCreatureAttribute;
import net.minecraft.entity.EnumCreatureAttribute;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.item.EntityPainting.EnumArt;
import net.minecraft.entity.item.EntityPainting.EnumArt;
import net.minecraft.entity.player.EntityPlayer.SleepResult;
import net.minecraft.entity.player.EntityPlayer.SleepResult;
import net.minecraft.item.EnumAction;
import net.minecraft.item.EnumAction;
import net.minecraft.item.EnumRarity;
import net.minecraft.item.EnumRarity;
Copiar
Copiado
Copiar
Copiado
import net.minecraft.item.Item;
import net.minecraft.item.Item.ToolMaterial;
import net.minecraft.item.Item.ToolMaterial;
import net.minecraft.item.ItemArmor.ArmorMaterial;
import net.minecraft.item.ItemArmor.ArmorMaterial;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.EnumSkyBlock;
import net.minecraft.world.EnumSkyBlock;
import net.minecraft.world.gen.structure.StructureStrongholdPieces.Stronghold.Door;
import net.minecraft.world.gen.structure.StructureStrongholdPieces.Stronghold.Door;
import net.minecraftforge.classloading.FMLForgePlugin;
import net.minecraftforge.classloading.FMLForgePlugin;
public class EnumHelper
public class EnumHelper
{
{
private static Object reflectionFactory = null;
private static Object reflectionFactory = null;
private static Method newConstructorAccessor = null;
private static Method newConstructorAccessor = null;
private static Method newInstance = null;
private static Method newInstance = null;
private static Method newFieldAccessor = null;
private static Method newFieldAccessor = null;
private static Method fieldAccessorSet = null;
private static Method fieldAccessorSet = null;
private static boolean isSetup = false;
private static boolean isSetup = false;
//Some enums are decompiled with extra arguments, so lets check for that
//Some enums are decompiled with extra arguments, so lets check for that
private static Class<?>[][] commonTypes =
private static Class<?>[][] commonTypes =
{
{
{EnumAction.class},
{EnumAction.class},
{ArmorMaterial.class, String.class, int.class, int[].class, int.class, SoundEvent.class, float.class},
{ArmorMaterial.class, String.class, int.class, int[].class, int.class, SoundEvent.class, float.class},
{EnumArt.class, String.class, int.class, int.class, int.class, int.class},
{EnumArt.class, String.class, int.class, int.class, int.class, int.class},
{EnumCreatureAttribute.class},
{EnumCreatureAttribute.class},
{EnumCreatureType.class, Class.class, int.class, Material.class, boolean.class, boolean.class},
{EnumCreatureType.class, Class.class, int.class, Material.class, boolean.class, boolean.class},
{Door.class},
{Door.class},
Copiar
Copiado
Copiar
Copiado
{EnumEnchantmentType.class
},
{EnumEnchantmentType.class
, Predicate.class
},
{Sensitivity.class},
{Sensitivity.class},
{RayTraceResult.Type.class},
{RayTraceResult.Type.class},
{EnumSkyBlock.class, int.class},
{EnumSkyBlock.class, int.class},
{SleepResult.class},
{SleepResult.class},
{ToolMaterial.class, int.class, int.class, float.class, float.class, int.class},
{ToolMaterial.class, int.class, int.class, float.class, float.class, int.class},
{EnumRarity.class, TextFormatting.class, String.class}
{EnumRarity.class, TextFormatting.class, String.class}
};
};
public static EnumAction addAction(String name)
public static EnumAction addAction(String name)
{
{
return addEnum(EnumAction.class, name);
return addEnum(EnumAction.class, name);
}
}
public static ArmorMaterial addArmorMaterial(String name, String textureName, int durability, int[] reductionAmounts, int enchantability, SoundEvent soundOnEquip, float toughness)
public static ArmorMaterial addArmorMaterial(String name, String textureName, int durability, int[] reductionAmounts, int enchantability, SoundEvent soundOnEquip, float toughness)
{
{
return addEnum(ArmorMaterial.class, name, textureName, durability, reductionAmounts, enchantability, soundOnEquip, toughness);
return addEnum(ArmorMaterial.class, name, textureName, durability, reductionAmounts, enchantability, soundOnEquip, toughness);
}
}
public static EnumArt addArt(String name, String tile, int sizeX, int sizeY, int offsetX, int offsetY)
public static EnumArt addArt(String name, String tile, int sizeX, int sizeY, int offsetX, int offsetY)
{
{
return addEnum(EnumArt.class, name, tile, sizeX, sizeY, offsetX, offsetY);
return addEnum(EnumArt.class, name, tile, sizeX, sizeY, offsetX, offsetY);
}
}
public static EnumCreatureAttribute addCreatureAttribute(String name)
public static EnumCreatureAttribute addCreatureAttribute(String name)
{
{
return addEnum(EnumCreatureAttribute.class, name);
return addEnum(EnumCreatureAttribute.class, name);
}
}
public static EnumCreatureType addCreatureType(String name, Class<?> typeClass, int maxNumber, Material material, boolean peaceful, boolean animal)
public static EnumCreatureType addCreatureType(String name, Class<?> typeClass, int maxNumber, Material material, boolean peaceful, boolean animal)
{
{
return addEnum(EnumCreatureType.class, name, typeClass, maxNumber, material, peaceful, animal);
return addEnum(EnumCreatureType.class, name, typeClass, maxNumber, material, peaceful, animal);
}
}
public static Door addDoor(String name)
public static Door addDoor(String name)
{
{
return addEnum(Door.class, name);
return addEnum(Door.class, name);
}
}
Copiar
Copiado
Copiar
Copiado
public static EnumEnchantmentType addEnchantmentType(String name
)
public static EnumEnchantmentType addEnchantmentType(String name
, Predicate<Item> delegate
)
{
{
Copiar
Copiado
Copiar
Copiado
return addEnum(EnumEnchantmentType.class, name
);
return addEnum(EnumEnchantmentType.class, name
, delegate
);
}
}
public static Sensitivity addSensitivity(String name)
public static Sensitivity addSensitivity(String name)
{
{
return addEnum(Sensitivity.class, name);
return addEnum(Sensitivity.class, name);
}
}
public static RayTraceResult.Type addMovingObjectType(String name)
public static RayTraceResult.Type addMovingObjectType(String name)
{
{
return addEnum(RayTraceResult.Type.class, name);
return addEnum(RayTraceResult.Type.class, name);
}
}
public static EnumSkyBlock addSkyBlock(String name, int lightValue)
public static EnumSkyBlock addSkyBlock(String name, int lightValue)
{
{
return addEnum(EnumSkyBlock.class, name, lightValue);
return addEnum(EnumSkyBlock.class, name, lightValue);
}
}
public static SleepResult addStatus(String name)
public static SleepResult addStatus(String name)
{
{
return addEnum(SleepResult.class, name);
return addEnum(SleepResult.class, name);
}
}
public static ToolMaterial addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, float damage, int enchantability)
public static ToolMaterial addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, float damage, int enchantability)
{
{
return addEnum(ToolMaterial.class, name, harvestLevel, maxUses, efficiency, damage, enchantability);
return addEnum(ToolMaterial.class, name, harvestLevel, maxUses, efficiency, damage, enchantability);
}
}
public static EnumRarity addRarity(String name, TextFormatting color, String displayName)
public static EnumRarity addRarity(String name, TextFormatting color, String displayName)
{
{
return addEnum(EnumRarity.class, name, color, displayName);
return addEnum(EnumRarity.class, name, color, displayName);
}
}
private static void setup()
private static void setup()
{
{
if (isSetup)
if (isSetup)
{
{
return;
return;
}
}
try
try
{
{
Method getReflectionFactory = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("getReflectionFactory");
Method getReflectionFactory = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("getReflectionFactory");
reflectionFactory = getReflectionFactory.invoke(null);
reflectionFactory = getReflectionFactory.invoke(null);
newConstructorAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newConstructorAccessor", Constructor.class);
newConstructorAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newConstructorAccessor", Constructor.class);
newInstance = Class.forName("sun.reflect.ConstructorAccessor").getDeclaredMethod("newInstance", Object[].class);
newInstance = Class.forName("sun.reflect.ConstructorAccessor").getDeclaredMethod("newInstance", Object[].class);
newFieldAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newFieldAccessor", Field.class, boolean.class);
newFieldAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newFieldAccessor", Field.class, boolean.class);
fieldAccessorSet = Class.forName("sun.reflect.FieldAccessor").getDeclaredMethod("set", Object.class, Object.class);
fieldAccessorSet = Class.forName("sun.reflect.FieldAccessor").getDeclaredMethod("set", Object.class, Object.class);
}
}
catch (Exception e)
catch (Exception e)
{
{
e.printStackTrace();
e.printStackTrace();
}
}
isSetup = true;
isSetup = true;
}
}
/*
/*
* Everything below this is found at the site below, and updated to be able to compile in Eclipse/Java 1.6+
* Everything below this is found at the site below, and updated to be able to compile in Eclipse/Java 1.6+
* Also modified for use in decompiled code.
* Also modified for use in decompiled code.
* Found at: http://niceideas.ch/roller2/badtrash/entry/java_create_enum_instances_dynamically
* Found at: http://niceideas.ch/roller2/badtrash/entry/java_create_enum_instances_dynamically
*/
*/
private static Object getConstructorAccessor(Class<?> enumClass, Class<?>[] additionalParameterTypes) throws Exception
private static Object getConstructorAccessor(Class<?> enumClass, Class<?>[] additionalParameterTypes) throws Exception
{
{
Class<?>[] parameterTypes = new Class[additionalParameterTypes.length + 2];
Class<?>[] parameterTypes = new Class[additionalParameterTypes.length + 2];
parameterTypes[0] = String.class;
parameterTypes[0] = String.class;
parameterTypes[1] = int.class;
parameterTypes[1] = int.class;
System.arraycopy(additionalParameterTypes, 0, parameterTypes, 2, additionalParameterTypes.length);
System.arraycopy(additionalParameterTypes, 0, parameterTypes, 2, additionalParameterTypes.length);
return newConstructorAccessor.invoke(reflectionFactory, enumClass.getDeclaredConstructor(parameterTypes));
return newConstructorAccessor.invoke(reflectionFactory, enumClass.getDeclaredConstructor(parameterTypes));
}
}
private static < T extends Enum<? >> T makeEnum(Class<T> enumClass, String value, int ordinal, Class<?>[] additionalTypes, Object[] additionalValues) throws Exception
private static < T extends Enum<? >> T makeEnum(Class<T> enumClass, String value, int ordinal, Class<?>[] additionalTypes, Object[] additionalValues) throws Exception
{
{
Object[] params = new Object[additionalValues.length + 2];
Object[] params = new Object[additionalValues.length + 2];
params[0] = value;
params[0] = value;
params[1] = ordinal;
params[1] = ordinal;
System.arraycopy(additionalValues, 0, params, 2, additionalValues.length);
System.arraycopy(additionalValues, 0, params, 2, additionalValues.length);
return enumClass.cast(newInstance.invoke(getConstructorAccessor(enumClass, additionalTypes), new Object[] {params}));
return enumClass.cast(newInstance.invoke(getConstructorAccessor(enumClass, additionalTypes), new Object[] {params}));
}
}
public static void setFailsafeFieldValue(Field field, Object target, Object value) throws Exception
public static void setFailsafeFieldValue(Field field, Object target, Object value) throws Exception
{
{
field.setAccessible(true);
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
Object fieldAccessor = newFieldAccessor.invoke(reflectionFactory, field, false);
Object fieldAccessor = newFieldAccessor.invoke(reflectionFactory, field, false);
fieldAccessorSet.invoke(fieldAccessor, target, value);
fieldAccessorSet.invoke(fieldAccessor, target, value);
}
}
private static void blankField(Class<?> enumClass, String fieldName) throws Exception
private static void blankField(Class<?> enumClass, String fieldName) throws Exception
{
{
for (Field field : Class.class.getDeclaredFields())
for (Field field : Class.class.getDeclaredFields())
{
{
if (field.getName().contains(fieldName))
if (field.getName().contains(fieldName))
{
{
field.setAccessible(true);
field.setAccessible(true);
setFailsafeFieldValue(field, enumClass, null);
setFailsafeFieldValue(field, enumClass, null);
break;
break;
}
}
}
}
}
}
private static void cleanEnumCache(Class<?> enumClass) throws Exception
private static void cleanEnumCache(Class<?> enumClass) throws Exception
{
{
blankField(enumClass, "enumConstantDirectory");
blankField(enumClass, "enumConstantDirectory");
blankField(enumClass, "enumConstants");
blankField(enumClass, "enumConstants");
}
}
private static <T extends Enum<? >> T addEnum(Class<T> enumType, String enumName, Object... paramValues)
private static <T extends Enum<? >> T addEnum(Class<T> enumType, String enumName, Object... paramValues)
{
{
setup();
setup();
return addEnum(commonTypes, enumType, enumName, paramValues);
return addEnum(commonTypes, enumType, enumName, paramValues);
}
}
protected static <T extends Enum<? >> T addEnum(Class<?>[][] map, Class<T> enumType, String enumName, Object... paramValues)
protected static <T extends Enum<? >> T addEnum(Class<?>[][] map, Class<T> enumType, String enumName, Object... paramValues)
{
{
for (Class<?>[] lookup : map)
for (Class<?>[] lookup : map)
{
{
if (lookup[0] == enumType)
if (lookup[0] == enumType)
{
{
Class<?>[] paramTypes = new Class<?>[lookup.length - 1];
Class<?>[] paramTypes = new Class<?>[lookup.length - 1];
if (paramTypes.length > 0)
if (paramTypes.length > 0)
{
{
System.arraycopy(lookup, 1, paramTypes, 0, paramTypes.length);
System.arraycopy(lookup, 1, paramTypes, 0, paramTypes.length);
}
}
return addEnum(enumType, enumName, paramTypes, paramValues);
return addEnum(enumType, enumName, paramTypes, paramValues);
}
}
}
}
return null;
return null;
}
}
//Tests an enum is compatible with these args, throws an error if not.
//Tests an enum is compatible with these args, throws an error if not.
public static void testEnum(Class<? extends Enum<?>> enumType, Class<?>[] paramTypes)
public static void testEnum(Class<? extends Enum<?>> enumType, Class<?>[] paramTypes)
{
{
addEnum(true, enumType, null, paramTypes, (Object[])null);
addEnum(true, enumType, null, paramTypes, (Object[])null);
}
}
public static <T extends Enum<? >> T addEnum(Class<T> enumType, String enumName, Class<?>[] paramTypes, Object... paramValues)
public static <T extends Enum<? >> T addEnum(Class<T> enumType, String enumName, Class<?>[] paramTypes, Object... paramValues)
{
{
return addEnum(false, enumType, enumName, paramTypes, paramValues);
return addEnum(false, enumType, enumName, paramTypes, paramValues);
}
}
@SuppressWarnings({ "unchecked", "serial" })
@SuppressWarnings({ "unchecked", "serial" })
private static <T extends Enum<? >> T addEnum(boolean test, final Class<T> enumType, String enumName, final Class<?>[] paramTypes, Object[] paramValues)
private static <T extends Enum<? >> T addEnum(boolean test, final Class<T> enumType, String enumName, final Class<?>[] paramTypes, Object[] paramValues)
{
{
if (!isSetup)
if (!isSetup)
{
{
setup();
setup();
}
}
Field valuesField = null;
Field valuesField = null;
Field[] fields = enumType.getDeclaredFields();
Field[] fields = enumType.getDeclaredFields();
for (Field field : fields)
for (Field field : fields)
{
{
String name = field.getName();
String name = field.getName();
if (name.equals("$VALUES") || name.equals("ENUM$VALUES")) //Added 'ENUM$VALUES' because Eclipse's internal compiler doesn't follow standards
if (name.equals("$VALUES") || name.equals("ENUM$VALUES")) //Added 'ENUM$VALUES' because Eclipse's internal compiler doesn't follow standards
{
{
valuesField = field;
valuesField = field;
break;
break;
}
}
}
}
int flags = (FMLForgePlugin.RUNTIME_DEOBF ? Modifier.PUBLIC : Modifier.PRIVATE) | Modifier.STATIC | Modifier.FINAL | 0x1000 /*SYNTHETIC*/;
int flags = (FMLForgePlugin.RUNTIME_DEOBF ? Modifier.PUBLIC : Modifier.PRIVATE) | Modifier.STATIC | Modifier.FINAL | 0x1000 /*SYNTHETIC*/;
if (valuesField == null)
if (valuesField == null)
{
{
String valueType = String.format("[L%s;", enumType.getName().replace('.', '/'));
String valueType = String.format("[L%s;", enumType.getName().replace('.', '/'));
for (Field field : fields)
for (Field field : fields)
{
{
if ((field.getModifiers() & flags) == flags &&
if ((field.getModifiers() & flags) == flags &&
field.getType().getName().replace('.', '/').equals(valueType)) //Apparently some JVMs return .'s and some don't..
field.getType().getName().replace('.', '/').equals(valueType)) //Apparently some JVMs return .'s and some don't..
{
{
valuesField = field;
valuesField = field;
break;
break;
}
}
}
}
}
}
if (valuesField == null)
if (valuesField == null)
{
{
final List<String> lines = Lists.newArrayList();
final List<String> lines = Lists.newArrayList();
lines.add(String.format("Could not find $VALUES field for enum: %s", enumType.getName()));
lines.add(String.format("Could not find $VALUES field for enum: %s", enumType.getName()));
lines.add(String.format("Runtime Deobf: %s", FMLForgePlugin.RUNTIME_DEOBF));
lines.add(String.format("Runtime Deobf: %s", FMLForgePlugin.RUNTIME_DEOBF));
lines.add(String.format("Flags: %s", String.format("%16s", Integer.toBinaryString(flags)).replace(' ', '0')));
lines.add(String.format("Flags: %s", String.format("%16s", Integer.toBinaryString(flags)).replace(' ', '0')));
lines.add( "Fields:");
lines.add( "Fields:");
for (Field field : fields)
for (Field field : fields)
{
{
String mods = String.format("%16s", Integer.toBinaryString(field.getModifiers())).replace(' ', '0');
String mods = String.format("%16s", Integer.toBinaryString(field.getModifiers())).replace(' ', '0');
lines.add(String.format(" %s %s: %s", mods, field.getName(), field.getType().getName()));
lines.add(String.format(" %s %s: %s", mods, field.getName(), field.getType().getName()));
}
}
for (String line : lines)
for (String line : lines)
FMLLog.severe(line);
FMLLog.severe(line);
if (test)
if (test)
{
{
throw new EnhancedRuntimeException("Could not find $VALUES field for enum: " + enumType.getName())
throw new EnhancedRuntimeException("Could not find $VALUES field for enum: " + enumType.getName())
{
{
@Override
@Override
protected void printStackTrace(WrappedPrintStream stream)
protected void printStackTrace(WrappedPrintStream stream)
{
{
for (String line : lines)
for (String line : lines)
stream.println(line);
stream.println(line);
}
}
};
};
}
}
return null;
return null;
}
}
if (test)
if (test)
{
{
Object ctr = null;
Object ctr = null;
Exception ex = null;
Exception ex = null;
try
try
{
{
ctr = getConstructorAccessor(enumType, paramTypes);
ctr = getConstructorAccessor(enumType, paramTypes);
}
}
catch (Exception e)
catch (Exception e)
{
{
ex = e;
ex = e;
}
}
if (ctr == null || ex != null)
if (ctr == null || ex != null)
{
{
throw new EnhancedRuntimeException(String.format("Could not find constructor for Enum %s", enumType.getName()), ex)
throw new EnhancedRuntimeException(String.format("Could not find constructor for Enum %s", enumType.getName()), ex)
{
{
private String toString(Class<?>[] cls)
private String toString(Class<?>[] cls)
{
{
StringBuilder b = new StringBuilder();
StringBuilder b = new StringBuilder();
for (int x = 0; x < cls.length; x++)
for (int x = 0; x < cls.length; x++)
{
{
b.append(cls[x].getName());
b.append(cls[x].getName());
if (x != cls.length - 1)
if (x != cls.length - 1)
b.append(", ");
b.append(", ");
}
}
return b.toString();
return b.toString();
}
}
@Override
@Override
protected void printStackTrace(WrappedPrintStream stream)
protected void printStackTrace(WrappedPrintStream stream)
{
{
stream.println("Target Arguments:");
stream.println("Target Arguments:");
stream.println(" java.lang.String, int, " + toString(paramTypes));
stream.println(" java.lang.String, int, " + toString(paramTypes));
stream.println("Found Constructors:");
stream.println("Found Constructors:");
for (Constructor<?> ctr : enumType.getDeclaredConstructors())
for (Constructor<?> ctr : enumType.getDeclaredConstructors())
{
{
stream.println(" " + toString(ctr.getParameterTypes()));
stream.println(" " + toString(ctr.getParameterTypes()));
}
}
}
}
};
};
}
}
return null;
return null;
}
}
valuesField.setAccessible(true);
valuesField.setAccessible(true);
try
try
{
{
T[] previousValues = (T[])valuesField.get(enumType);
T[] previousValues = (T[])valuesField.get(enumType);
List<T> values = new ArrayList<T>(Arrays.asList(previousValues));
List<T> values = new ArrayList<T>(Arrays.asList(previousValues));
T newValue = makeEnum(enumType, enumName, values.size(), paramTypes, paramValues);
T newValue = makeEnum(enumType, enumName, values.size(), paramTypes, paramValues);
values.add(newValue);
values.add(newValue);
setFailsafeFieldValue(valuesField, null, values.toArray((T[]) Array.newInstance(enumType, 0)));
setFailsafeFieldValue(valuesField, null, values.toArray((T[]) Array.newInstance(enumType, 0)));
cleanEnumCache(enumType);
cleanEnumCache(enumType);
return newValue;
return newValue;
}
}
catch (Exception e)
catch (Exception e)
{
{
e.printStackTrace();
e.printStackTrace();
throw new RuntimeException(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
}
}
static
static
{
{
if (!isSetup)
if (!isSetup)
{
{
setup();
setup();
}
}
}
}
}
}
Diferencias guardadas
Texto original
Abrir archivo
/* * Minecraft Forge * Copyright (c) 2016. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package net.minecraftforge.common.util; import java.lang.reflect.*; import java.util.*; import com.google.common.collect.Lists; import net.minecraftforge.fml.common.EnhancedRuntimeException; import net.minecraftforge.fml.common.FMLLog; import net.minecraft.block.BlockPressurePlate.Sensitivity; import net.minecraft.block.material.Material; import net.minecraft.enchantment.EnumEnchantmentType; import net.minecraft.entity.EnumCreatureAttribute; import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.item.EntityPainting.EnumArt; import net.minecraft.entity.player.EntityPlayer.SleepResult; import net.minecraft.item.EnumAction; import net.minecraft.item.EnumRarity; import net.minecraft.item.Item.ToolMaterial; import net.minecraft.item.ItemArmor.ArmorMaterial; import net.minecraft.util.SoundEvent; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.EnumSkyBlock; import net.minecraft.world.gen.structure.StructureStrongholdPieces.Stronghold.Door; import net.minecraftforge.classloading.FMLForgePlugin; public class EnumHelper { private static Object reflectionFactory = null; private static Method newConstructorAccessor = null; private static Method newInstance = null; private static Method newFieldAccessor = null; private static Method fieldAccessorSet = null; private static boolean isSetup = false; //Some enums are decompiled with extra arguments, so lets check for that private static Class<?>[][] commonTypes = { {EnumAction.class}, {ArmorMaterial.class, String.class, int.class, int[].class, int.class, SoundEvent.class, float.class}, {EnumArt.class, String.class, int.class, int.class, int.class, int.class}, {EnumCreatureAttribute.class}, {EnumCreatureType.class, Class.class, int.class, Material.class, boolean.class, boolean.class}, {Door.class}, {EnumEnchantmentType.class}, {Sensitivity.class}, {RayTraceResult.Type.class}, {EnumSkyBlock.class, int.class}, {SleepResult.class}, {ToolMaterial.class, int.class, int.class, float.class, float.class, int.class}, {EnumRarity.class, TextFormatting.class, String.class} }; public static EnumAction addAction(String name) { return addEnum(EnumAction.class, name); } public static ArmorMaterial addArmorMaterial(String name, String textureName, int durability, int[] reductionAmounts, int enchantability, SoundEvent soundOnEquip, float toughness) { return addEnum(ArmorMaterial.class, name, textureName, durability, reductionAmounts, enchantability, soundOnEquip, toughness); } public static EnumArt addArt(String name, String tile, int sizeX, int sizeY, int offsetX, int offsetY) { return addEnum(EnumArt.class, name, tile, sizeX, sizeY, offsetX, offsetY); } public static EnumCreatureAttribute addCreatureAttribute(String name) { return addEnum(EnumCreatureAttribute.class, name); } public static EnumCreatureType addCreatureType(String name, Class<?> typeClass, int maxNumber, Material material, boolean peaceful, boolean animal) { return addEnum(EnumCreatureType.class, name, typeClass, maxNumber, material, peaceful, animal); } public static Door addDoor(String name) { return addEnum(Door.class, name); } public static EnumEnchantmentType addEnchantmentType(String name) { return addEnum(EnumEnchantmentType.class, name); } public static Sensitivity addSensitivity(String name) { return addEnum(Sensitivity.class, name); } public static RayTraceResult.Type addMovingObjectType(String name) { return addEnum(RayTraceResult.Type.class, name); } public static EnumSkyBlock addSkyBlock(String name, int lightValue) { return addEnum(EnumSkyBlock.class, name, lightValue); } public static SleepResult addStatus(String name) { return addEnum(SleepResult.class, name); } public static ToolMaterial addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, float damage, int enchantability) { return addEnum(ToolMaterial.class, name, harvestLevel, maxUses, efficiency, damage, enchantability); } public static EnumRarity addRarity(String name, TextFormatting color, String displayName) { return addEnum(EnumRarity.class, name, color, displayName); } private static void setup() { if (isSetup) { return; } try { Method getReflectionFactory = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("getReflectionFactory"); reflectionFactory = getReflectionFactory.invoke(null); newConstructorAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newConstructorAccessor", Constructor.class); newInstance = Class.forName("sun.reflect.ConstructorAccessor").getDeclaredMethod("newInstance", Object[].class); newFieldAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newFieldAccessor", Field.class, boolean.class); fieldAccessorSet = Class.forName("sun.reflect.FieldAccessor").getDeclaredMethod("set", Object.class, Object.class); } catch (Exception e) { e.printStackTrace(); } isSetup = true; } /* * Everything below this is found at the site below, and updated to be able to compile in Eclipse/Java 1.6+ * Also modified for use in decompiled code. * Found at: http://niceideas.ch/roller2/badtrash/entry/java_create_enum_instances_dynamically */ private static Object getConstructorAccessor(Class<?> enumClass, Class<?>[] additionalParameterTypes) throws Exception { Class<?>[] parameterTypes = new Class[additionalParameterTypes.length + 2]; parameterTypes[0] = String.class; parameterTypes[1] = int.class; System.arraycopy(additionalParameterTypes, 0, parameterTypes, 2, additionalParameterTypes.length); return newConstructorAccessor.invoke(reflectionFactory, enumClass.getDeclaredConstructor(parameterTypes)); } private static < T extends Enum<? >> T makeEnum(Class<T> enumClass, String value, int ordinal, Class<?>[] additionalTypes, Object[] additionalValues) throws Exception { Object[] params = new Object[additionalValues.length + 2]; params[0] = value; params[1] = ordinal; System.arraycopy(additionalValues, 0, params, 2, additionalValues.length); return enumClass.cast(newInstance.invoke(getConstructorAccessor(enumClass, additionalTypes), new Object[] {params})); } public static void setFailsafeFieldValue(Field field, Object target, Object value) throws Exception { field.setAccessible(true); Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); Object fieldAccessor = newFieldAccessor.invoke(reflectionFactory, field, false); fieldAccessorSet.invoke(fieldAccessor, target, value); } private static void blankField(Class<?> enumClass, String fieldName) throws Exception { for (Field field : Class.class.getDeclaredFields()) { if (field.getName().contains(fieldName)) { field.setAccessible(true); setFailsafeFieldValue(field, enumClass, null); break; } } } private static void cleanEnumCache(Class<?> enumClass) throws Exception { blankField(enumClass, "enumConstantDirectory"); blankField(enumClass, "enumConstants"); } private static <T extends Enum<? >> T addEnum(Class<T> enumType, String enumName, Object... paramValues) { setup(); return addEnum(commonTypes, enumType, enumName, paramValues); } protected static <T extends Enum<? >> T addEnum(Class<?>[][] map, Class<T> enumType, String enumName, Object... paramValues) { for (Class<?>[] lookup : map) { if (lookup[0] == enumType) { Class<?>[] paramTypes = new Class<?>[lookup.length - 1]; if (paramTypes.length > 0) { System.arraycopy(lookup, 1, paramTypes, 0, paramTypes.length); } return addEnum(enumType, enumName, paramTypes, paramValues); } } return null; } //Tests an enum is compatible with these args, throws an error if not. public static void testEnum(Class<? extends Enum<?>> enumType, Class<?>[] paramTypes) { addEnum(true, enumType, null, paramTypes, (Object[])null); } public static <T extends Enum<? >> T addEnum(Class<T> enumType, String enumName, Class<?>[] paramTypes, Object... paramValues) { return addEnum(false, enumType, enumName, paramTypes, paramValues); } @SuppressWarnings({ "unchecked", "serial" }) private static <T extends Enum<? >> T addEnum(boolean test, final Class<T> enumType, String enumName, final Class<?>[] paramTypes, Object[] paramValues) { if (!isSetup) { setup(); } Field valuesField = null; Field[] fields = enumType.getDeclaredFields(); for (Field field : fields) { String name = field.getName(); if (name.equals("$VALUES") || name.equals("ENUM$VALUES")) //Added 'ENUM$VALUES' because Eclipse's internal compiler doesn't follow standards { valuesField = field; break; } } int flags = (FMLForgePlugin.RUNTIME_DEOBF ? Modifier.PUBLIC : Modifier.PRIVATE) | Modifier.STATIC | Modifier.FINAL | 0x1000 /*SYNTHETIC*/; if (valuesField == null) { String valueType = String.format("[L%s;", enumType.getName().replace('.', '/')); for (Field field : fields) { if ((field.getModifiers() & flags) == flags && field.getType().getName().replace('.', '/').equals(valueType)) //Apparently some JVMs return .'s and some don't.. { valuesField = field; break; } } } if (valuesField == null) { final List<String> lines = Lists.newArrayList(); lines.add(String.format("Could not find $VALUES field for enum: %s", enumType.getName())); lines.add(String.format("Runtime Deobf: %s", FMLForgePlugin.RUNTIME_DEOBF)); lines.add(String.format("Flags: %s", String.format("%16s", Integer.toBinaryString(flags)).replace(' ', '0'))); lines.add( "Fields:"); for (Field field : fields) { String mods = String.format("%16s", Integer.toBinaryString(field.getModifiers())).replace(' ', '0'); lines.add(String.format(" %s %s: %s", mods, field.getName(), field.getType().getName())); } for (String line : lines) FMLLog.severe(line); if (test) { throw new EnhancedRuntimeException("Could not find $VALUES field for enum: " + enumType.getName()) { @Override protected void printStackTrace(WrappedPrintStream stream) { for (String line : lines) stream.println(line); } }; } return null; } if (test) { Object ctr = null; Exception ex = null; try { ctr = getConstructorAccessor(enumType, paramTypes); } catch (Exception e) { ex = e; } if (ctr == null || ex != null) { throw new EnhancedRuntimeException(String.format("Could not find constructor for Enum %s", enumType.getName()), ex) { private String toString(Class<?>[] cls) { StringBuilder b = new StringBuilder(); for (int x = 0; x < cls.length; x++) { b.append(cls[x].getName()); if (x != cls.length - 1) b.append(", "); } return b.toString(); } @Override protected void printStackTrace(WrappedPrintStream stream) { stream.println("Target Arguments:"); stream.println(" java.lang.String, int, " + toString(paramTypes)); stream.println("Found Constructors:"); for (Constructor<?> ctr : enumType.getDeclaredConstructors()) { stream.println(" " + toString(ctr.getParameterTypes())); } } }; } return null; } valuesField.setAccessible(true); try { T[] previousValues = (T[])valuesField.get(enumType); List<T> values = new ArrayList<T>(Arrays.asList(previousValues)); T newValue = makeEnum(enumType, enumName, values.size(), paramTypes, paramValues); values.add(newValue); setFailsafeFieldValue(valuesField, null, values.toArray((T[]) Array.newInstance(enumType, 0))); cleanEnumCache(enumType); return newValue; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e.getMessage(), e); } } static { if (!isSetup) { setup(); } } }
Texto modificado
Abrir archivo
/* * Minecraft Forge * Copyright (c) 2016. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package net.minecraftforge.common.util; import java.lang.reflect.*; import java.util.*; import com.google.common.base.Predicate; import com.google.common.collect.Lists; import net.minecraftforge.fml.common.EnhancedRuntimeException; import net.minecraftforge.fml.common.FMLLog; import net.minecraft.block.BlockPressurePlate.Sensitivity; import net.minecraft.block.material.Material; import net.minecraft.enchantment.EnumEnchantmentType; import net.minecraft.entity.EnumCreatureAttribute; import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.item.EntityPainting.EnumArt; import net.minecraft.entity.player.EntityPlayer.SleepResult; import net.minecraft.item.EnumAction; import net.minecraft.item.EnumRarity; import net.minecraft.item.Item; import net.minecraft.item.Item.ToolMaterial; import net.minecraft.item.ItemArmor.ArmorMaterial; import net.minecraft.util.SoundEvent; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.EnumSkyBlock; import net.minecraft.world.gen.structure.StructureStrongholdPieces.Stronghold.Door; import net.minecraftforge.classloading.FMLForgePlugin; public class EnumHelper { private static Object reflectionFactory = null; private static Method newConstructorAccessor = null; private static Method newInstance = null; private static Method newFieldAccessor = null; private static Method fieldAccessorSet = null; private static boolean isSetup = false; //Some enums are decompiled with extra arguments, so lets check for that private static Class<?>[][] commonTypes = { {EnumAction.class}, {ArmorMaterial.class, String.class, int.class, int[].class, int.class, SoundEvent.class, float.class}, {EnumArt.class, String.class, int.class, int.class, int.class, int.class}, {EnumCreatureAttribute.class}, {EnumCreatureType.class, Class.class, int.class, Material.class, boolean.class, boolean.class}, {Door.class}, {EnumEnchantmentType.class, Predicate.class}, {Sensitivity.class}, {RayTraceResult.Type.class}, {EnumSkyBlock.class, int.class}, {SleepResult.class}, {ToolMaterial.class, int.class, int.class, float.class, float.class, int.class}, {EnumRarity.class, TextFormatting.class, String.class} }; public static EnumAction addAction(String name) { return addEnum(EnumAction.class, name); } public static ArmorMaterial addArmorMaterial(String name, String textureName, int durability, int[] reductionAmounts, int enchantability, SoundEvent soundOnEquip, float toughness) { return addEnum(ArmorMaterial.class, name, textureName, durability, reductionAmounts, enchantability, soundOnEquip, toughness); } public static EnumArt addArt(String name, String tile, int sizeX, int sizeY, int offsetX, int offsetY) { return addEnum(EnumArt.class, name, tile, sizeX, sizeY, offsetX, offsetY); } public static EnumCreatureAttribute addCreatureAttribute(String name) { return addEnum(EnumCreatureAttribute.class, name); } public static EnumCreatureType addCreatureType(String name, Class<?> typeClass, int maxNumber, Material material, boolean peaceful, boolean animal) { return addEnum(EnumCreatureType.class, name, typeClass, maxNumber, material, peaceful, animal); } public static Door addDoor(String name) { return addEnum(Door.class, name); } public static EnumEnchantmentType addEnchantmentType(String name, Predicate<Item> delegate) { return addEnum(EnumEnchantmentType.class, name, delegate); } public static Sensitivity addSensitivity(String name) { return addEnum(Sensitivity.class, name); } public static RayTraceResult.Type addMovingObjectType(String name) { return addEnum(RayTraceResult.Type.class, name); } public static EnumSkyBlock addSkyBlock(String name, int lightValue) { return addEnum(EnumSkyBlock.class, name, lightValue); } public static SleepResult addStatus(String name) { return addEnum(SleepResult.class, name); } public static ToolMaterial addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, float damage, int enchantability) { return addEnum(ToolMaterial.class, name, harvestLevel, maxUses, efficiency, damage, enchantability); } public static EnumRarity addRarity(String name, TextFormatting color, String displayName) { return addEnum(EnumRarity.class, name, color, displayName); } private static void setup() { if (isSetup) { return; } try { Method getReflectionFactory = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("getReflectionFactory"); reflectionFactory = getReflectionFactory.invoke(null); newConstructorAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newConstructorAccessor", Constructor.class); newInstance = Class.forName("sun.reflect.ConstructorAccessor").getDeclaredMethod("newInstance", Object[].class); newFieldAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newFieldAccessor", Field.class, boolean.class); fieldAccessorSet = Class.forName("sun.reflect.FieldAccessor").getDeclaredMethod("set", Object.class, Object.class); } catch (Exception e) { e.printStackTrace(); } isSetup = true; } /* * Everything below this is found at the site below, and updated to be able to compile in Eclipse/Java 1.6+ * Also modified for use in decompiled code. * Found at: http://niceideas.ch/roller2/badtrash/entry/java_create_enum_instances_dynamically */ private static Object getConstructorAccessor(Class<?> enumClass, Class<?>[] additionalParameterTypes) throws Exception { Class<?>[] parameterTypes = new Class[additionalParameterTypes.length + 2]; parameterTypes[0] = String.class; parameterTypes[1] = int.class; System.arraycopy(additionalParameterTypes, 0, parameterTypes, 2, additionalParameterTypes.length); return newConstructorAccessor.invoke(reflectionFactory, enumClass.getDeclaredConstructor(parameterTypes)); } private static < T extends Enum<? >> T makeEnum(Class<T> enumClass, String value, int ordinal, Class<?>[] additionalTypes, Object[] additionalValues) throws Exception { Object[] params = new Object[additionalValues.length + 2]; params[0] = value; params[1] = ordinal; System.arraycopy(additionalValues, 0, params, 2, additionalValues.length); return enumClass.cast(newInstance.invoke(getConstructorAccessor(enumClass, additionalTypes), new Object[] {params})); } public static void setFailsafeFieldValue(Field field, Object target, Object value) throws Exception { field.setAccessible(true); Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); Object fieldAccessor = newFieldAccessor.invoke(reflectionFactory, field, false); fieldAccessorSet.invoke(fieldAccessor, target, value); } private static void blankField(Class<?> enumClass, String fieldName) throws Exception { for (Field field : Class.class.getDeclaredFields()) { if (field.getName().contains(fieldName)) { field.setAccessible(true); setFailsafeFieldValue(field, enumClass, null); break; } } } private static void cleanEnumCache(Class<?> enumClass) throws Exception { blankField(enumClass, "enumConstantDirectory"); blankField(enumClass, "enumConstants"); } private static <T extends Enum<? >> T addEnum(Class<T> enumType, String enumName, Object... paramValues) { setup(); return addEnum(commonTypes, enumType, enumName, paramValues); } protected static <T extends Enum<? >> T addEnum(Class<?>[][] map, Class<T> enumType, String enumName, Object... paramValues) { for (Class<?>[] lookup : map) { if (lookup[0] == enumType) { Class<?>[] paramTypes = new Class<?>[lookup.length - 1]; if (paramTypes.length > 0) { System.arraycopy(lookup, 1, paramTypes, 0, paramTypes.length); } return addEnum(enumType, enumName, paramTypes, paramValues); } } return null; } //Tests an enum is compatible with these args, throws an error if not. public static void testEnum(Class<? extends Enum<?>> enumType, Class<?>[] paramTypes) { addEnum(true, enumType, null, paramTypes, (Object[])null); } public static <T extends Enum<? >> T addEnum(Class<T> enumType, String enumName, Class<?>[] paramTypes, Object... paramValues) { return addEnum(false, enumType, enumName, paramTypes, paramValues); } @SuppressWarnings({ "unchecked", "serial" }) private static <T extends Enum<? >> T addEnum(boolean test, final Class<T> enumType, String enumName, final Class<?>[] paramTypes, Object[] paramValues) { if (!isSetup) { setup(); } Field valuesField = null; Field[] fields = enumType.getDeclaredFields(); for (Field field : fields) { String name = field.getName(); if (name.equals("$VALUES") || name.equals("ENUM$VALUES")) //Added 'ENUM$VALUES' because Eclipse's internal compiler doesn't follow standards { valuesField = field; break; } } int flags = (FMLForgePlugin.RUNTIME_DEOBF ? Modifier.PUBLIC : Modifier.PRIVATE) | Modifier.STATIC | Modifier.FINAL | 0x1000 /*SYNTHETIC*/; if (valuesField == null) { String valueType = String.format("[L%s;", enumType.getName().replace('.', '/')); for (Field field : fields) { if ((field.getModifiers() & flags) == flags && field.getType().getName().replace('.', '/').equals(valueType)) //Apparently some JVMs return .'s and some don't.. { valuesField = field; break; } } } if (valuesField == null) { final List<String> lines = Lists.newArrayList(); lines.add(String.format("Could not find $VALUES field for enum: %s", enumType.getName())); lines.add(String.format("Runtime Deobf: %s", FMLForgePlugin.RUNTIME_DEOBF)); lines.add(String.format("Flags: %s", String.format("%16s", Integer.toBinaryString(flags)).replace(' ', '0'))); lines.add( "Fields:"); for (Field field : fields) { String mods = String.format("%16s", Integer.toBinaryString(field.getModifiers())).replace(' ', '0'); lines.add(String.format(" %s %s: %s", mods, field.getName(), field.getType().getName())); } for (String line : lines) FMLLog.severe(line); if (test) { throw new EnhancedRuntimeException("Could not find $VALUES field for enum: " + enumType.getName()) { @Override protected void printStackTrace(WrappedPrintStream stream) { for (String line : lines) stream.println(line); } }; } return null; } if (test) { Object ctr = null; Exception ex = null; try { ctr = getConstructorAccessor(enumType, paramTypes); } catch (Exception e) { ex = e; } if (ctr == null || ex != null) { throw new EnhancedRuntimeException(String.format("Could not find constructor for Enum %s", enumType.getName()), ex) { private String toString(Class<?>[] cls) { StringBuilder b = new StringBuilder(); for (int x = 0; x < cls.length; x++) { b.append(cls[x].getName()); if (x != cls.length - 1) b.append(", "); } return b.toString(); } @Override protected void printStackTrace(WrappedPrintStream stream) { stream.println("Target Arguments:"); stream.println(" java.lang.String, int, " + toString(paramTypes)); stream.println("Found Constructors:"); for (Constructor<?> ctr : enumType.getDeclaredConstructors()) { stream.println(" " + toString(ctr.getParameterTypes())); } } }; } return null; } valuesField.setAccessible(true); try { T[] previousValues = (T[])valuesField.get(enumType); List<T> values = new ArrayList<T>(Arrays.asList(previousValues)); T newValue = makeEnum(enumType, enumName, values.size(), paramTypes, paramValues); values.add(newValue); setFailsafeFieldValue(valuesField, null, values.toArray((T[]) Array.newInstance(enumType, 0))); cleanEnumCache(enumType); return newValue; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e.getMessage(), e); } } static { if (!isSetup) { setup(); } } }
Encontrar la diferencia