support construction options

This commit is contained in:
金戟 2021-04-25 23:27:51 +08:00
parent d11402dd6c
commit 75c6a67b8f
4 changed files with 37 additions and 14 deletions

View File

@ -7,13 +7,12 @@ import com.alibaba.testable.agent.util.CollectionUtil;
import org.objectweb.asm.Label;
import org.objectweb.asm.tree.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static com.alibaba.testable.agent.util.ClassUtil.CLASS_OBJECT;
import static com.alibaba.testable.core.constant.ConstPool.CONSTRUCTOR;
import static com.alibaba.testable.core.constant.ConstPool.THIS_REF;
import static com.alibaba.testable.core.util.CollectionUtil.contains;
/**
* @author flin
@ -32,9 +31,9 @@ public class OmniClassHandler extends BaseClassHandler {
private static final String[] JUNIT_TEST_ANNOTATIONS = new String[] {
JUnit4Framework.ANNOTATION_TEST, JUnit5Framework.ANNOTATION_TEST, JUnit5Framework.ANNOTATION_PARAMETERIZED_TEST
};
private static final Set<String> UNREACHABLE_CLASSES = new HashSet<String>() {{
add(CLASS_ABSTRACT_COLLECTION); add(CLASS_NUMBER);
}};
private static final String[] UNREACHABLE_CLASSES = new String[] {
CLASS_ABSTRACT_COLLECTION, CLASS_NUMBER
};
@Override
protected void transform(ClassNode cn) {
@ -96,10 +95,8 @@ public class OmniClassHandler extends BaseClassHandler {
continue;
}
for (AnnotationNode an : mn.visibleAnnotations) {
for (String annotation : JUNIT_TEST_ANNOTATIONS) {
if (an.desc.equals(annotation)) {
return true;
}
if (contains(JUNIT_TEST_ANNOTATIONS, an.desc)) {
return true;
}
}
}
@ -120,7 +117,7 @@ public class OmniClassHandler extends BaseClassHandler {
InsnList il = new InsnList();
il.add(start);
il.add(new VarInsnNode(ALOAD, 0));
if (UNREACHABLE_CLASSES.contains(cn.superName)) {
if (contains(UNREACHABLE_CLASSES, cn.superName)) {
il.add(new MethodInsnNode(INVOKESPECIAL, cn.superName, CONSTRUCTOR, VOID_METHOD, false));
} else {
il.add(new VarInsnNode(ALOAD, 1));

View File

@ -0,0 +1,7 @@
package com.alibaba.testable.core.model;
public enum ConstructionOption {
ALLOW_NULL_FOR_NESTED_TYPE
}

View File

@ -1,6 +1,8 @@
package com.alibaba.testable.core.tool;
import com.alibaba.testable.core.exception.ClassConstructionException;
import com.alibaba.testable.core.model.ConstructionOption;
import com.alibaba.testable.core.util.CollectionUtil;
import com.alibaba.testable.core.util.LogUtil;
import com.alibaba.testable.core.util.TypeUtil;
@ -8,6 +10,7 @@ import java.lang.reflect.*;
import java.util.*;
import static com.alibaba.testable.core.constant.ConstPool.DOLLAR;
import static com.alibaba.testable.core.model.ConstructionOption.ALLOW_NULL_FOR_NESTED_TYPE;
/**
* @author flin
@ -25,8 +28,12 @@ public class OmniConstructor {
* @param clazz 期望的对象类型
* @return 返回新创建的对象
*/
public static <T> T newInstance(Class<T> clazz) {
return handleCircleReference(newInstance(clazz, new HashSet<Class<?>>(INITIAL_CAPACITY)));
public static <T> T newInstance(Class<T> clazz, ConstructionOption... options) {
T ins = newInstance(clazz, new HashSet<Class<?>>(INITIAL_CAPACITY));
if (ins == null || CollectionUtil.contains(options, ALLOW_NULL_FOR_NESTED_TYPE)) {
return ins;
}
return handleCircleReference(ins);
}
/**
@ -36,8 +43,12 @@ public class OmniConstructor {
* @param size 数组大小
* @return 返回新创建的对象数组
*/
public static <T> T[] newArray(Class<T> clazz, int size) {
return (T[])handleCircleReference(newArray(clazz, size, new HashSet<Class<?>>(INITIAL_CAPACITY)));
public static <T> T[] newArray(Class<T> clazz, int size, ConstructionOption... options) {
T[] array = (T[])newArray(clazz, size, new HashSet<Class<?>>(INITIAL_CAPACITY));
if (CollectionUtil.contains(options, ALLOW_NULL_FOR_NESTED_TYPE)) {
return array;
}
return handleCircleReference(array);
}
private static <T> T newInstance(Class<T> clazz, Set<Class<?>> classPool) {

View File

@ -25,4 +25,12 @@ public class CollectionUtil {
return sb.toString();
}
public static <T> boolean contains(T[] collection, T target) {
for (T item : collection) {
if (target.equals(item)) {
return true;
}
}
return false;
}
}