/*
* Copyright (c) 2006 Rogério Liesenfeld
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit.internal.reflection;
import javax.annotation.*;
import mockit.internal.util.*;
public final class ParameterReflection
{
@Nonnull public static final Class<?>[] NO_PARAMETERS = new Class<?>[0];
private ParameterReflection() {}
@Nonnull
static String getParameterTypesDescription(@Nonnull Class<?>[] paramTypes)
{
StringBuilder paramTypesDesc = new StringBuilder(200);
String sep = "";
paramTypesDesc.append('(');
for (Class<?> paramType : paramTypes) {
String typeName = paramType.getCanonicalName().replace("java.lang.", "");
paramTypesDesc.append(sep).append(typeName);
sep = ", ";
}
paramTypesDesc.append(')');
return paramTypesDesc.toString();
}
@Nonnull
public static Class<?>[] getArgumentTypesFromArgumentValues(@Nonnull 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;
}
@Nonnull
private static Class<?> getArgumentTypeFromArgumentValue(int i, @Nonnull 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;
}
@Nonnull
public static Object[] argumentsWithExtraFirstValue(@Nonnull Object[] args, @Nonnull 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(@Nonnull Class<?>[] currentTypes, @Nonnull 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;
}
@Nonnull
private static Class<?> wrappedIfPrimitive(@Nonnull Class<?> parameterType)
{
if (parameterType.isPrimitive()) {
Class<?> wrapperType = AutoBoxing.getWrapperType(parameterType);
assert wrapperType != null;
return wrapperType;
}
return parameterType;
}
static boolean acceptsArgumentTypes(@Nonnull Class<?>[] paramTypes, @Nonnull 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(@Nonnull Class<?> firstType, @Nonnull Class<?> secondType)
{
return
firstType == secondType ||
firstType.isPrimitive() && isWrapperOfPrimitiveType(firstType, secondType) ||
secondType.isPrimitive() && isWrapperOfPrimitiveType(secondType, firstType);
}
private static boolean isWrapperOfPrimitiveType(@Nonnull Class<?> primitiveType, @Nonnull Class<?> otherType)
{
return primitiveType == AutoBoxing.getPrimitiveType(otherType);
}
static int indexOfFirstRealParameter(@Nonnull Class<?>[] mockParameterTypes, @Nonnull Class<?>[] realParameterTypes)
{
int extraParameters = mockParameterTypes.length - realParameterTypes.length;
if (extraParameters == 1) {
//noinspection UnnecessaryFullyQualifiedName
return mockParameterTypes[0] == mockit.Invocation.class ? 1 : -1;
}
if (extraParameters != 0) {
return -1;
}
return 0;
}
static boolean matchesParameterTypes(
@Nonnull Class<?>[] declaredTypes, @Nonnull 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;
}
@Nonnull
static IllegalArgumentException invalidArguments()
{
return new IllegalArgumentException("Invalid null value passed as argument");
}
}