mockit.internal.util.ParameterReflection Maven / Gradle / Ivy
/*
* Copyright (c) 2006-2012 Rogério Liesenfeld
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit.internal.util;
import java.lang.reflect.*;
import java.util.*;
public final class ParameterReflection
{
static final Class[] NO_PARAMETERS = new Class[0];
static String getParameterTypesDescription(Type[] paramTypes)
{
String paramTypesDesc = Arrays.asList(paramTypes).toString();
return paramTypesDesc.replace("class ", "").replace('[', '(').replace(']', ')');
}
public static Class[] getArgumentTypesFromArgumentValues(Object... args)
{
if (args.length == 0) {
return NO_PARAMETERS;
}
Class[] argTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
argTypes[i] = getArgumentTypeFromArgumentValue(i, args);
}
return argTypes;
}
private static Class getArgumentTypeFromArgumentValue(int i, Object[] args)
{
Object arg = args[i];
if (arg == null) {
throw new IllegalArgumentException("Invalid null value passed as argument " + i);
}
Class argType;
if (arg instanceof Class) {
argType = (Class) arg;
args[i] = null;
}
else {
argType = GeneratedClasses.getMockedClass(arg);
}
return argType;
}
public static Object[] argumentsWithExtraFirstValue(Object[] args, Object firstValue)
{
Object[] args2 = new Object[1 + args.length];
args2[0] = firstValue;
System.arraycopy(args, 0, args2, 1, args.length);
return args2;
}
static boolean hasMoreSpecificTypes(Class[] currentTypes, Class[] previousTypes)
{
for (int i = 0; i < currentTypes.length; i++) {
Class current = wrappedIfPrimitive(currentTypes[i]);
Class previous = wrappedIfPrimitive(previousTypes[i]);
if (current != previous && previous.isAssignableFrom(current)) {
return true;
}
}
return false;
}
private static Class wrappedIfPrimitive(Class parameterType)
{
return parameterType.isPrimitive() ? AutoBoxing.getWrapperType(parameterType) : parameterType;
}
static boolean acceptsArgumentTypes(Class[] paramTypes, Class[] argTypes, int firstParameter)
{
for (int i = firstParameter; i < paramTypes.length; i++) {
Class parType = paramTypes[i];
Class argType = argTypes[i - firstParameter];
if (isSameTypeIgnoringAutoBoxing(parType, argType) || parType.isAssignableFrom(argType)) {
// OK, move to next parameter.
}
else {
return false;
}
}
return true;
}
static boolean isSameTypeIgnoringAutoBoxing(Class firstType, Class secondType)
{
return
firstType == secondType ||
firstType.isPrimitive() && isWrapperOfPrimitiveType(firstType, secondType) ||
secondType.isPrimitive() && isWrapperOfPrimitiveType(secondType, firstType);
}
private static boolean isWrapperOfPrimitiveType(Class primitiveType, Class otherType)
{
return primitiveType == AutoBoxing.getPrimitiveType(otherType);
}
static int indexOfFirstRealParameter(Class[] mockParameterTypes, Class[] realParameterTypes)
{
int extraParameters = mockParameterTypes.length - realParameterTypes.length;
if (extraParameters == 1) {
//noinspection UnnecessaryFullyQualifiedName
return mockParameterTypes[0] == mockit.Invocation.class ? 1 : -1;
}
else if (extraParameters != 0) {
return -1;
}
return 0;
}
static boolean matchesParameterTypes(Class[] declaredTypes, Class[] specifiedTypes, int firstParameter)
{
for (int i = firstParameter; i < declaredTypes.length; i++) {
Class declaredType = declaredTypes[i];
Class specifiedType = specifiedTypes[i - firstParameter];
if (isSameTypeIgnoringAutoBoxing(declaredType, specifiedType)) {
// OK, move to next parameter.
}
else {
return false;
}
}
return true;
}
}