diff --git a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/MockClassHandler.java b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/MockClassHandler.java index 2d987a8..eb946e8 100644 --- a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/MockClassHandler.java +++ b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/MockClassHandler.java @@ -3,10 +3,7 @@ package com.alibaba.testable.agent.handler; import com.alibaba.testable.agent.constant.ByteCodeConst; import com.alibaba.testable.agent.constant.ConstPool; import com.alibaba.testable.agent.tool.ImmutablePair; -import com.alibaba.testable.agent.util.AnnotationUtil; -import com.alibaba.testable.agent.util.ClassUtil; -import com.alibaba.testable.agent.util.GlobalConfig; -import com.alibaba.testable.agent.util.MethodUtil; +import com.alibaba.testable.agent.util.*; import com.alibaba.testable.core.model.MockScope; import org.objectweb.asm.Label; import org.objectweb.asm.Type; @@ -47,9 +44,7 @@ public class MockClassHandler extends BaseClassWithContextHandler { injectRefFieldAndGetInstanceMethod(cn); for (MethodNode mn : cn.methods) { if (isMockMethod(mn)) { - mn.access &= ~ACC_PRIVATE; - mn.access &= ~ACC_PROTECTED; - mn.access |= ACC_PUBLIC; + mn.access = BytecodeUtil.toPublicAccess(mn.access); // firstly, unfold target class from annotation to parameter unfoldTargetClass(mn); // secondly, add invoke recorder at the beginning of mock method @@ -165,7 +160,7 @@ public class MockClassHandler extends BaseClassWithContextHandler { il.add(new JumpInsnNode(IFNE, firstLine)); il.add(invokeOriginalMethod(mn)); il.add(firstLine); - il.add( new FrameNode(F_SAME, 0, null, 0, null)); + il.add(new FrameNode(F_SAME, 0, null, 0, null)); mn.instructions.insertBefore(mn.instructions.getFirst(), il); } @@ -181,7 +176,7 @@ public class MockClassHandler extends BaseClassWithContextHandler { if (VOID_RES.equals(returnType)) { il.add(new InsnNode(POP)); il.add(new InsnNode(RETURN)); - } else if (returnType.charAt(0) == TYPE_ARRAY ||returnType.charAt(0) == TYPE_CLASS) { + } else if (returnType.charAt(0) == TYPE_ARRAY || returnType.charAt(0) == TYPE_CLASS) { il.add(new TypeInsnNode(CHECKCAST, ClassUtil.toSlashSeparateJavaStyleName(returnType))); il.add(new InsnNode(ARETURN)); } else { diff --git a/testable-agent/src/main/java/com/alibaba/testable/agent/transformer/TestableClassTransformer.java b/testable-agent/src/main/java/com/alibaba/testable/agent/transformer/TestableClassTransformer.java index 5452079..2c0cbb4 100644 --- a/testable-agent/src/main/java/com/alibaba/testable/agent/transformer/TestableClassTransformer.java +++ b/testable-agent/src/main/java/com/alibaba/testable/agent/transformer/TestableClassTransformer.java @@ -27,8 +27,7 @@ import static com.alibaba.testable.agent.constant.ConstPool.KOTLIN_POSTFIX_COMPA import static com.alibaba.testable.core.constant.ConstPool.*; import static com.alibaba.testable.agent.util.ClassUtil.toJavaStyleClassName; import static com.alibaba.testable.core.constant.ConstPool.TEST_POSTFIX; -import static org.objectweb.asm.Opcodes.ACC_PUBLIC; -import static org.objectweb.asm.Opcodes.ACC_STATIC; +import static org.objectweb.asm.Opcodes.*; /** * @author flin @@ -194,12 +193,12 @@ public class TestableClassTransformer implements ClassFileTransformer { */ private String lookForInnerMockClass(ClassNode cn) { for (InnerClassNode ic : cn.innerClasses) { - if ((ic.access & ACC_PUBLIC) != 0 && ic.name.equals(getInnerMockClassName(cn.name)) && - mockClassParser.isMockClass(ic.name)) { - if ((ic.access & ACC_STATIC) != 0) { - return ic.name; - } else { + if (ic.name.equals(getInnerMockClassName(cn.name)) && mockClassParser.isMockClass(ic.name)) { + if ((ic.access & ACC_STATIC) == 0) { LogUtil.warn(String.format("Mock class in \"%s\" is not declared as static", cn.name)); + } else { + ic.access = BytecodeUtil.toPublicAccess(ic.access); + return ic.name; } } } diff --git a/testable-agent/src/main/java/com/alibaba/testable/agent/util/BytecodeUtil.java b/testable-agent/src/main/java/com/alibaba/testable/agent/util/BytecodeUtil.java index 4885ca3..ebe3896 100644 --- a/testable-agent/src/main/java/com/alibaba/testable/agent/util/BytecodeUtil.java +++ b/testable-agent/src/main/java/com/alibaba/testable/agent/util/BytecodeUtil.java @@ -173,8 +173,24 @@ public class BytecodeUtil { put(IFNONNULL, -1); }}; + /** + * Get stack impact of a specified ops code + * @param bytecode ops code to check + * @return stack change + */ public static int stackEffect(int bytecode) { return bytecodeStackEffect.get(bytecode); } + /** + * Make sure method has public access + * @param access original access mark + * @return access mark with public flag + */ + public static int toPublicAccess(int access) { + access &= ~ACC_PRIVATE; + access &= ~ACC_PROTECTED; + access |= ACC_PUBLIC; + return access; + } } diff --git a/testable-agent/src/main/java/com/alibaba/testable/agent/util/ClassUtil.java b/testable-agent/src/main/java/com/alibaba/testable/agent/util/ClassUtil.java index 80904e6..a719746 100644 --- a/testable-agent/src/main/java/com/alibaba/testable/agent/util/ClassUtil.java +++ b/testable-agent/src/main/java/com/alibaba/testable/agent/util/ClassUtil.java @@ -79,7 +79,7 @@ public class ClassUtil { } /** - * fit kotlin companion class name to original name + * Fit kotlin companion class name to original name * @param name a class name (which could be a companion class) * @return is companion class or not */ @@ -88,7 +88,7 @@ public class ClassUtil { } /** - * fit kotlin companion class name to original name + * Fit kotlin companion class name to original name * @param name a class name (which could be a companion class) * @return original name */ @@ -98,7 +98,7 @@ public class ClassUtil { } /** - * fit kotlin accessor method name to original name + * Fit kotlin accessor method name to original name * @param name a accessor name (which could be a common kotlin method) * @return original name */ @@ -108,7 +108,7 @@ public class ClassUtil { } /** - * get mock class name from source class name + * Get mock class name from source class name * @param sourceClassName source class name * @return mock class name */ @@ -117,7 +117,7 @@ public class ClassUtil { } /** - * get test class name from source class name + * Get test class name from source class name * @param sourceClassName source class name * @return test class name */ @@ -126,7 +126,7 @@ public class ClassUtil { } /** - * get source class name from test class name + * Get source class name from test class name * @param testClassName test class name * @return source class name */ @@ -135,7 +135,7 @@ public class ClassUtil { } /** - * get wrapper class of specified private type + * Get wrapper class of specified private type * @param primaryType byte code of private type * @return byte code of wrapper class */ @@ -144,7 +144,7 @@ public class ClassUtil { } /** - * get method name and descriptor to convert wrapper type to primary type + * Get method name and descriptor to convert wrapper type to primary type * @param primaryType byte code of private type * @return pair of [method-name, method-descriptor] */ @@ -153,7 +153,7 @@ public class ClassUtil { } /** - * get byte code for return specified private type + * Get byte code for return specified private type * @param type class type * @return byte code of return operation */ @@ -163,7 +163,7 @@ public class ClassUtil { } /** - * get method node to convert primary type to wrapper type + * Get method node to convert primary type to wrapper type * @param type primary type to convert * @return converter method node */ @@ -174,7 +174,7 @@ public class ClassUtil { } /** - * convert slash separated name to dot separated name + * Convert slash separated name to dot separated name * @param name original name * @return converted name */ @@ -183,7 +183,7 @@ public class ClassUtil { } /** - * convert dot separated name to slash separated name + * Convert dot separated name to slash separated name * @param name original name * @return converted name */ @@ -192,7 +192,7 @@ public class ClassUtil { } /** - * convert dot separated name to byte code class name + * Convert dot separated name to byte code class name * @param className original name * @return converted name */ @@ -201,7 +201,7 @@ public class ClassUtil { } /** - * convert byte code class name to slash separated human readable name + * Convert byte code class name to slash separated human readable name * @param className original name * @return converted name */ @@ -210,7 +210,7 @@ public class ClassUtil { } /** - * convert byte code class name to dot separated human readable name + * Convert byte code class name to dot separated human readable name * @param className original name * @return converted name */ diff --git a/testable-agent/src/main/java/com/alibaba/testable/agent/util/MethodUtil.java b/testable-agent/src/main/java/com/alibaba/testable/agent/util/MethodUtil.java index f3e671d..94476cd 100644 --- a/testable-agent/src/main/java/com/alibaba/testable/agent/util/MethodUtil.java +++ b/testable-agent/src/main/java/com/alibaba/testable/agent/util/MethodUtil.java @@ -22,7 +22,7 @@ public class MethodUtil { } /** - * parse method desc, fetch parameter types + * Parse method desc, fetch parameter types * @param desc method description * @return list of parameter types */ @@ -55,7 +55,7 @@ public class MethodUtil { } /** - * extract parameter part of method desc + * Extract parameter part of method desc * @param desc method description * @return parameter value */ @@ -65,7 +65,7 @@ public class MethodUtil { } /** - * parse method desc, fetch return value types + * Parse method desc, fetch return value types * @param desc method description * @return types of return value */ @@ -75,7 +75,7 @@ public class MethodUtil { } /** - * parse method desc, fetch first parameter type (assume first parameter is an object type) + * Parse method desc, fetch first parameter type (assume first parameter is an object type) * @param desc method description * @return types of first parameter */ @@ -85,7 +85,7 @@ public class MethodUtil { } /** - * remove first parameter from method descriptor + * Remove first parameter from method descriptor * @param desc original descriptor * @return descriptor without first parameter */ @@ -94,7 +94,7 @@ public class MethodUtil { } /** - * add extra parameter to the beginning of method descriptor + * Add extra parameter to the beginning of method descriptor * @param desc original descriptor * @param type byte code class name * @return descriptor with specified parameter at begin @@ -109,7 +109,7 @@ public class MethodUtil { } /** - * format to java style constructor descriptor + * Format to java style constructor descriptor * @param owner class of method belongs to * @param desc method constructor in bytecode format * @return java style constructor descriptor @@ -121,7 +121,7 @@ public class MethodUtil { } /** - * format to java style method descriptor + * Format to java style method descriptor * @param owner class of method belongs to * @param name method name * @param desc method descriptor in bytecode format @@ -135,7 +135,7 @@ public class MethodUtil { } /** - * convert bytecode style parameter descriptor to java style descriptor + * Convert bytecode style parameter descriptor to java style descriptor * @param desc bytecode style descriptor * @return java style descriptor */