Search in sources :

Example 1 with ValueGetter

use of org.bytedeco.javacpp.annotation.ValueGetter in project javacpp by bytedeco.

the class Generator method methodInformation.

MethodInformation methodInformation(Method method) {
    MethodInformation info = new MethodInformation();
    info.cls = method.getDeclaringClass();
    info.method = method;
    info.annotations = method.getAnnotations();
    info.modifiers = method.getModifiers();
    info.returnType = method.getReturnType();
    info.name = method.getName();
    Name name = method.getAnnotation(Name.class);
    info.memberName = name != null ? name.value() : new String[] { info.name };
    Index index = method.getAnnotation(Index.class);
    info.dim = index != null ? index.value() : 0;
    info.parameterTypes = method.getParameterTypes();
    info.parameterAnnotations = method.getParameterAnnotations();
    info.returnRaw = method.isAnnotationPresent(Raw.class);
    info.withEnv = info.returnRaw ? method.getAnnotation(Raw.class).withEnv() : false;
    info.parameterRaw = new boolean[info.parameterAnnotations.length];
    for (int i = 0; i < info.parameterAnnotations.length; i++) {
        for (int j = 0; j < info.parameterAnnotations[i].length; j++) {
            if (info.parameterAnnotations[i][j] instanceof Raw) {
                info.parameterRaw[i] = true;
                info.withEnv |= ((Raw) info.parameterAnnotations[i][j]).withEnv();
            }
        }
    }
    boolean canBeGetter = info.returnType != void.class || (info.parameterTypes.length > 0 && info.parameterTypes[0].isArray() && info.parameterTypes[0].getComponentType().isPrimitive());
    boolean canBeSetter = (info.returnType == void.class || info.returnType == info.cls) && info.parameterTypes.length > 0;
    boolean canBeAllocator = !Modifier.isStatic(info.modifiers) && info.returnType == void.class;
    boolean canBeArrayAllocator = canBeAllocator && info.parameterTypes.length == 1 && (info.parameterTypes[0] == int.class || info.parameterTypes[0] == long.class);
    boolean valueGetter = false;
    boolean valueSetter = false;
    boolean memberGetter = false;
    boolean memberSetter = false;
    boolean noReturnGetter = false;
    Method pairedMethod = null;
    for (Method method2 : info.cls.getDeclaredMethods()) {
        MethodInformation info2 = annotationCache.get(method2);
        if (info2 == null) {
            annotationCache.put(method2, info2 = new MethodInformation());
            info2.modifiers = method2.getModifiers();
            info2.returnType = method2.getReturnType();
            info2.name = method2.getName();
            info2.parameterTypes = method2.getParameterTypes();
            info2.annotations = method2.getAnnotations();
            info2.parameterAnnotations = method2.getParameterAnnotations();
        }
        int skipParameters = info.parameterTypes.length > 0 && info.parameterTypes[0] == Class.class ? 1 : 0;
        int skipParameters2 = info2.parameterTypes.length > 0 && info2.parameterTypes[0] == Class.class ? 1 : 0;
        if (method.equals(method2) || !Modifier.isNative(info2.modifiers)) {
            continue;
        }
        boolean canBeValueGetter = false;
        boolean canBeValueSetter = false;
        boolean canBeMemberGetter = false;
        boolean canBeMemberSetter = false;
        if (canBeGetter && "get".equals(info.name) && "put".equals(info2.name)) {
            canBeValueGetter = true;
        } else if (canBeSetter && "put".equals(info.name) && "get".equals(info2.name)) {
            canBeValueSetter = true;
        } else if (info2.name.equals(info.name)) {
            info.overloaded = true;
            canBeMemberGetter = canBeGetter;
            canBeMemberSetter = canBeSetter;
        } else {
            continue;
        }
        boolean sameIndexParameters = true;
        for (int j = 0; j < info.parameterTypes.length - skipParameters && j < info2.parameterTypes.length - skipParameters2; j++) {
            if (info.parameterTypes[j + skipParameters] != info2.parameterTypes[j + skipParameters2]) {
                sameIndexParameters = false;
            }
        }
        if (!sameIndexParameters) {
            continue;
        }
        boolean parameterAsReturn = canBeValueGetter && info.parameterTypes.length > 0 && info.parameterTypes[0].isArray() && info.parameterTypes[0].getComponentType().isPrimitive();
        boolean parameterAsReturn2 = canBeValueSetter && info2.parameterTypes.length > 0 && info2.parameterTypes[0].isArray() && info2.parameterTypes[0].getComponentType().isPrimitive();
        if (canBeGetter && info2.parameterTypes.length - (parameterAsReturn ? 0 : 1) == info.parameterTypes.length - skipParameters && (parameterAsReturn ? info.parameterTypes[info.parameterTypes.length - 1] : info.returnType) == info2.parameterTypes[info2.parameterTypes.length - 1] && (info2.returnType == void.class || info2.returnType == info.cls) && (info2.parameterAnnotations[info2.parameterAnnotations.length - 1].length == 0 || (Arrays.equals(info2.parameterAnnotations[info2.parameterAnnotations.length - 1], info.annotations)))) {
            pairedMethod = method2;
            valueGetter = canBeValueGetter;
            memberGetter = canBeMemberGetter;
            noReturnGetter = parameterAsReturn;
        } else if (canBeSetter && info.parameterTypes.length - (parameterAsReturn2 ? 0 : 1) == info2.parameterTypes.length - skipParameters2 && (parameterAsReturn2 ? info2.parameterTypes[info2.parameterTypes.length - 1] : info2.returnType) == info.parameterTypes[info.parameterTypes.length - 1] && (info.returnType == void.class || info.returnType == info.cls) && (info.parameterAnnotations[info.parameterAnnotations.length - 1].length == 0 || (Arrays.equals(info.parameterAnnotations[info.parameterAnnotations.length - 1], info2.annotations)))) {
            pairedMethod = method2;
            valueSetter = canBeValueSetter;
            memberSetter = canBeMemberSetter;
        }
        if (memberGetter || memberSetter) {
            for (int j = skipParameters; j < info.parameterTypes.length; j++) {
                if (!method.isAnnotationPresent(Index.class) && (pairedMethod == null || !pairedMethod.isAnnotationPresent(Index.class)) && info.parameterTypes[j] != int.class && info.parameterTypes[j] != long.class) {
                    memberGetter = false;
                    if (j < info.parameterTypes.length - 1) {
                        memberSetter = false;
                    }
                }
            }
        }
    }
    Annotation behavior = behavior(info.annotations);
    if (canBeGetter && behavior instanceof ValueGetter) {
        info.valueGetter = true;
        info.noReturnGetter = noReturnGetter;
    } else if (canBeSetter && behavior instanceof ValueSetter) {
        info.valueSetter = true;
    } else if (canBeGetter && behavior instanceof MemberGetter) {
        info.memberGetter = true;
        info.noReturnGetter = noReturnGetter;
    } else if (canBeSetter && behavior instanceof MemberSetter) {
        info.memberSetter = true;
    } else if (canBeAllocator && behavior instanceof Allocator) {
        info.allocator = true;
    } else if (canBeArrayAllocator && behavior instanceof ArrayAllocator) {
        info.allocator = info.arrayAllocator = true;
    } else if (behavior == null) {
        // try to guess the behavior of the method
        if (info.returnType == void.class && "deallocate".equals(info.name) && !Modifier.isStatic(info.modifiers) && info.parameterTypes.length == 2 && info.parameterTypes[0] == long.class && info.parameterTypes[1] == long.class) {
            info.deallocator = true;
        } else if (canBeAllocator && "allocate".equals(info.name)) {
            info.allocator = true;
        } else if (canBeArrayAllocator && "allocateArray".equals(info.name)) {
            info.allocator = info.arrayAllocator = true;
        } else if (info.returnType.isAssignableFrom(ByteBuffer.class) && "asDirectBuffer".equals(info.name) && !Modifier.isStatic(info.modifiers) && info.parameterTypes.length == 0) {
            info.bufferGetter = true;
        } else if (valueGetter || (!memberGetter && canBeGetter && "get".equals(info.name) && index != null)) {
            info.valueGetter = true;
            info.noReturnGetter = noReturnGetter;
            info.pairedMethod = pairedMethod;
        } else if (valueSetter) {
            info.valueSetter = true;
            info.pairedMethod = pairedMethod;
        } else if (memberGetter) {
            info.memberGetter = true;
            info.noReturnGetter = noReturnGetter;
            info.pairedMethod = pairedMethod;
        } else if (memberSetter) {
            info.memberSetter = true;
            info.pairedMethod = pairedMethod;
        }
    } else if (!(behavior instanceof Function)) {
        logger.warn("Method \"" + method + "\" cannot behave like a \"" + behavior.annotationType().getSimpleName() + "\". No code will be generated.");
        return null;
    }
    if (name == null && info.pairedMethod != null) {
        name = info.pairedMethod.getAnnotation(Name.class);
        if (name != null) {
            info.memberName = name.value();
        }
    }
    info.noOffset = info.cls.isAnnotationPresent(NoOffset.class) || method.isAnnotationPresent(NoOffset.class) || method.isAnnotationPresent(Index.class);
    if (!info.noOffset && info.pairedMethod != null) {
        info.noOffset = info.pairedMethod.isAnnotationPresent(NoOffset.class) || info.pairedMethod.isAnnotationPresent(Index.class);
    }
    if (info.parameterTypes.length == 0 || !info.parameterTypes[0].isArray()) {
        if (info.valueGetter || info.memberGetter) {
            info.dim = info.parameterTypes.length;
        } else if (info.memberSetter || info.valueSetter) {
            info.dim = info.parameterTypes.length - 1;
        }
        if ((info.valueGetter || info.valueSetter) && FunctionPointer.class.isAssignableFrom(info.cls) && info.cls.isAnnotationPresent(Namespace.class)) {
            // a member pointer where the first argument is the object
            info.dim--;
        }
    }
    Index index2 = pairedMethod != null ? pairedMethod.getAnnotation(Index.class) : null;
    info.throwsException = null;
    if (!noException(info.cls, method)) {
        if ((by(info.annotations) instanceof ByVal && !noException(info.returnType, method)) || (index != null && index.function().length() > 0) || (index2 != null && index2.function().length() > 0) || !info.deallocator && !info.valueGetter && !info.valueSetter && !info.memberGetter && !info.memberSetter && !info.bufferGetter) {
            Class<?>[] exceptions = method.getExceptionTypes();
            info.throwsException = exceptions.length > 0 ? exceptions[0] : RuntimeException.class;
        }
    }
    return info;
}
Also used : ArrayAllocator(org.bytedeco.javacpp.annotation.ArrayAllocator) Allocator(org.bytedeco.javacpp.annotation.Allocator) Raw(org.bytedeco.javacpp.annotation.Raw) Index(org.bytedeco.javacpp.annotation.Index) Method(java.lang.reflect.Method) Annotation(java.lang.annotation.Annotation) MemberGetter(org.bytedeco.javacpp.annotation.MemberGetter) Namespace(org.bytedeco.javacpp.annotation.Namespace) Name(org.bytedeco.javacpp.annotation.Name) ValueGetter(org.bytedeco.javacpp.annotation.ValueGetter) ByVal(org.bytedeco.javacpp.annotation.ByVal) Function(org.bytedeco.javacpp.annotation.Function) MemberSetter(org.bytedeco.javacpp.annotation.MemberSetter) ValueSetter(org.bytedeco.javacpp.annotation.ValueSetter) ArrayAllocator(org.bytedeco.javacpp.annotation.ArrayAllocator) NoOffset(org.bytedeco.javacpp.annotation.NoOffset)

