Fix getter return types again

This commit is contained in:
Adam
2016-04-17 12:55:53 -04:00
parent e710975305
commit fa6a326bf5
3 changed files with 118 additions and 21 deletions

View File

@@ -96,29 +96,53 @@ public class Inject
return sig; return sig;
} }
private Type toApiType(Type t) private Type classToType(java.lang.Class<?> c)
{ {
// t = vanilla type int dimms = 0;
while (c.isArray())
if (t.isPrimitive())
return t;
String type = t.getType();
type = type.substring(1, type.length() - 1);
ClassFile cf = vanilla.findClass(type);
if (cf == null)
return t;
for (Class c : cf.getInterfaces().getInterfaces())
{ {
if (c.getName().startsWith(API_PACKAGE_BASE.replace('.', '/'))) c = c.getComponentType();
{ ++dimms;
return new Type("L" + c.getName() + ";", t.getArrayDims());
}
} }
return t; if (c.isPrimitive())
{
String s;
switch (c.getName())
{
case "int":
s = "I";
break;
case "long":
s = "J";
break;
case "boolean":
s = "Z";
break;
case "char":
s = "C";
break;
case "short":
s = "S";
break;
case "float":
s = "F";
break;
case "double":
s = "D";
break;
case "byte":
s = "B";
break;
default:
throw new RuntimeException("unknown primitive type");
}
return new Type(s, dimms);
}
return new Type("L" + c.getName().replace('.', '/') + ";", dimms);
} }
public void run() public void run()
@@ -300,7 +324,7 @@ public class Inject
assert field.isStatic() || field.getFields().getClassFile() == clazz; assert field.isStatic() || field.getFields().getClassFile() == clazz;
Signature sig = new Signature(); Signature sig = new Signature();
sig.setTypeOfReturnValue(toApiType(field.getType())); sig.setTypeOfReturnValue(classToType(method.getReturnType()));
Method getterMethod = new Method(clazz.getMethods(), method.getName(), sig); Method getterMethod = new Method(clazz.getMethods(), method.getName(), sig);
getterMethod.setAccessFlags(Method.ACC_PUBLIC); getterMethod.setAccessFlags(Method.ACC_PUBLIC);

View File

@@ -2,6 +2,7 @@ package net.runelite.deob.injection;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import net.runelite.asm.ClassFile;
import net.runelite.asm.ClassGroup; import net.runelite.asm.ClassGroup;
import net.runelite.deob.util.JarUtil; import net.runelite.deob.util.JarUtil;
import org.junit.After; import org.junit.After;
@@ -30,10 +31,21 @@ public class InjectTest
} }
@Test @Test
public void testRun() public void testRun() throws IOException, ClassNotFoundException
{ {
Inject instance = new Inject(deob, vanilla); Inject instance = new Inject(deob, vanilla);
instance.run(); instance.run();
testLoading(vanilla);
}
private void testLoading(ClassGroup group) throws ClassNotFoundException
{
TestingClassLoader loader = new TestingClassLoader(group);
for (ClassFile cf : group.getClasses())
{
loader.findClass(cf.getName());
}
} }
} }

View File

@@ -0,0 +1,61 @@
package net.runelite.deob.injection;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.SecureClassLoader;
import java.util.HashMap;
import java.util.Map;
import net.runelite.asm.ClassFile;
import net.runelite.asm.ClassGroup;
import net.runelite.asm.objectwebasm.AsmUtils;
public class TestingClassLoader extends SecureClassLoader
{
private ClassGroup group;
private Map<String, Class<?> > classes = new HashMap<>();
public TestingClassLoader(ClassGroup group)
{
this.group = group;
}
@Override
public Class<?> findClass(String name) throws ClassNotFoundException
{
ClassFile cf = group.findClass(name);
if (cf == null)
return super.findClass(name);
Class<?> c = classes.get(name);
if (c != null)
return c;
return defineClass(name, classToBytes(cf));
}
private Class<?> defineClass(String name, byte[] b)
{
Class<?> c = super.defineClass(name.replace('/', '.'), b, 0, b.length);
classes.put(name, c);
return c;
}
private byte[] classToBytes(ClassFile cf)
{
try
{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
cf.write(new DataOutputStream(bout));
// run through asm to generate stackmaps
return AsmUtils.rebuildWithStackmaps(group, new ByteArrayInputStream(bout.toByteArray()));
}
catch (IOException ex)
{
ex.printStackTrace();
return null;
}
}
}