Commit 0f2907dd by Eric Bruneton

Merge branch 'refactor-tests'

2 parents ac45f369 ca03e07e
Pipeline #363 passed
in 9 minutes 54 seconds
Showing with 915 additions and 1281 deletions
......@@ -45,7 +45,7 @@ import org.objectweb.asm.tree.MethodNode;
*
* @author Eric Bruneton
*/
public class AnalyzerUnitTest {
public class AnalyzerTest {
protected ClassWriter cw;
......
......@@ -38,7 +38,7 @@ import org.junit.jupiter.api.Test;
*
* @author Eric Bruneton
*/
public class SmallSetUnitTest {
public class SmallSetTest {
private final Object A = new Object();
private final Object B = new Object();
......
......@@ -36,7 +36,7 @@ import org.junit.jupiter.api.Test;
*
* @author Eric Bruneton
*/
public class ValueUnitTest {
public class ValueTest {
@Test
public void testBasicValue() {
......
......@@ -29,6 +29,11 @@ package org.objectweb.asm.commons;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.objectweb.asm.ClassReader;
......@@ -45,6 +50,184 @@ import org.objectweb.asm.test.AsmTest;
*/
public class AdviceAdapterTest extends AsmTest {
@Test
public void test() throws Exception {
Class<?> c = getClass();
String name = c.getName();
AdvisingClassLoader cl = new AdvisingClassLoader(name + "$");
Class<?> cc = cl.loadClass(name + "$B");
Method m = cc.getMethod("run", new Class<?>[] {Integer.TYPE});
try {
m.invoke(null, new Object[] {new Integer(0)});
} catch (InvocationTargetException e) {
throw (Exception) e.getTargetException();
}
}
private static final class AdvisingClassLoader extends ClassLoader {
private String prefix;
public AdvisingClassLoader(final String prefix) throws IOException {
this.prefix = prefix;
}
@Override
public Class<?> loadClass(final String name) throws ClassNotFoundException {
if (name.startsWith(prefix)) {
try {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
ClassReader cr =
new ClassReader(
getClass().getResourceAsStream("/" + name.replace('.', '/') + ".class"));
cr.accept(new AdviceClassAdapter(cw), ClassReader.EXPAND_FRAMES);
byte[] bytecode = cw.toByteArray();
return super.defineClass(name, bytecode, 0, bytecode.length);
} catch (IOException ex) {
throw new ClassNotFoundException("Load error: " + ex.toString(), ex);
}
}
return super.loadClass(name);
}
}
// test callback
private static int n = 0;
public static void enter(final String msg) {
n++;
}
public static void exit(final String msg) {
n--;
}
private static StringBuilder off() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
sb.append(" ");
}
return sb;
}
static class AdviceClassAdapter extends ClassVisitor implements Opcodes {
String cname;
public AdviceClassAdapter(final ClassVisitor cv) {
super(Opcodes.ASM5, cv);
}
@Override
public void visit(
final int version,
final int access,
final String name,
final String signature,
final String superName,
final String[] interfaces) {
this.cname = name;
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public MethodVisitor visitMethod(
final int access,
final String name,
final String desc,
final String signature,
final String[] exceptions) {
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
if (mv == null || (access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) > 0) {
return mv;
}
return new AdviceAdapter(Opcodes.ASM5, mv, access, name, desc) {
@Override
protected void onMethodEnter() {
mv.visitLdcInsn(cname + "." + name + desc);
mv.visitMethodInsn(
INVOKESTATIC,
"org/objectweb/asm/commons/AdviceAdapterTest",
"enter",
"(Ljava/lang/String;)V",
false);
}
@Override
protected void onMethodExit(final int opcode) {
mv.visitLdcInsn(cname + "." + name + desc);
mv.visitMethodInsn(
INVOKESTATIC,
"org/objectweb/asm/commons/AdviceAdapterTest",
"exit",
"(Ljava/lang/String;)V",
false);
}
};
}
}
// TEST CLASSES
public static class A {
final String s;
public A(final String s) {
this.s = s;
}
public A(final A a) {
this.s = a.s;
}
}
public static class B extends A {
public B() {
super(new B(""));
test(this);
}
public B(final A a) {
super(a);
test(this);
}
public B(final String s) {
super(s == null ? new A("") : new A(s));
test(this);
}
private static A aa;
public B(final String s, final A a) {
this(s == null ? aa = new A(s) : a);
A aa = new A("");
test(aa);
}
public B(final String s, final String s1) {
super(s != null ? new A(getA(s1).s) : new A(s));
test(this);
}
private void test(final Object b) {}
private static A getA(final String s) {
return new A(s);
}
// execute all
public static void run(final int n) {
new B();
new B(new A(""));
new B(new B());
new B("", new A(""));
new B("", "");
}
}
@ParameterizedTest
@MethodSource(ALL_CLASSES_AND_ALL_APIS)
public void testEmptyAdviceAdapter(PrecompiledClass classParameter, Api apiParameter)
......@@ -55,7 +238,7 @@ public class AdviceAdapterTest extends AsmTest {
ClassVisitor expectedClassVisitor =
new ReferenceClassAdapter(apiParameter.value(), expectedClassWriter);
ClassVisitor actualClassVisitor =
new AdviceClassAdapter(apiParameter.value(), actualClassWriter);
new EmptyAdviceClassAdapter(apiParameter.value(), actualClassWriter);
if (classParameter.isMoreRecentThan(apiParameter)) {
assertThrows(
RuntimeException.class,
......@@ -91,9 +274,9 @@ public class AdviceAdapterTest extends AsmTest {
}
}
private static class AdviceClassAdapter extends ClassVisitor {
private static class EmptyAdviceClassAdapter extends ClassVisitor {
AdviceClassAdapter(final int api, final ClassVisitor cv) {
EmptyAdviceClassAdapter(final int api, final ClassVisitor cv) {
super(api, cv);
}
......
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.commons;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.junit.jupiter.api.Test;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* Simple example of using AdviceAdapter to implement tracing callback
*
* @author Eugene Kuleshov
*/
public class AdviceAdapterUnitTest {
@Test
public void test() throws Exception {
Class<?> c = getClass();
String name = c.getName();
AdvisingClassLoader cl = new AdvisingClassLoader(name + "$");
Class<?> cc = cl.loadClass(name + "$B");
Method m = cc.getMethod("run", new Class<?>[] {Integer.TYPE});
try {
m.invoke(null, new Object[] {new Integer(0)});
} catch (InvocationTargetException e) {
throw (Exception) e.getTargetException();
}
}
private static class AdvisingClassLoader extends ClassLoader {
private String prefix;
public AdvisingClassLoader(final String prefix) throws IOException {
this.prefix = prefix;
}
@Override
public Class<?> loadClass(final String name) throws ClassNotFoundException {
if (name.startsWith(prefix)) {
try {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
ClassReader cr =
new ClassReader(
getClass().getResourceAsStream("/" + name.replace('.', '/') + ".class"));
cr.accept(new AdviceClassAdapter(cw), ClassReader.EXPAND_FRAMES);
byte[] bytecode = cw.toByteArray();
return super.defineClass(name, bytecode, 0, bytecode.length);
} catch (IOException ex) {
throw new ClassNotFoundException("Load error: " + ex.toString(), ex);
}
}
return super.loadClass(name);
}
}
// test callback
private static int n = 0;
public static void enter(final String msg) {
System.err.println(off().append("enter ").append(msg).toString());
n++;
}
public static void exit(final String msg) {
n--;
System.err.println(off().append("<").toString());
}
private static StringBuilder off() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
sb.append(" ");
}
return sb;
}
static class AdviceClassAdapter extends ClassVisitor implements Opcodes {
String cname;
public AdviceClassAdapter(final ClassVisitor cv) {
super(Opcodes.ASM5, cv);
}
@Override
public void visit(
final int version,
final int access,
final String name,
final String signature,
final String superName,
final String[] interfaces) {
this.cname = name;
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public MethodVisitor visitMethod(
final int access,
final String name,
final String desc,
final String signature,
final String[] exceptions) {
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
if (mv == null || (access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) > 0) {
return mv;
}
return new AdviceAdapter(Opcodes.ASM5, mv, access, name, desc) {
@Override
protected void onMethodEnter() {
mv.visitLdcInsn(cname + "." + name + desc);
mv.visitMethodInsn(
INVOKESTATIC,
"org/objectweb/asm/commons/AdviceAdapterUnitTest",
"enter",
"(Ljava/lang/String;)V",
false);
}
@Override
protected void onMethodExit(final int opcode) {
mv.visitLdcInsn(cname + "." + name + desc);
mv.visitMethodInsn(
INVOKESTATIC,
"org/objectweb/asm/commons/AdviceAdapterUnitTest",
"exit",
"(Ljava/lang/String;)V",
false);
}
};
}
}
// TEST CLASSES
public static class A {
final String s;
public A(final String s) {
this.s = s;
}
public A(final A a) {
this.s = a.s;
}
}
public static class B extends A {
public B() {
super(new B(""));
test(this);
}
public B(final A a) {
super(a);
test(this);
}
public B(final String s) {
super(s == null ? new A("") : new A(s));
test(this);
}
private static A aa;
public B(final String s, final A a) {
this(s == null ? aa = new A(s) : a);
A aa = new A("");
test(aa);
}
public B(final String s, final String s1) {
super(s != null ? new A(getA(s1).s) : new A(s));
test(this);
}
private void test(final Object b) {}
private static A getA(final String s) {
return new A(s);
}
// execute all
public static void run(final int n) {
new B();
new B(new A(""));
new B(new B());
new B("", new A(""));
new B("", "");
}
}
}
......@@ -27,16 +27,227 @@
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.commons;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.objectweb.asm.test.Assertions.assertThat;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.ListIterator;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.test.AsmTest;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.FrameNode;
import org.objectweb.asm.tree.InnerClassNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.MultiANewArrayInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.tree.TypeInsnNode;
public class ClassRemapperTest extends AsmTest implements Opcodes {
@Test
public void testClassRemapper() throws Exception {
Map<String, String> map = new HashMap<String, String>();
map.put("Boo", "B1");
map.put("Coo", "C1");
map.put("Doo", "D1");
Remapper remapper = new SimpleRemapper(map);
ClassNode cn = new ClassNode();
dump(new ClassRemapper(cn, remapper));
assertEquals("D1", cn.name);
assertEquals("B1", cn.superName);
assertEquals(Arrays.asList(new String[] {"I", "I", "C1", "J", "B1"}), cn.interfaces);
assertEquals("LB1;", field(cn, 0).desc);
assertEquals("[LB1;", field(cn, 1).desc);
assertEquals("D1", innerClass(cn, 0).name);
assertEquals("B1", innerClass(cn, 0).outerName);
// assertEquals("Doo", innerClass(cn, 0).innerName);
assertEquals("B1", cn.outerClass);
assertEquals("([[LB1;LC1;LD1;)LC1;", cn.outerMethodDesc);
MethodNode mn0 = cn.methods.get(0);
ListIterator<AbstractInsnNode> it = mn0.instructions.iterator();
FieldInsnNode n0 = (FieldInsnNode) it.next();
assertEquals("D1", n0.owner);
assertEquals("LB1;", n0.desc);
assertEquals(Type.getType("LB1;"), ((LdcInsnNode) it.next()).cst);
assertEquals(Type.getType("[LD1;"), ((LdcInsnNode) it.next()).cst);
assertEquals(Type.getType("[I"), ((LdcInsnNode) it.next()).cst);
assertEquals(Type.getType("J"), ((LdcInsnNode) it.next()).cst);
assertEquals("B1", ((TypeInsnNode) it.next()).desc);
assertEquals("[LD1;", ((TypeInsnNode) it.next()).desc);
assertEquals("[I", ((TypeInsnNode) it.next()).desc);
assertEquals("J", ((TypeInsnNode) it.next()).desc);
MultiANewArrayInsnNode n3 = (MultiANewArrayInsnNode) it.next();
assertEquals("[[LB1;", n3.desc);
MethodInsnNode n4 = (MethodInsnNode) it.next();
assertEquals("D1", n4.owner);
assertEquals("([[LB1;LC1;LD1;)LC1;", n4.desc);
FrameNode fn0 = (FrameNode) it.next();
assertEquals(Collections.EMPTY_LIST, fn0.local);
assertEquals(Collections.EMPTY_LIST, fn0.stack);
assertEquals(Arrays.asList(new Object[] {"B1", "C1", "D1"}), ((FrameNode) it.next()).local);
assertEquals(
Arrays.asList(new Object[] {Opcodes.INTEGER, "C1", Opcodes.INTEGER, "D1"}),
((FrameNode) it.next()).local);
assertEquals(
Arrays.asList(new Object[] {Opcodes.INTEGER, Opcodes.INTEGER}),
((FrameNode) it.next()).local);
// assertEquals(Collections.EMPTY_LIST, fn0.stack);
TryCatchBlockNode tryCatchBlockNode = mn0.tryCatchBlocks.get(0);
assertEquals("C1", tryCatchBlockNode.type);
MethodNode mn1 = cn.methods.get(1);
assertEquals("([[LB1;LC1;LD1;)V", mn1.desc);
assertEquals(Arrays.asList(new String[] {"I", "J"}), mn1.exceptions);
}
private FieldNode field(ClassNode cn, int n) {
return cn.fields.get(n);
}
private InnerClassNode innerClass(ClassNode cn, int n) {
return cn.innerClasses.get(n);
}
public static void dump(ClassVisitor cv) throws Exception {
cv.visit(V1_5, 0, "Doo", null, "Boo", new String[] {"I", "I", "Coo", "J", "Boo"});
cv.visitInnerClass("Doo", "Boo", "Doo", 0);
cv.visitOuterClass("Boo", "foo", "([[LBoo;LCoo;LDoo;)LCoo;");
cv.visitField(0, "boo", "LBoo;", null, null).visitEnd();
cv.visitField(0, "boo1", "[LBoo;", null, null).visitEnd();
cv.visitField(0, "s", "Ljava/lang/String;", null, null).visitEnd();
cv.visitField(0, "i", "I", null, null).visitEnd();
MethodVisitor mv;
public class ClassRemapperTest extends AsmTest {
mv = cv.visitMethod(0, "foo", "()V", null, null);
mv.visitCode();
mv.visitFieldInsn(GETFIELD, "Doo", "boo", "LBoo;");
mv.visitLdcInsn(Type.getType("LBoo;"));
mv.visitLdcInsn(Type.getType("[LDoo;"));
mv.visitLdcInsn(Type.getType("[I"));
mv.visitLdcInsn(Type.getType("J"));
mv.visitTypeInsn(ANEWARRAY, "Boo");
mv.visitTypeInsn(ANEWARRAY, "[LDoo;");
mv.visitTypeInsn(ANEWARRAY, "[I");
mv.visitTypeInsn(ANEWARRAY, "J");
mv.visitMultiANewArrayInsn("[[LBoo;", 2);
mv.visitMethodInsn(INVOKEVIRTUAL, "Doo", "goo", "([[LBoo;LCoo;LDoo;)LCoo;", false);
mv.visitFrame(Opcodes.F_NEW, 0, new Object[5], 0, new Object[10]);
mv.visitFrame(Opcodes.F_NEW, 3, new Object[] {"Boo", "Coo", "Doo"}, 0, new Object[0]);
mv.visitFrame(
Opcodes.F_NEW,
4,
new Object[] {Opcodes.INTEGER, "Coo", Opcodes.INTEGER, "Doo"},
0,
new Object[0]);
mv.visitFrame(
Opcodes.F_NEW, 2, new Object[] {Opcodes.INTEGER, Opcodes.INTEGER}, 0, new Object[0]);
Label l = new Label();
mv.visitLocalVariable("boo", "LBoo;", null, l, l, 1);
mv.visitLocalVariable("boo1", "[LBoo;", null, l, l, 3);
mv.visitLocalVariable("boo2", "[[LBoo;", null, l, l, 4);
mv.visitMaxs(0, 0);
mv.visitTryCatchBlock(l, l, l, "Coo");
mv.visitEnd();
mv = cv.visitMethod(0, "goo", "([[LBoo;LCoo;LDoo;)V", null, new String[] {"I", "J"});
mv.visitEnd();
cv.visitEnd();
}
// /*
public static class Boo {}
public static interface Coo {}
public static class Doo extends Boo implements Coo {
Boo boo = new Boo();
Boo[] boo1 = new Boo[2];
String s = "";
int i = 5;
static final Class<?> c1 = Boo.class;
static final Class<?> c2 = Boo[].class;
public Doo() {}
public Doo(int i, Coo coo, Boo boo) {}
void foo() {
class Eoo {
String s;
}
Eoo e = new Eoo();
e.s = "aaa";
// visitFieldInsn(int, String, String, String)
// visitLocalVariable(String, String, String, Label, Label, int)
Boo boo = this.boo;
// visitLdcInsn(Object)
Class<?> cc = Boo.class;
// visitTypeInsn(int, String)
Boo[] boo1 = new Boo[2];
// visitMultiANewArrayInsn(String, int)
Boo[][] boo2 = new Boo[2][2];
// visitMethodInsn(int, String, String, String)
goo(boo2, this, this);
}
Coo goo(Boo[][] boo2, Coo coo, Doo doo) {
return null;
}
}
/** Tests that classes transformed with a ClassRemapper can be loaded and instantiated. */
@ParameterizedTest
......
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.commons;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.ListIterator;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.FrameNode;
import org.objectweb.asm.tree.InnerClassNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.MultiANewArrayInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.tree.TypeInsnNode;
public class ClassRemapperUnitTest implements Opcodes {
@Test
public void testClassRemapper() throws Exception {
Map<String, String> map = new HashMap<String, String>();
map.put("Boo", "B1");
map.put("Coo", "C1");
map.put("Doo", "D1");
Remapper remapper = new SimpleRemapper(map);
ClassNode cn = new ClassNode();
dump(new ClassRemapper(cn, remapper));
assertEquals("D1", cn.name);
assertEquals("B1", cn.superName);
assertEquals(Arrays.asList(new String[] {"I", "I", "C1", "J", "B1"}), cn.interfaces);
assertEquals("LB1;", field(cn, 0).desc);
assertEquals("[LB1;", field(cn, 1).desc);
assertEquals("D1", innerClass(cn, 0).name);
assertEquals("B1", innerClass(cn, 0).outerName);
// assertEquals("Doo", innerClass(cn, 0).innerName);
assertEquals("B1", cn.outerClass);
assertEquals("([[LB1;LC1;LD1;)LC1;", cn.outerMethodDesc);
MethodNode mn0 = cn.methods.get(0);
ListIterator<AbstractInsnNode> it = mn0.instructions.iterator();
FieldInsnNode n0 = (FieldInsnNode) it.next();
assertEquals("D1", n0.owner);
assertEquals("LB1;", n0.desc);
assertEquals(Type.getType("LB1;"), ((LdcInsnNode) it.next()).cst);
assertEquals(Type.getType("[LD1;"), ((LdcInsnNode) it.next()).cst);
assertEquals(Type.getType("[I"), ((LdcInsnNode) it.next()).cst