allow non-public mock class

This commit is contained in:
金戟 2021-03-22 14:57:59 +08:00
parent 9064f7a582
commit 3feba7fdfa
5 changed files with 50 additions and 40 deletions

View File

@ -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 {

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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
*/

View File

@ -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
*/