Fix ClassCircularityError with config package being used by asm package

This commit is contained in:
Chicken-Bomes committed 2014-04-29 11:42:02 +10:00
1 parent 52f82017e7
commit 1f03959a99
2 files changed
+77 -82

No files matched your search

+18
View File
@@ -0,0 +1,18 @@
package codechicken.lib.asm;
import net.minecraft.launchwrapper.Launch;
/**
* Initialisation class for using this package. Call this on coremod load
*/
public class ASMInit
{
private static boolean initialised = false;
public static void init() {
if(!initialised) {
Launch.classLoader.addTransformerExclusion("codechicken.lib.asm");
Launch.classLoader.addTransformerExclusion("codechicken.lib.config");
initialised = true;
}
}
}
@@ -2,6 +2,7 @@ package codechicken.lib.asm;
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
import net.minecraft.launchwrapper.IClassTransformer;
import net.minecraft.launchwrapper.Launch;
import net.minecraft.launchwrapper.LaunchClassLoader;
import org.objectweb.asm.tree.ClassNode;
@@ -19,22 +20,18 @@ public class ClassHeirachyManager implements IClassTransformer
String superclass;
public HashSet<String> parents = new HashSet<String>();
private boolean flattened;
public void add(String parent)
{
public void add(String parent) {
parents.add(parent);
}
public void flatten()
{
if(flattened)
public void flatten() {
if (flattened)
return;
for(String s : new ArrayList<String>(parents))
{
for (String s : new ArrayList<String>(parents)) {
SuperCache c = declareClass(s);
if(c != null)
{
if (c != null) {
c.flatten();
parents.addAll(c.parents);
}
@@ -42,146 +39,126 @@ public class ClassHeirachyManager implements IClassTransformer
flattened = true;
}
}
public static HashMap<String, SuperCache> superclasses = new HashMap<String, SuperCache>();
private static LaunchClassLoader cl = (LaunchClassLoader)ClassHeirachyManager.class.getClassLoader();
static
{
cl.addTransformerExclusion("codechicken.lib.asm");
}
public static String toKey(String name)
{
if(ObfMapping.obfuscated)
private static LaunchClassLoader cl = Launch.classLoader;
public static String toKey(String name) {
if (ObfMapping.obfuscated)
name = FMLDeobfuscatingRemapper.INSTANCE.map(name.replace('.', '/')).replace('/', '.');
return name;
}
public static String unKey(String name)
{
if(ObfMapping.obfuscated)
public static String unKey(String name) {
if (ObfMapping.obfuscated)
name = FMLDeobfuscatingRemapper.INSTANCE.unmap(name.replace('.', '/')).replace('/', '.');
return name;
}
/**
* @param name The class in question
* @param name The class in question
* @param superclass The class being extended
* @return true if clazz extends, either directly or indirectly, superclass.
*/
public static boolean classExtends(String name, String superclass)
{
public static boolean classExtends(String name, String superclass) {
name = toKey(name);
superclass = toKey(superclass);
if(name.equals(superclass))
if (name.equals(superclass))
return true;
SuperCache cache = declareClass(name);
if(cache == null)//just can't handle this
if (cache == null)//just can't handle this
return false;
cache.flatten();
return cache.parents.contains(superclass);
}
private static SuperCache declareClass(String name)
{
private static SuperCache declareClass(String name) {
name = toKey(name);
SuperCache cache = superclasses.get(name);
if(cache != null)
if (cache != null)
return cache;
try
{
try {
byte[] bytes = cl.getClassBytes(unKey(name));
if(bytes != null)
if (bytes != null)
cache = declareASM(bytes);
}
catch(Exception e)
{
} catch (Exception e) {
}
if(cache != null)
if (cache != null)
return cache;
try
{
try {
cache = declareReflection(name);
} catch (ClassNotFoundException e) {
}
catch(ClassNotFoundException e)
{
}
return cache;
}
private static SuperCache declareReflection(String name) throws ClassNotFoundException
{
private static SuperCache declareReflection(String name) throws ClassNotFoundException {
Class<?> aclass = Class.forName(name);
SuperCache cache = getOrCreateCache(name);
if(aclass.isInterface())
if (aclass.isInterface())
cache.superclass = "java.lang.Object";
else if(name.equals("java.lang.Object"))
else if (name.equals("java.lang.Object"))
return cache;
else
cache.superclass = toKey(aclass.getSuperclass().getName());
cache.add(cache.superclass);
for(Class<?> iclass : aclass.getInterfaces())
for (Class<?> iclass : aclass.getInterfaces())
cache.add(toKey(iclass.getName()));
return cache;
}
private static SuperCache declareASM(byte[] bytes)
{
private static SuperCache declareASM(byte[] bytes) {
ClassNode node = ASMHelper.createClassNode(bytes);
String name = toKey(node.name);
SuperCache cache = getOrCreateCache(name);
cache.superclass = toKey(node.superName.replace('/', '.'));
cache.add(cache.superclass);
for(String iclass : node.interfaces)
for (String iclass : node.interfaces)
cache.add(toKey(iclass.replace('/', '.')));
return cache;
}
@Override
public byte[] transform(String name, String tname, byte[] bytes)
{
public byte[] transform(String name, String tname, byte[] bytes) {
if (bytes == null)
return null;
if(!superclasses.containsKey(tname))
if (!superclasses.containsKey(tname))
declareASM(bytes);
return bytes;
}
public static SuperCache getOrCreateCache(String name)
{
public static SuperCache getOrCreateCache(String name) {
SuperCache cache = superclasses.get(name);
if(cache == null)
if (cache == null)
superclasses.put(name, cache = new SuperCache());
return cache;
}
public static String getSuperClass(String name, boolean runtime)
{
public static String getSuperClass(String name, boolean runtime) {
name = toKey(name);
SuperCache cache = declareClass(name);
if(cache == null)
if (cache == null)
return "java.lang.Object";
cache.flatten();
String s = cache.superclass;
if(!runtime)
if (!runtime)
s = FMLDeobfuscatingRemapper.INSTANCE.unmap(s);
return s;
}