mirror of
https://github.com/alibaba/testable-mock.git
synced 2026-08-19 09:43:29 +08:00
feat: cache constructor parameter types for efficiency
This commit is contained in:
@@ -5,13 +5,16 @@ import com.alibaba.testable.agent.handler.test.JUnit5Framework;
|
|||||||
import com.alibaba.testable.agent.util.AnnotationUtil;
|
import com.alibaba.testable.agent.util.AnnotationUtil;
|
||||||
import com.alibaba.testable.agent.util.BytecodeUtil;
|
import com.alibaba.testable.agent.util.BytecodeUtil;
|
||||||
import com.alibaba.testable.agent.util.ClassUtil;
|
import com.alibaba.testable.agent.util.ClassUtil;
|
||||||
|
import com.alibaba.testable.core.exception.ClassConstructionException;
|
||||||
import com.alibaba.testable.core.util.CollectionUtil;
|
import com.alibaba.testable.core.util.CollectionUtil;
|
||||||
|
import com.alibaba.testable.core.util.LogUtil;
|
||||||
import com.alibaba.testable.core.util.StringUtil;
|
import com.alibaba.testable.core.util.StringUtil;
|
||||||
import com.alibaba.testable.core.util.TypeUtil;
|
import com.alibaba.testable.core.util.TypeUtil;
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.tree.*;
|
import org.objectweb.asm.tree.*;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -45,6 +48,8 @@ public class OmniClassHandler extends BaseClassHandler {
|
|||||||
JUnit4Framework.ANNOTATION_TEST, JUnit5Framework.ANNOTATION_TEST, JUnit5Framework.ANNOTATION_PARAMETERIZED_TEST
|
JUnit4Framework.ANNOTATION_TEST, JUnit5Framework.ANNOTATION_TEST, JUnit5Framework.ANNOTATION_PARAMETERIZED_TEST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static final Map<String, Class<?>[]> constructorParameterCache = new HashMap<String, Class<?>[]>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void transform(ClassNode cn) {
|
protected void transform(ClassNode cn) {
|
||||||
if (isInterfaceOrAtom(cn) || isUniqueConstructorClass(cn) || isUninstantiableClass(cn) ||
|
if (isInterfaceOrAtom(cn) || isUniqueConstructorClass(cn) || isUninstantiableClass(cn) ||
|
||||||
@@ -66,8 +71,12 @@ public class OmniClassHandler extends BaseClassHandler {
|
|||||||
extraParameterCount = PRELOADED_CLASSES.get(cn.superName).length;
|
extraParameterCount = PRELOADED_CLASSES.get(cn.superName).length;
|
||||||
} else if (cn.superName.startsWith("java/")) {
|
} else if (cn.superName.startsWith("java/")) {
|
||||||
try {
|
try {
|
||||||
Class<?> superClazz = Class.forName(ClassUtil.toDotSeparatedName(cn.superName));
|
Class<?>[] constructorParameterTypes = constructorParameterCache.get(cn.superName);
|
||||||
Class<?>[] constructorParameterTypes = TypeUtil.getBestConstructor(superClazz).getParameterTypes();
|
if (constructorParameterTypes == null) {
|
||||||
|
Class<?> superClazz = Class.forName(ClassUtil.toDotSeparatedName(cn.superName));
|
||||||
|
constructorParameterTypes = TypeUtil.getBestConstructor(superClazz).getParameterTypes();
|
||||||
|
constructorParameterCache.put(superClazz.getName(), constructorParameterTypes);
|
||||||
|
}
|
||||||
if (constructorParameterTypes.length == 0) {
|
if (constructorParameterTypes.length == 0) {
|
||||||
constructor.instructions = invokeSuperWithoutTestableParameter(cn.superName, new String[0], start, end);
|
constructor.instructions = invokeSuperWithoutTestableParameter(cn.superName, new String[0], start, end);
|
||||||
extraParameterCount = 0;
|
extraParameterCount = 0;
|
||||||
@@ -80,7 +89,8 @@ public class OmniClassHandler extends BaseClassHandler {
|
|||||||
extraParameterCount = constructorParameterTypes.length;
|
extraParameterCount = constructorParameterTypes.length;
|
||||||
}
|
}
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
constructor.instructions = invokeSuperWithTestableVoidParameter(cn.superName, start, end);
|
LogUtil.warn("[OmniConstructor] Failed to load class " + cn.superName);
|
||||||
|
constructor.instructions = invokeSuperWithoutTestableParameter(cn.superName, new String[0], start, end);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
constructor.instructions = invokeSuperWithTestableVoidParameter(cn.superName, start, end);
|
constructor.instructions = invokeSuperWithTestableVoidParameter(cn.superName, start, end);
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ public class BytecodeUtil {
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Java primitive type name to bytecode mapping
|
* java primitive type name to bytecode mapping
|
||||||
*/
|
*/
|
||||||
public static Map<String, String> PRIMITIVE_TYPE_NAME_MAP = new HashMap<String, String>() {{
|
public static Map<String, String> PRIMITIVE_TYPE_NAME_MAP = new HashMap<String, String>() {{
|
||||||
put("byte", String.valueOf((char)TYPE_BYTE));
|
put("byte", String.valueOf((char)TYPE_BYTE));
|
||||||
@@ -202,7 +202,7 @@ public class BytecodeUtil {
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get stack impact of a specified ops code
|
* get stack impact of a specified ops code
|
||||||
* @param bytecode ops code to check
|
* @param bytecode ops code to check
|
||||||
* @return stack change
|
* @return stack change
|
||||||
*/
|
*/
|
||||||
@@ -211,7 +211,7 @@ public class BytecodeUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make sure method has public access
|
* make sure method has public access
|
||||||
* @param access original access mark
|
* @param access original access mark
|
||||||
* @return access mark with public flag
|
* @return access mark with public flag
|
||||||
*/
|
*/
|
||||||
@@ -223,7 +223,7 @@ public class BytecodeUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dump byte code to specified class file
|
* dump byte code to specified class file
|
||||||
* @param cn original class node
|
* @param cn original class node
|
||||||
* @param dumpPath folder to store class file
|
* @param dumpPath folder to store class file
|
||||||
* @param bytes original class bytes
|
* @param bytes original class bytes
|
||||||
|
|||||||
Reference in New Issue
Block a user