Search in sources :

Example 1 with WrappingComputerMethod

use of mekanism.common.integration.computer.annotation.WrappingComputerMethod in project Mekanism by mekanism.

the class ComputerMethodMapper method wrapMethodHandle.

private static void wrapMethodHandle(Map<String, Class<?>> classNameCache, MethodHandle methodHandle, AnnotationData data, List<MethodDetails> methodDetails, Map<Class<?>, List<WrappingMethodHelper>> cachedWrappers, Class<?> annotatedClass, String identifier) {
    Class<?> wrapperClass = getAnnotationValue(classNameCache, data, "wrapper");
    if (wrapperClass != null) {
        List<String> methodNames = getAnnotationValue(data, "methodNames", Collections.emptyList());
        int methodNameCount = methodNames.size();
        if (methodNameCount == 0) {
            Mekanism.logger.warn("No method names on wrapper for {} in class '{}', so the WrappingComputerMethod annotation should probably be removed.", identifier, annotatedClass.getSimpleName());
        } else {
            List<WrappingMethodHelper> wrapperHandles = cachedWrappers.computeIfAbsent(wrapperClass, clazz -> {
                List<WrappingMethodHelper> helpers = new ArrayList<>();
                try {
                    Method[] methods = clazz.getDeclaredMethods();
                    Arrays.sort(methods, (a, b) -> {
                        WrappingComputerMethodIndex aIndex = a.getAnnotation(WrappingComputerMethodIndex.class);
                        WrappingComputerMethodIndex bIndex = b.getAnnotation(WrappingComputerMethodIndex.class);
                        return Integer.compare(aIndex == null ? 0 : aIndex.value(), bIndex == null ? 0 : bIndex.value());
                    });
                    boolean hasFaultyOrder = false;
                    for (Method method : methods) {
                        WrappingComputerMethodIndex index = method.getAnnotation(WrappingComputerMethodIndex.class);
                        if (index == null) {
                            if (!helpers.isEmpty()) {
                                hasFaultyOrder = true;
                            }
                        } else if (index.value() < helpers.size()) {
                            hasFaultyOrder = true;
                        }
                        helpers.add(new WrappingMethodHelper(PUBLIC_LOOKUP.unreflect(method)));
                    }
                    if (hasFaultyOrder) {
                        Mekanism.logger.error("Faulty method index annotations in class '{}'", clazz.getSimpleName());
                    }
                } catch (IllegalAccessException e) {
                    Mekanism.logger.error("Failed to retrieve method handle for methods in class '{}'.", clazz.getSimpleName());
                }
                return helpers;
            });
            // actual environment so shouldn't really matter too much
            if (wrapperHandles.size() != methodNameCount) {
                Mekanism.logger.warn("Mismatch in count of method names ({}) for generated methods and methods to generate ({}).", methodNameCount, wrapperHandles.size());
            } else {
                MethodRestriction restriction = getAnnotationValue(data, "restriction", MethodRestriction.NONE);
                boolean threadSafe = getAnnotationValue(data, "threadSafe", false);
                for (int index = 0; index < methodNameCount; index++) {
                    // If there is an error at dev time it should crash with an IllegalArgumentException
                    MethodHandle newHandle = MethodHandles.filterReturnValue(methodHandle, wrapperHandles.get(index).asType(methodHandle.type().returnType()));
                    methodDetails.add(new MethodDetails(methodNames.get(index), newHandle, restriction, threadSafe));
                }
            }
        }
    }
}
Also used : ArrayList(java.util.ArrayList) WrappingComputerMethod(mekanism.common.integration.computer.annotation.WrappingComputerMethod) ComputerMethod(mekanism.common.integration.computer.annotation.ComputerMethod) Method(java.lang.reflect.Method) SyntheticComputerMethod(mekanism.common.integration.computer.annotation.SyntheticComputerMethod) WrappingComputerMethodIndex(mekanism.common.integration.computer.annotation.WrappingComputerMethod.WrappingComputerMethodIndex) MethodHandle(java.lang.invoke.MethodHandle) ThreadAwareMethodHandle(mekanism.common.integration.computer.BoundComputerMethod.ThreadAwareMethodHandle)

Aggregations

MethodHandle (java.lang.invoke.MethodHandle)1 Method (java.lang.reflect.Method)1 ArrayList (java.util.ArrayList)1 ThreadAwareMethodHandle (mekanism.common.integration.computer.BoundComputerMethod.ThreadAwareMethodHandle)1 ComputerMethod (mekanism.common.integration.computer.annotation.ComputerMethod)1 SyntheticComputerMethod (mekanism.common.integration.computer.annotation.SyntheticComputerMethod)1 WrappingComputerMethod (mekanism.common.integration.computer.annotation.WrappingComputerMethod)1 WrappingComputerMethodIndex (mekanism.common.integration.computer.annotation.WrappingComputerMethod.WrappingComputerMethodIndex)1