mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-01-24 11:20:26 +08:00
use void type instead of null type
This commit is contained in:
parent
af409a65a8
commit
78d7ee21a6
@ -18,8 +18,7 @@ import static com.alibaba.testable.core.constant.ConstPool.THIS_REF;
|
|||||||
*/
|
*/
|
||||||
public class OmniClassHandler extends BaseClassHandler {
|
public class OmniClassHandler extends BaseClassHandler {
|
||||||
|
|
||||||
private static final String TESTABLE_NULL_TYPE = "com.alibaba.testable.core.model.TestableNull";
|
private static final String VOID_TYPE = "java/lang/Void";
|
||||||
private static final String NULL_TYPE = "javax.lang.model.type.NullType";
|
|
||||||
private static final String IGNORE = "ignore";
|
private static final String IGNORE = "ignore";
|
||||||
private static final String METHOD_START = "(";
|
private static final String METHOD_START = "(";
|
||||||
private static final String VOID_METHOD_END = ")V";
|
private static final String VOID_METHOD_END = ")V";
|
||||||
@ -35,12 +34,12 @@ public class OmniClassHandler extends BaseClassHandler {
|
|||||||
if (isInterface(cn) || isJunitTestClass(cn) || isUninstantiableClass(cn) || hasSpecialAnnotation(cn)) {
|
if (isInterface(cn) || isJunitTestClass(cn) || isUninstantiableClass(cn) || hasSpecialAnnotation(cn)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addConstructorWithNullTypeParameter(cn);
|
addConstructorWithVoidTypeParameter(cn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addConstructorWithNullTypeParameter(ClassNode cn) {
|
private void addConstructorWithVoidTypeParameter(ClassNode cn) {
|
||||||
MethodNode constructor = new MethodNode(ACC_PUBLIC, CONSTRUCTOR,
|
MethodNode constructor = new MethodNode(ACC_PUBLIC, CONSTRUCTOR,
|
||||||
METHOD_START + ClassUtil.toByteCodeClassName(NULL_TYPE) + VOID_METHOD_END, null, null);
|
METHOD_START + ClassUtil.toByteCodeClassName(VOID_TYPE) + VOID_METHOD_END, null, null);
|
||||||
LabelNode start = new LabelNode(new Label());
|
LabelNode start = new LabelNode(new Label());
|
||||||
LabelNode end = new LabelNode(new Label());
|
LabelNode end = new LabelNode(new Label());
|
||||||
if (cn.superName.equals(CLASS_OBJECT)) {
|
if (cn.superName.equals(CLASS_OBJECT)) {
|
||||||
@ -48,7 +47,7 @@ public class OmniClassHandler extends BaseClassHandler {
|
|||||||
constructor.localVariables = createLocalVariables(cn, start, end);
|
constructor.localVariables = createLocalVariables(cn, start, end);
|
||||||
constructor.maxStack = 1;
|
constructor.maxStack = 1;
|
||||||
} else {
|
} else {
|
||||||
constructor.instructions = invokeSuperWithTestableNullParameter(cn, start, end);
|
constructor.instructions = invokeSuperWithTestableVoidParameter(cn, start, end);
|
||||||
constructor.localVariables = createLocalVariables(cn, start, end);
|
constructor.localVariables = createLocalVariables(cn, start, end);
|
||||||
constructor.maxStack = 3;
|
constructor.maxStack = 3;
|
||||||
}
|
}
|
||||||
@ -79,8 +78,8 @@ public class OmniClassHandler extends BaseClassHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInterface(ClassNode cn) {
|
private boolean isInterface(ClassNode cn) {
|
||||||
// is interface or the object class
|
// is interface, Object class or Void class
|
||||||
return (cn.access & ACC_INTERFACE) != 0 || cn.superName == null;
|
return (cn.access & ACC_INTERFACE) != 0 || cn.superName == null || VOID_TYPE.equals(cn.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isJunitTestClass(ClassNode cn) {
|
private boolean isJunitTestClass(ClassNode cn) {
|
||||||
@ -110,16 +109,13 @@ public class OmniClassHandler extends BaseClassHandler {
|
|||||||
return il;
|
return il;
|
||||||
}
|
}
|
||||||
|
|
||||||
private InsnList invokeSuperWithTestableNullParameter(ClassNode cn, LabelNode start, LabelNode end) {
|
private InsnList invokeSuperWithTestableVoidParameter(ClassNode cn, LabelNode start, LabelNode end) {
|
||||||
InsnList il = new InsnList();
|
InsnList il = new InsnList();
|
||||||
il.add(start);
|
il.add(start);
|
||||||
il.add(new VarInsnNode(ALOAD, 0));
|
il.add(new VarInsnNode(ALOAD, 0));
|
||||||
il.add(new TypeInsnNode(NEW, ClassUtil.toSlashSeparatedName(TESTABLE_NULL_TYPE)));
|
il.add(new VarInsnNode(ALOAD, 1));
|
||||||
il.add(new InsnNode(DUP));
|
|
||||||
il.add(new MethodInsnNode(INVOKESPECIAL, ClassUtil.toSlashSeparatedName(TESTABLE_NULL_TYPE), CONSTRUCTOR,
|
|
||||||
VOID_METHOD, false));
|
|
||||||
il.add(new MethodInsnNode(INVOKESPECIAL, cn.superName, CONSTRUCTOR,
|
il.add(new MethodInsnNode(INVOKESPECIAL, cn.superName, CONSTRUCTOR,
|
||||||
METHOD_START + ClassUtil.toByteCodeClassName(NULL_TYPE) + VOID_METHOD_END, false));
|
METHOD_START + ClassUtil.toByteCodeClassName(VOID_TYPE) + VOID_METHOD_END, false));
|
||||||
il.add(new InsnNode(RETURN));
|
il.add(new InsnNode(RETURN));
|
||||||
il.add(end);
|
il.add(end);
|
||||||
return il;
|
return il;
|
||||||
@ -128,7 +124,7 @@ public class OmniClassHandler extends BaseClassHandler {
|
|||||||
private List<LocalVariableNode> createLocalVariables(ClassNode cn, LabelNode start, LabelNode end) {
|
private List<LocalVariableNode> createLocalVariables(ClassNode cn, LabelNode start, LabelNode end) {
|
||||||
return CollectionUtil.listOf(
|
return CollectionUtil.listOf(
|
||||||
new LocalVariableNode(THIS_REF, ClassUtil.toByteCodeClassName(cn.name), null, start, end, 0),
|
new LocalVariableNode(THIS_REF, ClassUtil.toByteCodeClassName(cn.name), null, start, end, 0),
|
||||||
new LocalVariableNode(IGNORE, ClassUtil.toByteCodeClassName(NULL_TYPE), null, start, end, 1)
|
new LocalVariableNode(IGNORE, ClassUtil.toByteCodeClassName(VOID_TYPE), null, start, end, 1)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
package com.alibaba.testable.core.model;
|
|
||||||
|
|
||||||
import javax.lang.model.element.AnnotationMirror;
|
|
||||||
import javax.lang.model.type.NullType;
|
|
||||||
import javax.lang.model.type.TypeKind;
|
|
||||||
import javax.lang.model.type.TypeVisitor;
|
|
||||||
import java.lang.annotation.Annotation;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author flin
|
|
||||||
*/
|
|
||||||
public class TestableNull implements NullType {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeKind getKind() {
|
|
||||||
return TypeKind.NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <R, P> R accept(TypeVisitor<R, P> v, P p) {
|
|
||||||
return v.visitNull(this, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<? extends AnnotationMirror> getAnnotationMirrors() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +1,9 @@
|
|||||||
package com.alibaba.testable.core.tool;
|
package com.alibaba.testable.core.tool;
|
||||||
|
|
||||||
import com.alibaba.testable.core.exception.ClassConstructionException;
|
import com.alibaba.testable.core.exception.ClassConstructionException;
|
||||||
import com.alibaba.testable.core.model.TestableNull;
|
|
||||||
import com.alibaba.testable.core.util.LogUtil;
|
import com.alibaba.testable.core.util.LogUtil;
|
||||||
import com.alibaba.testable.core.util.TypeUtil;
|
import com.alibaba.testable.core.util.TypeUtil;
|
||||||
|
|
||||||
import javax.lang.model.type.NullType;
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -193,8 +191,8 @@ public class OmniConstructor {
|
|||||||
throws InstantiationException, IllegalAccessException, InvocationTargetException {
|
throws InstantiationException, IllegalAccessException, InvocationTargetException {
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
Class<?>[] types = constructor.getParameterTypes();
|
Class<?>[] types = constructor.getParameterTypes();
|
||||||
if (types.length == 1 && types[0].equals(NullType.class)) {
|
if (types.length == 1 && types[0].equals(Void.class)) {
|
||||||
return constructor.newInstance(new TestableNull());
|
return constructor.newInstance(OmniConstructor.newInstance(Void.class));
|
||||||
} else {
|
} else {
|
||||||
Object[] args = new Object[types.length];
|
Object[] args = new Object[types.length];
|
||||||
for (int i = 0; i < types.length; i++) {
|
for (int i = 0; i < types.length; i++) {
|
||||||
@ -209,7 +207,7 @@ public class OmniConstructor {
|
|||||||
int minimalParametersSize = 999;
|
int minimalParametersSize = 999;
|
||||||
for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
|
for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
|
||||||
Class<?>[] types = constructor.getParameterTypes();
|
Class<?>[] types = constructor.getParameterTypes();
|
||||||
if (types.length == 1 && types[0].equals(NullType.class)) {
|
if (types.length == 1 && types[0].equals(Void.class)) {
|
||||||
return constructor;
|
return constructor;
|
||||||
} else if (types.length < minimalParametersSize && !anyMatch(types, clazz)) {
|
} else if (types.length < minimalParametersSize && !anyMatch(types, clazz)) {
|
||||||
minimalParametersSize = types.length;
|
minimalParametersSize = types.length;
|
||||||
|
Loading…
Reference in New Issue
Block a user