Example 2 with ValueGetter

use of org.bytedeco.javacpp.annotation.ValueGetter in project bigbluebutton by bigbluebutton.

the class Generator method methodInformation.

MethodInformation methodInformation(Method method) {
    MethodInformation info = new MethodInformation();
    info.cls = method.getDeclaringClass();
    info.method = method;
    info.annotations = method.getAnnotations();
    info.modifiers = method.getModifiers();
    info.returnType = method.getReturnType();
    info.name = method.getName();
    Name name = method.getAnnotation(Name.class);
    info.memberName = name != null ? name.value() : new String[] { info.name };
    Index index = method.getAnnotation(Index.class);
    info.dim = index != null ? index.value() : 0;
    info.parameterTypes = method.getParameterTypes();
    info.parameterAnnotations = method.getParameterAnnotations();
    info.returnRaw = method.isAnnotationPresent(Raw.class);
    info.withEnv = info.returnRaw ? method.getAnnotation(Raw.class).withEnv() : false;
    info.parameterRaw = new boolean[info.parameterAnnotations.length];
    for (int i = 0; i < info.parameterAnnotations.length; i++) {
        for (int j = 0; j < info.parameterAnnotations[i].length; j++) {
            if (info.parameterAnnotations[i][j] instanceof Raw) {
                info.parameterRaw[i] = true;
                info.withEnv |= ((Raw) info.parameterAnnotations[i][j]).withEnv();
            }
        }
    }
    boolean canBeGetter = info.returnType != void.class || (info.parameterTypes.length > 0 && info.parameterTypes[0].isArray() && info.parameterTypes[0].getComponentType().isPrimitive());
    boolean canBeSetter = (info.returnType == void.class || info.returnType == info.cls) && info.parameterTypes.length > 0;
    boolean canBeAllocator = !Modifier.isStatic(info.modifiers) && info.returnType == void.class;
    boolean canBeArrayAllocator = canBeAllocator && info.parameterTypes.length == 1 && (info.parameterTypes[0] == int.class || info.parameterTypes[0] == long.class);
    boolean valueGetter = false;
    boolean valueSetter = false;
    boolean memberGetter = false;
    boolean memberSetter = false;
    boolean noReturnGetter = false;
    Method pairedMethod = null;
    for (Method method2 : info.cls.getDeclaredMethods()) {
        MethodInformation info2 = annotationCache.get(method2);
        if (info2 == null) {
            annotationCache.put(method2, info2 = new MethodInformation());
            info2.modifiers = method2.getModifiers();
            info2.returnType = method2.getReturnType();
            info2.name = method2.getName();
            info2.parameterTypes = method2.getParameterTypes();
            info2.annotations = method2.getAnnotations();
            info2.parameterAnnotations = method2.getParameterAnnotations();
        }
        int skipParameters = info.parameterTypes.length > 0 && info.parameterTypes[0] == Class.class ? 1 : 0;
        int skipParameters2 = info2.parameterTypes.length > 0 && info2.parameterTypes[0] == Class.class ? 1 : 0;
        if (method.equals(method2) || !Modifier.isNative(info2.modifiers)) {
            continue;
        }
        boolean canBeValueGetter = false;
        boolean canBeValueSetter = false;
        boolean canBeMemberGetter = false;
        boolean canBeMemberSetter = false;
        if (canBeGetter && "get".equals(info.name) && "put".equals(info2.name)) {
            canBeValueGetter = true;
        } else if (canBeSetter && "put".equals(info.name) && "get".equals(info2.name)) {
            canBeValueSetter = true;
        } else if (info2.name.equals(info.name)) {
            info.overloaded = true;
            canBeMemberGetter = canBeGetter;
            canBeMemberSetter = canBeSetter;
            for (int j = skipParameters; j < info.parameterTypes.length; j++) {
                if (info.parameterTypes[j] != int.class && info.parameterTypes[j] != long.class) {
                    canBeMemberGetter = false;
                    if (j < info.parameterTypes.length - 1) {
                        canBeMemberSetter = false;
                    }
                }
            }
        } else {
            continue;
        }
        boolean sameIndexParameters = true;
        for (int j = 0; j < info.parameterTypes.length - skipParameters && j < info2.parameterTypes.length - skipParameters2; j++) {
            if (info.parameterTypes[j + skipParameters] != info2.parameterTypes[j + skipParameters2]) {
                sameIndexParameters = false;
            }
        }
        if (!sameIndexParameters) {
            continue;
        }
        boolean parameterAsReturn = canBeValueGetter && info.parameterTypes.length > 0 && info.parameterTypes[0].isArray() && info.parameterTypes[0].getComponentType().isPrimitive();
        boolean parameterAsReturn2 = canBeValueSetter && info2.parameterTypes.length > 0 && info2.parameterTypes[0].isArray() && info2.parameterTypes[0].getComponentType().isPrimitive();
        if (canBeGetter && info2.parameterTypes.length - (parameterAsReturn ? 0 : 1) == info.parameterTypes.length - skipParameters && (parameterAsReturn ? info.parameterTypes[info.parameterTypes.length - 1] : info.returnType) == info2.parameterTypes[info2.parameterTypes.length - 1] && (info2.returnType == void.class || info2.returnType == info.cls) && (info2.parameterAnnotations[info2.parameterAnnotations.length - 1].length == 0 || (Arrays.equals(info2.parameterAnnotations[info2.parameterAnnotations.length - 1], info.annotations)))) {
            pairedMethod = method2;
            valueGetter = canBeValueGetter;
            memberGetter = canBeMemberGetter;
            noReturnGetter = parameterAsReturn;
        } else if (canBeSetter && info.parameterTypes.length - (parameterAsReturn2 ? 0 : 1) == info2.parameterTypes.length - skipParameters2 && (parameterAsReturn2 ? info2.parameterTypes[info2.parameterTypes.length - 1] : info2.returnType) == info.parameterTypes[info.parameterTypes.length - 1] && (info.returnType == void.class || info.returnType == info.cls) && (info.parameterAnnotations[info.parameterAnnotations.length - 1].length == 0 || (Arrays.equals(info.parameterAnnotations[info.parameterAnnotations.length - 1], info2.annotations)))) {
            pairedMethod = method2;
            valueSetter = canBeValueSetter;
            memberSetter = canBeMemberSetter;
        }
    }
    Annotation behavior = behavior(info.annotations);
    if (canBeGetter && behavior instanceof ValueGetter) {
        info.valueGetter = true;
        info.noReturnGetter = noReturnGetter;
    } else if (canBeSetter && behavior instanceof ValueSetter) {
        info.valueSetter = true;
    } else if (canBeGetter && behavior instanceof MemberGetter) {
        info.memberGetter = true;
        info.noReturnGetter = noReturnGetter;
    } else if (canBeSetter && behavior instanceof MemberSetter) {
        info.memberSetter = true;
    } else if (canBeAllocator && behavior instanceof Allocator) {
        info.allocator = true;
    } else if (canBeArrayAllocator && behavior instanceof ArrayAllocator) {
        info.allocator = info.arrayAllocator = true;
    } else if (behavior == null) {
        // try to guess the behavior of the method
        if (info.returnType == void.class && "deallocate".equals(info.name) && !Modifier.isStatic(info.modifiers) && info.parameterTypes.length == 2 && info.parameterTypes[0] == long.class && info.parameterTypes[1] == long.class) {
            info.deallocator = true;
        } else if (canBeAllocator && "allocate".equals(info.name)) {
            info.allocator = true;
        } else if (canBeArrayAllocator && "allocateArray".equals(info.name)) {
            info.allocator = info.arrayAllocator = true;
        } else if (info.returnType.isAssignableFrom(ByteBuffer.class) && "asDirectBuffer".equals(info.name) && !Modifier.isStatic(info.modifiers) && info.parameterTypes.length == 0) {
            info.bufferGetter = true;
        } else if (valueGetter) {
            info.valueGetter = true;
            info.noReturnGetter = noReturnGetter;
            info.pairedMethod = pairedMethod;
        } else if (valueSetter) {
            info.valueSetter = true;
            info.pairedMethod = pairedMethod;
        } else if (memberGetter) {
            info.memberGetter = true;
            info.noReturnGetter = noReturnGetter;
            info.pairedMethod = pairedMethod;
        } else if (memberSetter) {
            info.memberSetter = true;
            info.pairedMethod = pairedMethod;
        }
    } else if (!(behavior instanceof Function)) {
        logger.warn("Method \"" + method + "\" cannot behave like a \"" + behavior.annotationType().getSimpleName() + "\". No code will be generated.");
        return null;
    }
    if (name == null && info.pairedMethod != null) {
        name = info.pairedMethod.getAnnotation(Name.class);
        if (name != null) {
            info.memberName = name.value();
        }
    }
    info.noOffset = info.cls.isAnnotationPresent(NoOffset.class) || method.isAnnotationPresent(NoOffset.class) || method.isAnnotationPresent(Index.class);
    if (!info.noOffset && info.pairedMethod != null) {
        info.noOffset = info.pairedMethod.isAnnotationPresent(NoOffset.class) || info.pairedMethod.isAnnotationPresent(Index.class);
    }
    if (info.parameterTypes.length == 0 || !info.parameterTypes[0].isArray()) {
        if (info.valueGetter || info.memberGetter) {
            info.dim = info.parameterTypes.length;
        } else if (info.memberSetter || info.valueSetter) {
            info.dim = info.parameterTypes.length - 1;
        }
    }
    info.throwsException = null;
    if (!noException(info.cls, method)) {
        if ((by(info.annotations) instanceof ByVal && !noException(info.returnType, method)) || !info.deallocator && !info.valueGetter && !info.valueSetter && !info.memberGetter && !info.memberSetter && !info.bufferGetter) {
            Class<?>[] exceptions = method.getExceptionTypes();
            info.throwsException = exceptions.length > 0 ? exceptions[0] : RuntimeException.class;
        }
    }
    return info;
}
Also used : ArrayAllocator(org.bytedeco.javacpp.annotation.ArrayAllocator) Allocator(org.bytedeco.javacpp.annotation.Allocator) Raw(org.bytedeco.javacpp.annotation.Raw) Index(org.bytedeco.javacpp.annotation.Index) Method(java.lang.reflect.Method) Annotation(java.lang.annotation.Annotation) MemberGetter(org.bytedeco.javacpp.annotation.MemberGetter) Name(org.bytedeco.javacpp.annotation.Name) ValueGetter(org.bytedeco.javacpp.annotation.ValueGetter) ByVal(org.bytedeco.javacpp.annotation.ByVal) Function(org.bytedeco.javacpp.annotation.Function) MemberSetter(org.bytedeco.javacpp.annotation.MemberSetter) ValueSetter(org.bytedeco.javacpp.annotation.ValueSetter) ArrayAllocator(org.bytedeco.javacpp.annotation.ArrayAllocator) NoOffset(org.bytedeco.javacpp.annotation.NoOffset)

Aggregations

Annotation (java.lang.annotation.Annotation)2 Method (java.lang.reflect.Method)2 Allocator (org.bytedeco.javacpp.annotation.Allocator)2 ArrayAllocator (org.bytedeco.javacpp.annotation.ArrayAllocator)2 ByVal (org.bytedeco.javacpp.annotation.ByVal)2 Function (org.bytedeco.javacpp.annotation.Function)2 Index (org.bytedeco.javacpp.annotation.Index)2 MemberGetter (org.bytedeco.javacpp.annotation.MemberGetter)2 MemberSetter (org.bytedeco.javacpp.annotation.MemberSetter)2 Name (org.bytedeco.javacpp.annotation.Name)2 NoOffset (org.bytedeco.javacpp.annotation.NoOffset)2 Raw (org.bytedeco.javacpp.annotation.Raw)2 ValueGetter (org.bytedeco.javacpp.annotation.ValueGetter)2 ValueSetter (org.bytedeco.javacpp.annotation.ValueSetter)2 Namespace (org.bytedeco.javacpp.annotation.Namespace)1