mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-01-27 12:51:00 +08:00
fit kotlin companion object as static method
This commit is contained in:
parent
0ef13a8e95
commit
36136e878e
@ -84,7 +84,8 @@ public class SourceClassHandler extends BaseClassHandler {
|
|||||||
|
|
||||||
private String getMemberInjectMethodName(List<MethodInfo> memberInjectMethodList, MethodInsnNode node) {
|
private String getMemberInjectMethodName(List<MethodInfo> memberInjectMethodList, MethodInsnNode node) {
|
||||||
for (MethodInfo m : memberInjectMethodList) {
|
for (MethodInfo m : memberInjectMethodList) {
|
||||||
if (m.getClazz().equals(node.owner) && m.getName().equals(node.name) && m.getDesc().equals(node.desc)) {
|
String nodeOwner = ClassUtil.fitCompanionClassName(node.owner);
|
||||||
|
if (m.getClazz().equals(nodeOwner) && m.getName().equals(node.name) && m.getDesc().equals(node.desc)) {
|
||||||
return m.getMockName();
|
return m.getMockName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,16 +167,24 @@ public class SourceClassHandler extends BaseClassHandler {
|
|||||||
String testClassName = ClassUtil.getTestClassName(cn.name);
|
String testClassName = ClassUtil.getTestClassName(cn.name);
|
||||||
mn.instructions.insertBefore(instructions[start], new FieldInsnNode(GETSTATIC, testClassName,
|
mn.instructions.insertBefore(instructions[start], new FieldInsnNode(GETSTATIC, testClassName,
|
||||||
ConstPool.TESTABLE_INJECT_REF, ClassUtil.toByteCodeClassName(testClassName)));
|
ConstPool.TESTABLE_INJECT_REF, ClassUtil.toByteCodeClassName(testClassName)));
|
||||||
if (Opcodes.INVOKESTATIC == opcode) {
|
if (Opcodes.INVOKESTATIC == opcode || isCompanionMethod(ownerClass, opcode)) {
|
||||||
// append a null value if it was a static invoke
|
// append a null value if it was a static invoke or in kotlin companion class
|
||||||
mn.instructions.insertBefore(instructions[start], new InsnNode(ACONST_NULL));
|
mn.instructions.insertBefore(instructions[start], new InsnNode(ACONST_NULL));
|
||||||
|
if (ClassUtil.isCompanionClassName(ownerClass)) {
|
||||||
|
// for kotlin companion class, remove the byte code of reference to "companion" static field
|
||||||
|
mn.instructions.remove(instructions[end - 1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mn.instructions.insertBefore(instructions[end], new MethodInsnNode(INVOKEVIRTUAL, testClassName,
|
mn.instructions.insertBefore(instructions[end], new MethodInsnNode(INVOKEVIRTUAL, testClassName,
|
||||||
substitutionMethod, addFirstParameter(method.desc, ownerClass), false));
|
substitutionMethod, addFirstParameter(method.desc, ClassUtil.fitCompanionClassName(ownerClass)), false));
|
||||||
mn.instructions.remove(instructions[end]);
|
mn.instructions.remove(instructions[end]);
|
||||||
return mn.instructions.toArray();
|
return mn.instructions.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isCompanionMethod(String ownerClass, int opcode) {
|
||||||
|
return Opcodes.INVOKEVIRTUAL == opcode && ClassUtil.isCompanionClassName(ownerClass);
|
||||||
|
}
|
||||||
|
|
||||||
private String addFirstParameter(String desc, String ownerClass) {
|
private String addFirstParameter(String desc, String ownerClass) {
|
||||||
return "(" + ClassUtil.toByteCodeClassName(ownerClass) + desc.substring(1);
|
return "(" + ClassUtil.toByteCodeClassName(ownerClass) + desc.substring(1);
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,22 @@ public class ClassUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fit kotlin companion class name to original name
|
||||||
|
* @param name a class name (which could be a companion class)
|
||||||
|
*/
|
||||||
|
public static boolean isCompanionClassName(String name) {
|
||||||
|
return name.endsWith("$Companion");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fit kotlin companion class name to original name
|
||||||
|
* @param name a class name (which could be a companion class)
|
||||||
|
*/
|
||||||
|
public static String fitCompanionClassName(String name) {
|
||||||
|
return name.replaceAll("\\$Companion$", "");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get test class name from source class name
|
* get test class name from source class name
|
||||||
* @param sourceClassName source class name
|
* @param sourceClassName source class name
|
||||||
|
@ -40,5 +40,17 @@ class ClassUtilTest {
|
|||||||
assertEquals("Ljava/lang/String;", ClassUtil.toByteCodeClassName("java.lang.String"));
|
assertEquals("Ljava/lang/String;", ClassUtil.toByteCodeClassName("java.lang.String"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_able_to_fit_companion_class_name() {
|
||||||
|
assertEquals("com/intellij/rt/debugger/agent/CaptureAgent$ParamKeyProvider",
|
||||||
|
ClassUtil.fitCompanionClassName("com/intellij/rt/debugger/agent/CaptureAgent$ParamKeyProvider"));
|
||||||
|
assertEquals("com/alibaba/testable/demo/BlackBox",
|
||||||
|
ClassUtil.fitCompanionClassName("com/alibaba/testable/demo/BlackBox"));
|
||||||
|
assertEquals("com/alibaba/testable/demo/BlackBox$Companion",
|
||||||
|
ClassUtil.fitCompanionClassName("com/alibaba/testable/demo/BlackBox$Companion$Companion"));
|
||||||
|
assertEquals("com/alibaba/testable/demo/BlackBox",
|
||||||
|
ClassUtil.fitCompanionClassName("com/alibaba/testable/demo/BlackBox$Companion"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user