fit for kotlin auto generated accessor method

This commit is contained in:
金戟 2021-01-05 23:28:35 +08:00
parent 55ec1ca5b5
commit 0a1b46b352
6 changed files with 43 additions and 5 deletions

View File

@ -31,7 +31,7 @@ class DemoMockTest {
}
@MockMethod
private String staticFunc(DemoMock self) {
private String staticFunc(DemoMock ignore) {
return "_MOCK_TAIL";
}
@ -77,6 +77,7 @@ class DemoMockTest {
void should_able_to_mock_member_method() throws Exception {
assertEquals("{ \"res\": \"mock_hello_MOCK_TAIL\"}", demoMock.outerFunc("hello"));
verify("innerFunc").with("hello");
verify("staticFunc").with();
}
@Test

View File

@ -61,5 +61,9 @@ class DemoMock {
private fun staticFunc(): String {
return "_STATIC_TAIL"
}
// fun callStaticFunc(): String {
// return "CALL${staticFunc()}"
// }
}
}

View File

@ -26,7 +26,7 @@ internal class DemoMockTest {
private fun innerFunc(self: DemoMock, text: String) = "mock_$text"
@MockMethod
private fun staticFunc(self: DemoMock): String {
private fun staticFunc(ignore: DemoMock): String {
return "_MOCK_TAIL";
}
@ -72,8 +72,15 @@ internal class DemoMockTest {
fun should_able_to_mock_member_method() {
assertEquals("{ \"res\": \"mock_hello_MOCK_TAIL\"}", demoMock.outerFunc("hello"))
verify("innerFunc").with("hello")
verify("staticFunc").with()
}
// @Test
// fun should_able_to_mock_method_in_companion_object() {
// assertEquals("CALL_MOCK_TAIL", DemoMock.callStaticFunc())
// verify("staticFunc").with()
// }
@Test
fun should_able_to_mock_common_method() {
assertEquals("trim_string__sub_string__false", demoMock.commonFunc())

View File

@ -20,6 +20,9 @@ public class ConstPool {
public static final String CGLIB_CLASS_INFIX = "$$EnhancerBy";
public static final String KOTLIN_POSTFIX_COMPANION = "$Companion";
public static final String KOTLIN_PREFIX_ACCESS = "access$";
/**
* Name of the constructor method
*/

View File

@ -107,7 +107,10 @@ public class SourceClassHandler extends BaseClassHandler {
private MethodInfo getMemberInjectMethodName(Set<MethodInfo> memberInjectMethods, MethodInsnNode node) {
for (MethodInfo m : memberInjectMethods) {
String nodeOwner = ClassUtil.fitCompanionClassName(node.owner);
if (m.getClazz().equals(nodeOwner) && m.getName().equals(node.name) && m.getDesc().equals(node.desc)) {
String nodeName = ClassUtil.fitKotlinAccessorName(node.name);
// Kotlin accessor method will append a extra type parameter
String nodeDesc = nodeName.equals(node.name) ? node.desc : ClassUtil.removeFirstParameter(node.desc);
if (m.getClazz().equals(nodeOwner) && m.getName().equals(nodeName) && m.getDesc().equals(nodeDesc)) {
return m;
}
}

View File

@ -61,7 +61,7 @@ public class ClassUtil {
* @return is companion class or not
*/
public static boolean isCompanionClassName(String name) {
return name.endsWith("$Companion");
return name.endsWith(ConstPool.KOTLIN_POSTFIX_COMPANION);
}
/**
@ -70,7 +70,18 @@ public class ClassUtil {
* @return original name
*/
public static String fitCompanionClassName(String name) {
return name.replaceAll("\\$Companion$", "");
return isCompanionClassName(name) ?
name.substring(0, name.length() - ConstPool.KOTLIN_POSTFIX_COMPANION.length()) : name;
}
/**
* fit kotlin accessor method name to original name
* @param name a accessor name (which could be a common kotlin method)
* @return original name
*/
public static String fitKotlinAccessorName(String name) {
return name.startsWith(ConstPool.KOTLIN_PREFIX_ACCESS) ?
name.substring(ConstPool.KOTLIN_PREFIX_ACCESS.length()) : name;
}
/**
@ -198,6 +209,15 @@ public class ClassUtil {
return toSlashSeparatedName(className).substring(1, className.length() - 1);
}
/**
* remove first parameter from method descriptor
* @param desc original descriptor
* @return descriptor without first parameter
*/
public static String removeFirstParameter(String desc) {
return "(" + desc.substring(desc.indexOf(";") + 1);
}
private static String toDescriptor(Byte type, String objectType) {
return "(" + (char)type.byteValue() + ")L" + objectType + ";";
}