aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorBenedikt Ritter <britter@apache.org>2016-09-06 06:38:18 +0000
committerBenedikt Ritter <britter@apache.org>2016-09-06 06:38:18 +0000
commitc96a3e5a40040ef43e0a51935a368458763d3424 (patch)
treee698d0ceebc8d38e34f9402ffef7af735c1c2de6 /src/test
parent7ceb5a6b8236517d708d7965f4873344c5630969 (diff)
downloadapache-commons-bcel-c96a3e5a40040ef43e0a51935a368458763d3424.tar.gz
BCEL-276: LocalVariableTypeTable is not updated. Thanks to Sam Yoon. This also fixes #10 from GitHub.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/bcel/trunk@1759364 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/test')
-rw-r--r--src/test/java/org/apache/bcel/LocalVariableTypeTableTestCase.java142
-rw-r--r--src/test/java/org/apache/bcel/data/SimpleClassHasMethodIncludeGenericArgument.java34
2 files changed, 176 insertions, 0 deletions
diff --git a/src/test/java/org/apache/bcel/LocalVariableTypeTableTestCase.java b/src/test/java/org/apache/bcel/LocalVariableTypeTableTestCase.java
new file mode 100644
index 00000000..ca7e2da1
--- /dev/null
+++ b/src/test/java/org/apache/bcel/LocalVariableTypeTableTestCase.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.bcel;
+
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.Method;
+import org.apache.bcel.generic.ACONST_NULL;
+import org.apache.bcel.generic.ALOAD;
+import org.apache.bcel.generic.ConstantPoolGen;
+import org.apache.bcel.generic.GETSTATIC;
+import org.apache.bcel.generic.INVOKEVIRTUAL;
+import org.apache.bcel.generic.Instruction;
+import org.apache.bcel.generic.InstructionList;
+import org.apache.bcel.generic.LocalVariableGen;
+import org.apache.bcel.generic.MethodGen;
+import org.apache.bcel.generic.Type;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.LinkedList;
+import java.util.List;
+
+public class LocalVariableTypeTableTestCase extends AbstractTestCase {
+ public class TestClassLoader extends ClassLoader {
+ public TestClassLoader(ClassLoader parent) {
+ super(parent);
+ }
+
+ public Class<?> findClass(String name, byte[] bytes) {
+ return defineClass(name, bytes, 0, bytes.length);
+ }
+ }
+
+ @Test
+ public void testWithGenericArguement() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException {
+ String targetClass = PACKAGE_BASE_NAME + ".data.SimpleClassHasMethodIncludeGenericArgument";
+ TestClassLoader loader = new TestClassLoader(getClass().getClassLoader());
+ Class cls = loader.findClass(targetClass, getBytesFromClass(targetClass));
+
+ java.lang.reflect.Method method = cls.getDeclaredMethod("a", String.class, List.class);
+ method.invoke(null, "a1", new LinkedList<String>());
+ method = cls.getDeclaredMethod("b", String.class, List.class);
+ method.invoke(null, "b1", new LinkedList<String>());
+ method = cls.getDeclaredMethod("c", String.class, String.class);
+ method.invoke(null, "c1", "c2");
+ method = cls.getDeclaredMethod("d", List.class, String.class);
+ method.invoke(null, new LinkedList<String>(), "d2");
+ }
+
+ private byte[] getBytesFromClass(String className) throws ClassNotFoundException, IOException {
+ JavaClass clazz = getTestClass(className);
+ ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
+
+ Method[] methods = clazz.getMethods();
+
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ if (!method.isNative() && !method.isAbstract())
+ methods[i] = injection(clazz, method, cp, findFirstStringLocalVariableOffset(method));
+ }
+
+ clazz.setConstantPool(cp.getFinalConstantPool());
+
+ return clazz.getBytes();
+ }
+
+ public Method injection(JavaClass clazz, Method method, ConstantPoolGen cp, int firstStringOffset) {
+ MethodGen methodGen = new MethodGen(method, clazz.getClassName(), cp);
+
+ InstructionList instructionList = methodGen.getInstructionList();
+ instructionList.insert(instructionList.getStart(), makeWillBeAddedInstructionList(methodGen, firstStringOffset));
+
+ methodGen.setMaxStack();
+ methodGen.setMaxLocals();
+
+ method = methodGen.getMethod();
+ instructionList.dispose();
+
+ return method;
+ }
+
+ public InstructionList makeWillBeAddedInstructionList(MethodGen methodGen, int firstStringOffset) {
+ if (firstStringOffset == -1)
+ return new InstructionList();
+
+ LocalVariableGen localVariableGen = methodGen.getLocalVariables()[firstStringOffset];
+ Instruction instruction;
+
+ if (localVariableGen != null)
+ instruction = new ALOAD(localVariableGen.getIndex());
+ else
+ instruction = new ACONST_NULL();
+
+ return createPrintln(methodGen.getConstantPool(), instruction);
+ }
+
+ public InstructionList createPrintln(ConstantPoolGen cp, Instruction instruction) {
+ final InstructionList il = new InstructionList();
+
+ final int out = cp.addFieldref("java.lang.System", "out", "Ljava/io/PrintStream;");
+ final int println = cp.addMethodref("java.io.PrintStream", "println", "(Ljava/lang/String;)V");
+ il.append(new GETSTATIC(out));
+ il.append(instruction);
+ il.append(new INVOKEVIRTUAL(println));
+
+ return il;
+ }
+
+ public int findFirstStringLocalVariableOffset(Method method) {
+ Type[] argumentTypes = method.getArgumentTypes();
+ int offset = -1;
+
+ for (int i = 0, count = argumentTypes.length; i < count; i++) {
+ if (Type.STRING.getSignature().equals(argumentTypes[i].getSignature())) {
+ if (method.isStatic())
+ offset = i;
+ else
+ offset = i + 1;
+
+ break;
+ }
+ }
+
+ return offset;
+ }
+}
diff --git a/src/test/java/org/apache/bcel/data/SimpleClassHasMethodIncludeGenericArgument.java b/src/test/java/org/apache/bcel/data/SimpleClassHasMethodIncludeGenericArgument.java
new file mode 100644
index 00000000..c9acb259
--- /dev/null
+++ b/src/test/java/org/apache/bcel/data/SimpleClassHasMethodIncludeGenericArgument.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.bcel.data;
+
+import java.util.List;
+
+public class SimpleClassHasMethodIncludeGenericArgument {
+ public static void a(String a1, List<String> a2) {
+ }
+
+ public static void b(String b1, List b2) {
+ }
+
+ public static void c(String c1, String c2) {
+ }
+
+ public static void d(List<String> d1, String d2) {
+ }
+}