mockit.internal.util.TypeConversion Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jmockit Show documentation
Show all versions of jmockit Show documentation
JMockit is a Java toolkit for automated developer testing.
It contains APIs for the creation of the objects to be tested, for mocking dependencies, and for faking external
APIs; JUnit (4 & 5) and TestNG test runners are supported.
It also contains an advanced code coverage tool.
/*
* Copyright (c) 2006 Rogério Liesenfeld
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit.internal.util;
import javax.annotation.*;
import mockit.external.asm.*;
import static mockit.external.asm.Opcodes.*;
public final class TypeConversion
{
private static final String[] PRIMITIVE_WRAPPER_TYPE = {
null, "java/lang/Boolean", "java/lang/Character", "java/lang/Byte", "java/lang/Short", "java/lang/Integer",
"java/lang/Float", "java/lang/Long", "java/lang/Double"
};
private static final String PRIMITIVE_WRAPPER_TYPES =
"java/lang/Boolean java/lang/Character java/lang/Byte java/lang/Short " +
"java/lang/Integer java/lang/Float java/lang/Long java/lang/Double";
private static final String[] UNBOXING_NAME = {
null, "booleanValue", "charValue", "byteValue", "shortValue", "intValue", "floatValue", "longValue", "doubleValue"
};
private static final String[] UNBOXING_DESC = {null, "()Z", "()C", "()B", "()S", "()I", "()F", "()J", "()D"};
private TypeConversion() {}
public static void generateCastToObject(@Nonnull MethodVisitor mv, @Nonnull JavaType type)
{
int sort = type.getSort();
if (sort < JavaType.Sort.ARRAY) {
String wrapperType = PRIMITIVE_WRAPPER_TYPE[sort];
String desc = '(' + type.getDescriptor() + ")L" + wrapperType + ';';
mv.visitMethodInsn(INVOKESTATIC, wrapperType, "valueOf", desc, false);
}
}
public static void generateCastFromObject(@Nonnull MethodVisitor mv, @Nonnull JavaType toType)
{
int sort = toType.getSort();
if (sort == JavaType.Sort.VOID) {
mv.visitInsn(POP);
}
else {
generateTypeCheck(mv, toType);
if (sort < JavaType.Sort.ARRAY) {
mv.visitMethodInsn(
INVOKEVIRTUAL, PRIMITIVE_WRAPPER_TYPE[sort], UNBOXING_NAME[sort], UNBOXING_DESC[sort], false);
}
}
}
private static void generateTypeCheck(@Nonnull MethodVisitor mv, @Nonnull JavaType toType)
{
int sort = toType.getSort();
String typeDesc;
switch (sort) {
case JavaType.Sort.ARRAY: typeDesc = toType.getDescriptor(); break;
case JavaType.Sort.OBJECT: typeDesc = toType.getInternalName(); break;
default: typeDesc = PRIMITIVE_WRAPPER_TYPE[sort];
}
mv.visitTypeInsn(CHECKCAST, typeDesc);
}
public static void generateCastOrUnboxing(@Nonnull MethodVisitor mv, @Nonnull JavaType parameterType, int opcode)
{
if (opcode == ASTORE) {
generateTypeCheck(mv, parameterType);
return;
}
int sort = parameterType.getSort();
String typeDesc;
if (sort < JavaType.Sort.ARRAY) {
typeDesc = PRIMITIVE_WRAPPER_TYPE[sort];
}
else {
typeDesc = parameterType.getInternalName();
int i = PRIMITIVE_WRAPPER_TYPES.indexOf(typeDesc);
if (i >= 0) {
sort = i / 20 + 1;
}
else if (opcode == ISTORE && "java/lang/Number".equals(typeDesc)) {
sort = JavaType.Sort.INT;
}
else {
sort = JavaType.Sort.INT;
//noinspection SwitchStatementWithoutDefaultBranch
switch (opcode) {
case FSTORE: sort = JavaType.Sort.FLOAT; break;
case LSTORE: sort = JavaType.Sort.LONG; break;
case DSTORE: sort = JavaType.Sort.DOUBLE;
}
typeDesc = PRIMITIVE_WRAPPER_TYPE[sort];
}
}
mv.visitTypeInsn(CHECKCAST, typeDesc);
mv.visitMethodInsn(INVOKEVIRTUAL, typeDesc, UNBOXING_NAME[sort], UNBOXING_DESC[sort], false);
}
public static boolean isPrimitiveWrapper(@Nonnull String typeDesc)
{
return PRIMITIVE_WRAPPER_TYPES.contains(typeDesc);
}
public static boolean isBoxing(@Nonnull String owner, @Nonnull String name, @Nonnull String desc)
{
return desc.charAt(2) == ')' && "valueOf".equals(name) && isPrimitiveWrapper(owner);
}
public static boolean isUnboxing(int opcode, @Nonnull String owner, @Nonnull String desc)
{
return opcode == INVOKEVIRTUAL && desc.charAt(1) == ')' && isPrimitiveWrapper(owner);
}
}