Skip to content

Commit

Permalink
Improved exception handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Lenni0451 committed Dec 3, 2023
1 parent 7c8354a commit add5c25
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 24 deletions.
19 changes: 7 additions & 12 deletions src/main/java/net/lenni0451/reflect/accessor/FieldAccessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

import static net.lenni0451.reflect.wrapper.ASMWrapper.*;
Expand Down Expand Up @@ -185,25 +183,22 @@ private static Method findInvokerMethod(final Class<?> invokerClass, final Class
if (!Modifier.isInterface(invokerClass.getModifiers())) throw new IllegalArgumentException("The invoker class must be an interface");

int abstractMethods = 0;
List<Method> methods = new ArrayList<>();
Method matched = null;
for (Method invokerMethod : Methods.getDeclaredMethods(invokerClass)) {
if (!Modifier.isAbstract(invokerMethod.getModifiers())) continue;
if (++abstractMethods > 1) throw new IllegalArgumentException("The invoker class must only have one abstract method");
if (invokerMethod.getParameterCount() != parameterTypes.length) continue;
if (!invokerMethod.getReturnType().isAssignableFrom(returnType)) continue;
if (invokerMethod.getParameterCount() != parameterTypes.length) throw new IllegalArgumentException("The invoker method must have " + parameterTypes.length + " parameters");
if (!invokerMethod.getReturnType().isAssignableFrom(returnType)) throw new IllegalArgumentException("The invoker method return type must be of type " + returnType.getName());

boolean hasIncompatibleParameter = false;
Class<?>[] invokerParameterTypes = invokerMethod.getParameterTypes();
for (int i = 0; i < invokerParameterTypes.length; i++) {
if (invokerParameterTypes[i].isAssignableFrom(parameterTypes[i])) continue;
hasIncompatibleParameter = true;
break;
throw new IllegalArgumentException("The invoker method parameter " + i + " must be of type " + parameterTypes[i].getName());
}
if (hasIncompatibleParameter) continue;
methods.add(invokerMethod);
matched = invokerMethod;
}
if (methods.size() != 1) throw new IllegalArgumentException("Could not find a valid invoker method for: " + desc(parameterTypes, returnType));
return methods.get(0);
if (matched == null) throw new IllegalArgumentException("Could not find a valid invoker method for: " + desc(parameterTypes, returnType));
return matched;
}

private static void addConstructor(final ASMWrapper acc, final String newClassName, @Nullable final Supplier<Class<?>> instanceType, final Field field) {
Expand Down
23 changes: 11 additions & 12 deletions src/main/java/net/lenni0451/reflect/accessor/MethodAccessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

import static net.lenni0451.reflect.wrapper.ASMWrapper.*;

Expand Down Expand Up @@ -137,28 +135,29 @@ private static Method findInvokerMethod(final Class<?> invokerClass, final Metho
if (!Modifier.isInterface(invokerClass.getModifiers())) throw new IllegalArgumentException("The invoker class must be an interface");

int abstractMethods = 0;
List<Method> methods = new ArrayList<>();
Method matched = null;
for (Method invokerMethod : Methods.getDeclaredMethods(invokerClass)) {
if (!Modifier.isAbstract(invokerMethod.getModifiers())) continue;
if (++abstractMethods > 1) throw new IllegalArgumentException("The invoker class must only have one abstract method");
if (invokerMethod.getParameterCount() != method.getParameterCount() + (requireInstance ? 1 : 0)) continue;
if (!invokerMethod.getReturnType().isAssignableFrom(method.getReturnType())) continue;
if (invokerMethod.getParameterCount() != method.getParameterCount() + (requireInstance ? 1 : 0)) {
throw new IllegalArgumentException("The invoker method must have " + (method.getParameterCount() + (requireInstance ? 1 : 0)) + " parameters");
}
if (!invokerMethod.getReturnType().isAssignableFrom(method.getReturnType())) {
throw new IllegalArgumentException("The invoker method return type must be of type " + method.getReturnType().getName());
}

boolean hasIncompatibleParameter = false;
Class<?>[] invokerParameterTypes = invokerMethod.getParameterTypes();
Class<?>[] methodParameterTypes = method.getParameterTypes();
for (int i = 0; i < invokerParameterTypes.length; i++) {
Class<?> invokerParameterType = invokerParameterTypes[i];
Class<?> methodParameterType = (requireInstance && i == 0) ? method.getDeclaringClass() : methodParameterTypes[i - (requireInstance ? 1 : 0)];
if (invokerParameterType.isAssignableFrom(methodParameterType)) continue;
hasIncompatibleParameter = true;
break;
throw new IllegalArgumentException("The invoker method parameter " + i + " must be of type " + methodParameterType);
}
if (hasIncompatibleParameter) continue;
methods.add(invokerMethod);
matched = invokerMethod;
}
if (methods.size() != 1) throw new IllegalArgumentException("Could not find a valid invoker method for: " + method);
return methods.get(0);
if (matched == null) throw new IllegalArgumentException("Could not find a valid invoker method for: " + method);
return matched;
}

private static void pushArgs(final MethodVisitorAccess mv, final Class<?>[] supplied, final Class<?>[] target) {
Expand Down

0 comments on commit add5c25

Please sign in to comment.