mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-01-10 12:20:09 +08:00
should handle frame byte code when mock substitutions
This commit is contained in:
parent
d49f526376
commit
190cf4cc3c
@ -84,6 +84,7 @@ public class SourceClassHandler extends BaseClassHandler {
|
||||
// it's a member or static method and an inject method for it exist
|
||||
int rangeStart = getMemberMethodStart(instructions, i);
|
||||
if (rangeStart >= 0) {
|
||||
handleFrameStackChange(mn, mockMethod, rangeStart, i);
|
||||
instructions = replaceMemberCallOps(mn, mockMethod,
|
||||
instructions, node.owner, node.getOpcode(), rangeStart, i);
|
||||
i = rangeStart;
|
||||
@ -249,6 +250,17 @@ public class SourceClassHandler extends BaseClassHandler {
|
||||
return mn.instructions.toArray();
|
||||
}
|
||||
|
||||
private void handleFrameStackChange(MethodNode mn, MethodInfo mockMethod, int start, int end) {
|
||||
AbstractInsnNode curInsn = mn.instructions.get(start);
|
||||
AbstractInsnNode endInsn = mn.instructions.get(end);
|
||||
do {
|
||||
if (curInsn instanceof FrameNode && ((FrameNode)curInsn).type == F_FULL) {
|
||||
((FrameNode)curInsn).stack.add(0, mockMethod.getMockClass());
|
||||
}
|
||||
curInsn = curInsn.getNext();
|
||||
} while (!curInsn.equals(endInsn));
|
||||
}
|
||||
|
||||
private boolean isCompanionMethod(String ownerClass, int opcode) {
|
||||
return Opcodes.INVOKEVIRTUAL == opcode && ClassUtil.isCompanionClassName(ownerClass);
|
||||
}
|
||||
|
@ -17,6 +17,10 @@ public class MethodInfo {
|
||||
* parameter and return value of the source method
|
||||
*/
|
||||
private final String desc;
|
||||
/**
|
||||
* name of the class where this mock method defined (in slash-separate format)
|
||||
*/
|
||||
private final String mockClass;
|
||||
/**
|
||||
* name of the mock method
|
||||
*/
|
||||
@ -30,10 +34,11 @@ public class MethodInfo {
|
||||
*/
|
||||
private final boolean isStatic;
|
||||
|
||||
public MethodInfo(String clazz, String name, String desc, String mockName, String mockDesc, boolean isStatic) {
|
||||
public MethodInfo(String clazz, String name, String desc, String mockClass, String mockName, String mockDesc, boolean isStatic) {
|
||||
this.clazz = clazz;
|
||||
this.name = name;
|
||||
this.desc = desc;
|
||||
this.mockClass = mockClass;
|
||||
this.mockName = mockName;
|
||||
this.mockDesc = mockDesc;
|
||||
this.isStatic = isStatic;
|
||||
@ -51,6 +56,10 @@ public class MethodInfo {
|
||||
return desc;
|
||||
}
|
||||
|
||||
public String getMockClass() {
|
||||
return mockClass;
|
||||
}
|
||||
|
||||
public String getMockName() {
|
||||
return mockName;
|
||||
}
|
||||
@ -74,6 +83,7 @@ public class MethodInfo {
|
||||
if (!clazz.equals(that.clazz)) { return false; }
|
||||
if (!name.equals(that.name)) { return false; }
|
||||
if (!desc.equals(that.desc)) { return false; }
|
||||
if (!mockClass.equals(that.mockClass)) { return false; }
|
||||
if (!mockName.equals(that.mockName)) { return false; }
|
||||
return mockDesc.equals(that.mockDesc);
|
||||
}
|
||||
@ -83,6 +93,7 @@ public class MethodInfo {
|
||||
int result = clazz.hashCode();
|
||||
result = 31 * result + name.hashCode();
|
||||
result = 31 * result + desc.hashCode();
|
||||
result = 31 * result + mockClass.hashCode();
|
||||
result = 31 * result + mockName.hashCode();
|
||||
result = 31 * result + mockDesc.hashCode();
|
||||
result = 31 * result + (isStatic ? 1 : 0);
|
||||
|
@ -96,7 +96,7 @@ public class MockClassParser {
|
||||
if (CONSTRUCTOR.equals(targetMethod)) {
|
||||
addMockConstructor(methodInfos, cn, mn);
|
||||
} else {
|
||||
MethodInfo mi = getMethodInfo(mn, an, targetMethod);
|
||||
MethodInfo mi = getMethodInfo(cn, mn, an, targetMethod);
|
||||
if (mi != null) {
|
||||
methodInfos.add(mi);
|
||||
}
|
||||
@ -112,7 +112,7 @@ public class MockClassParser {
|
||||
return type == null ? MethodUtil.removeFirstParameter(mn.desc) : mn.desc;
|
||||
}
|
||||
|
||||
private MethodInfo getMethodInfo(MethodNode mn, AnnotationNode an, String targetMethod) {
|
||||
private MethodInfo getMethodInfo(ClassNode cn, MethodNode mn, AnnotationNode an, String targetMethod) {
|
||||
Type targetType = AnnotationUtil.getAnnotationParameter(an, ConstPool.FIELD_TARGET_CLASS, null, Type.class);
|
||||
boolean isStatic = isStatic(mn);
|
||||
if (targetType == null) {
|
||||
@ -121,18 +121,19 @@ public class MockClassParser {
|
||||
if (methodDescPair == null) {
|
||||
return null;
|
||||
}
|
||||
return new MethodInfo(methodDescPair.left, targetMethod, methodDescPair.right, mn.name, mn.desc, isStatic);
|
||||
return new MethodInfo(methodDescPair.left, targetMethod, methodDescPair.right, cn.name, mn.name, mn.desc,
|
||||
isStatic);
|
||||
} else {
|
||||
// "targetClass" found, use it as target class type
|
||||
String slashSeparatedName = ClassUtil.toSlashSeparatedName(targetType.getClassName());
|
||||
return new MethodInfo(slashSeparatedName, targetMethod, mn.desc, mn.name,
|
||||
return new MethodInfo(slashSeparatedName, targetMethod, mn.desc, cn.name, mn.name,
|
||||
MethodUtil.addParameterAtBegin(mn.desc, ClassUtil.toByteCodeClassName(slashSeparatedName)), isStatic);
|
||||
}
|
||||
}
|
||||
|
||||
private void addMockConstructor(List<MethodInfo> methodInfos, ClassNode cn, MethodNode mn) {
|
||||
String sourceClassName = ClassUtil.getSourceClassName(cn.name);
|
||||
methodInfos.add(new MethodInfo(sourceClassName, CONSTRUCTOR, mn.desc, mn.name, mn.desc, isStatic(mn)));
|
||||
methodInfos.add(new MethodInfo(sourceClassName, CONSTRUCTOR, mn.desc, cn.name, mn.name, mn.desc, isStatic(mn)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user