use of org.bytedeco.javacpp.annotation.Name in project bigbluebutton by bigbluebutton.
the class Generator method cppScopeName.
static String cppScopeName(Class<?> type) {
String scopeName = "";
while (type != null) {
Namespace namespace = type.getAnnotation(Namespace.class);
String spaceName = namespace == null ? "" : namespace.value();
if (Pointer.class.isAssignableFrom(type) && (!baseClasses.contains(type) || type.isAnnotationPresent(Name.class))) {
Name name = type.getAnnotation(Name.class);
String s;
if (name == null) {
s = type.getName();
int i = s.lastIndexOf("$");
if (i < 0) {
i = s.lastIndexOf(".");
}
s = s.substring(i + 1);
} else {
s = name.value()[0];
}
if (spaceName.length() > 0 && !spaceName.endsWith("::")) {
spaceName += "::";
}
spaceName += s;
}
if (scopeName.length() > 0 && !spaceName.endsWith("::")) {
spaceName += "::";
}
scopeName = spaceName + scopeName;
if ((namespace != null && namespace.value().length() == 0) || spaceName.startsWith("::")) {
// user wants to reset namespace here
break;
}
type = type.getDeclaringClass();
}
return scopeName;
}
use of org.bytedeco.javacpp.annotation.Name in project bigbluebutton by bigbluebutton.
the class Generator method methods.
boolean methods(Class<?> cls) {
if (!checkPlatform(cls)) {
return false;
}
Set<String> memberList = members.get(cls);
if (!cls.isAnnotationPresent(Opaque.class) && !FunctionPointer.class.isAssignableFrom(cls) && cls.getEnclosingClass() != Pointer.class) {
if (memberList == null) {
members.put(cls, memberList = new LinkedHashSet<String>());
}
if (!memberList.contains("sizeof")) {
memberList.add("sizeof");
}
}
boolean didSomething = false;
for (Class<?> c : cls.getDeclaredClasses()) {
if (Pointer.class.isAssignableFrom(c) || Pointer.class.isAssignableFrom(c.getEnclosingClass())) {
didSomething |= methods(c);
}
}
Method[] methods = cls.getDeclaredMethods();
MethodInformation[] methodInfos = new MethodInformation[methods.length];
for (int i = 0; i < methods.length; i++) {
methodInfos[i] = methodInformation(methods[i]);
}
Class<?> c = cls.getSuperclass();
while (c != null && c != Object.class) {
// consider non-duplicate virtual functions from superclasses as well
for (Method m : c.getDeclaredMethods()) {
if (m.isAnnotationPresent(Virtual.class)) {
boolean found = false;
String name = m.getName();
Class<?>[] types = m.getParameterTypes();
for (Method m2 : methods) {
if (name.equals(m2.getName()) && Arrays.equals(types, m2.getParameterTypes())) {
found = true;
break;
}
}
if (!found) {
methods = Arrays.copyOf(methods, methods.length + 1);
methods[methods.length - 1] = m;
methodInfos = Arrays.copyOf(methodInfos, methodInfos.length + 1);
methodInfos[methods.length - 1] = methodInformation(m);
methodInfos[methods.length - 1].cls = cls;
}
}
}
c = c.getSuperclass();
}
boolean[] callbackAllocators = new boolean[methods.length];
Method functionMethod = functionMethod(cls, callbackAllocators);
boolean firstCallback = true;
for (int i = 0; i < methods.length; i++) {
if (!checkPlatform(methods[i].getAnnotation(Platform.class), null)) {
continue;
}
MethodInformation methodInfo = methodInfos[i];
String nativeName = mangle(cls.getName()) + "_" + mangle(methods[i].getName());
String callbackName = callbackAllocators[i] && methodInfo.parameterTypes.length > 0 ? null : "JavaCPP_" + nativeName + "_callback";
if (callbackAllocators[i] && functionMethod == null) {
logger.warn("No callback method call() or apply() has been not declared in \"" + cls.getCanonicalName() + "\". No code will be generated for callback allocator.");
continue;
} else if (callbackAllocators[i] || (methods[i].equals(functionMethod) && !Modifier.isNative(methods[i].getModifiers()))) {
functions.index(cls);
Name name = methods[i].getAnnotation(Name.class);
if (name != null && name.value().length > 0 && name.value()[0].length() > 0) {
callbackName = name.value()[0];
}
callback(cls, functionMethod, callbackName, firstCallback, null);
firstCallback = false;
didSomething = true;
}
if ((Modifier.isNative(methods[i].getModifiers()) || Modifier.isAbstract(methods[i].getModifiers())) && !methodInfo.valueGetter && !methodInfo.valueSetter && !methodInfo.memberGetter && !methodInfo.memberSetter && !cls.isInterface() && (methods[i].isAnnotationPresent(Virtual.class) || methodInfo.allocator)) {
callback(cls, methods[i], methodInfo.memberName[0], !methodInfo.allocator, methodInfo);
}
if (!Modifier.isNative(methods[i].getModifiers())) {
continue;
}
if ((methodInfo.memberGetter || methodInfo.memberSetter) && !methodInfo.noOffset && memberList != null && !Modifier.isStatic(methodInfo.modifiers)) {
if (!memberList.contains(methodInfo.memberName[0])) {
memberList.add(methodInfo.memberName[0]);
}
}
didSomething = true;
out.print("JNIEXPORT " + jniTypeName(methodInfo.returnType) + " JNICALL Java_" + nativeName);
if (methodInfo.overloaded) {
out.print("__" + mangle(signature(methodInfo.parameterTypes)));
}
if (Modifier.isStatic(methodInfo.modifiers)) {
out.print("(JNIEnv* env, jclass cls");
} else {
out.print("(JNIEnv* env, jobject obj");
}
for (int j = 0; j < methodInfo.parameterTypes.length; j++) {
out.print(", " + jniTypeName(methodInfo.parameterTypes[j]) + " arg" + j);
}
out.println(") {");
if (callbackAllocators[i]) {
callbackAllocator(cls, callbackName);
continue;
} else if (!Modifier.isStatic(methodInfo.modifiers) && !methodInfo.allocator && !methodInfo.arrayAllocator && !methodInfo.deallocator) {
// get our "this" pointer
String[] typeName = cppTypeName(cls);
if ("void*".equals(typeName[0]) && !cls.isAnnotationPresent(Opaque.class)) {
typeName[0] = "char*";
} else if (FunctionPointer.class.isAssignableFrom(cls)) {
functions.index(cls);
typeName[0] = functionClassName(cls) + "*";
typeName[1] = "";
}
out.println(" " + typeName[0] + " ptr" + typeName[1] + " = (" + typeName[0] + typeName[1] + ")jlong_to_ptr(env->GetLongField(obj, JavaCPP_addressFID));");
out.println(" if (ptr == NULL) {");
out.println(" env->ThrowNew(JavaCPP_getClass(env, " + jclasses.index(NullPointerException.class) + "), \"This pointer address is NULL.\");");
out.println(" return" + (methodInfo.returnType == void.class ? ";" : " 0;"));
out.println(" }");
if (FunctionPointer.class.isAssignableFrom(cls)) {
out.println(" if (ptr->ptr == NULL) {");
out.println(" env->ThrowNew(JavaCPP_getClass(env, " + jclasses.index(NullPointerException.class) + "), \"This function pointer address is NULL.\");");
out.println(" return" + (methodInfo.returnType == void.class ? ";" : " 0;"));
out.println(" }");
}
if (!cls.isAnnotationPresent(Opaque.class)) {
out.println(" jlong position = env->GetLongField(obj, JavaCPP_positionFID);");
out.println(" ptr += position;");
if (methodInfo.bufferGetter) {
out.println(" jlong size = env->GetLongField(obj, JavaCPP_limitFID);");
out.println(" size -= position;");
}
}
}
parametersBefore(methodInfo);
String returnPrefix = returnBefore(methodInfo);
call(methodInfo, returnPrefix, false);
returnAfter(methodInfo);
parametersAfter(methodInfo);
if (methodInfo.throwsException != null) {
out.println(" if (exc != NULL) {");
out.println(" env->Throw(exc);");
out.println(" }");
}
if (methodInfo.returnType != void.class) {
out.println(" return rarg;");
}
out.println("}");
}
out.println();
return didSomething;
}
use of org.bytedeco.javacpp.annotation.Name 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;
}
use of org.bytedeco.javacpp.annotation.Name in project javacpp by bytedeco.
the class Generator method methods.
boolean methods(Class<?> cls) {
if (!Loader.checkPlatform(cls, properties)) {
return false;
}
Set<String> memberList = members.get(cls);
if (!cls.isAnnotationPresent(Opaque.class) && cls != Loader.class && !FunctionPointer.class.isAssignableFrom(cls) && cls.getEnclosingClass() != Pointer.class) {
if (memberList == null) {
members.put(cls, memberList = new LinkedHashSet<String>());
}
if (!memberList.contains("sizeof")) {
memberList.add("sizeof");
}
}
boolean didSomething = false;
for (Class<?> c : cls.getDeclaredClasses()) {
if (Pointer.class.isAssignableFrom(c) || Pointer.class.isAssignableFrom(c.getEnclosingClass())) {
didSomething |= methods(c);
}
}
Method[] methods = cls.getDeclaredMethods();
MethodInformation[] methodInfos = new MethodInformation[methods.length];
for (int i = 0; i < methods.length; i++) {
methodInfos[i] = methodInformation(methods[i]);
}
Class<?> c = cls.getSuperclass();
while (c != null && c != Object.class) {
// consider non-duplicate virtual functions from superclasses as well
for (Method m : c.getDeclaredMethods()) {
if (m.isAnnotationPresent(Virtual.class)) {
boolean found = false;
String name = m.getName();
Class<?>[] types = m.getParameterTypes();
for (Method m2 : methods) {
if (name.equals(m2.getName()) && Arrays.equals(types, m2.getParameterTypes())) {
found = true;
break;
}
}
if (!found) {
methods = Arrays.copyOf(methods, methods.length + 1);
methods[methods.length - 1] = m;
methodInfos = Arrays.copyOf(methodInfos, methodInfos.length + 1);
methodInfos[methods.length - 1] = methodInformation(m);
methodInfos[methods.length - 1].cls = cls;
}
}
}
c = c.getSuperclass();
}
boolean[] callbackAllocators = new boolean[methods.length];
Method[] functionMethods = functionMethods(cls, callbackAllocators);
boolean firstCallback = true;
for (int i = 0; i < methods.length; i++) {
if (!Loader.checkPlatform(methods[i].getAnnotation(Platform.class), properties)) {
continue;
}
MethodInformation methodInfo = methodInfos[i];
String nativeName = mangle(cls.getName()) + "_" + mangle(methods[i].getName());
String callbackName = callbackAllocators[i] && methodInfo.parameterTypes.length > 0 ? null : "JavaCPP_" + nativeName + "_callback";
if (callbackAllocators[i] && functionMethods == null) {
logger.warn("No callback method call() or apply() has been not declared in \"" + cls.getCanonicalName() + "\". No code will be generated for callback allocator.");
continue;
} else if (functionMethods != null) {
for (Method functionMethod : functionMethods) {
if (functionMethod != null && (callbackAllocators[i]) || (methods[i].equals(functionMethod) && !Modifier.isNative(methods[i].getModifiers()))) {
functions.index(cls);
Name name = methods[i].getAnnotation(Name.class);
if (name != null && name.value().length > 0 && name.value()[0].length() > 0) {
callbackName = name.value()[0];
}
callback(cls, functionMethod, callbackName, firstCallback, null);
firstCallback = false;
didSomething = true;
}
}
}
if ((Modifier.isNative(methods[i].getModifiers()) || Modifier.isAbstract(methods[i].getModifiers())) && !methodInfo.valueGetter && !methodInfo.valueSetter && !methodInfo.memberGetter && !methodInfo.memberSetter && !cls.isInterface() && (methods[i].isAnnotationPresent(Virtual.class) || methodInfo.allocator)) {
callback(cls, methods[i], methodInfo.memberName[0], !methodInfo.allocator, methodInfo);
}
if (!Modifier.isNative(methods[i].getModifiers())) {
continue;
}
if ((methodInfo.memberGetter || methodInfo.memberSetter) && !methodInfo.noOffset && memberList != null && !Modifier.isStatic(methodInfo.modifiers)) {
if (!memberList.contains(methodInfo.memberName[0])) {
memberList.add(methodInfo.memberName[0]);
}
}
didSomething = true;
out.print("JNIEXPORT " + jniTypeName(methodInfo.returnType) + " JNICALL Java_" + nativeName);
if (methodInfo.overloaded) {
out.print("__" + mangle(signature(methodInfo.parameterTypes)));
}
if (Modifier.isStatic(methodInfo.modifiers)) {
out.print("(JNIEnv* env, jclass cls");
} else {
out.print("(JNIEnv* env, jobject obj");
}
for (int j = 0; j < methodInfo.parameterTypes.length; j++) {
out.print(", " + jniTypeName(methodInfo.parameterTypes[j]) + " arg" + j);
}
out.println(") {");
if (callbackAllocators[i]) {
callbackAllocator(cls, callbackName);
continue;
} else if (!Modifier.isStatic(methodInfo.modifiers) && Pointer.class.isAssignableFrom(cls) && !methodInfo.allocator && !methodInfo.arrayAllocator && !methodInfo.deallocator) {
// get our "this" pointer
String[] typeName = cppTypeName(cls);
if ("void*".equals(typeName[0]) && !cls.isAnnotationPresent(Opaque.class)) {
typeName[0] = "char*";
} else if (FunctionPointer.class.isAssignableFrom(cls)) {
functions.index(cls);
typeName[0] = functionClassName(cls) + "*";
typeName[1] = "";
}
out.println(" " + typeName[0] + " ptr" + typeName[1] + " = (" + typeName[0] + typeName[1] + ")jlong_to_ptr(env->GetLongField(obj, JavaCPP_addressFID));");
out.println(" if (ptr == NULL) {");
out.println(" env->ThrowNew(JavaCPP_getClass(env, " + jclasses.index(NullPointerException.class) + "), \"This pointer address is NULL.\");");
out.println(" return" + (methodInfo.returnType == void.class ? ";" : " 0;"));
out.println(" }");
if (FunctionPointer.class.isAssignableFrom(cls)) {
out.println(" if (ptr->ptr == NULL) {");
out.println(" env->ThrowNew(JavaCPP_getClass(env, " + jclasses.index(NullPointerException.class) + "), \"This function pointer address is NULL.\");");
out.println(" return" + (methodInfo.returnType == void.class ? ";" : " 0;"));
out.println(" }");
}
if (!cls.isAnnotationPresent(Opaque.class)) {
out.println(" jlong position = env->GetLongField(obj, JavaCPP_positionFID);");
out.println(" ptr += position;");
if (methodInfo.bufferGetter) {
out.println(" jlong size = env->GetLongField(obj, JavaCPP_limitFID);");
out.println(" size -= position;");
}
}
}
parametersBefore(methodInfo);
String returnPrefix = returnBefore(methodInfo);
call(methodInfo, returnPrefix, false);
returnAfter(methodInfo);
parametersAfter(methodInfo);
if (methodInfo.throwsException != null) {
out.println(" if (exc != NULL) {");
out.println(" env->Throw(exc);");
out.println(" }");
}
if (methodInfo.returnType != void.class) {
out.println(" return rarg;");
}
out.println("}");
}
out.println();
return didSomething;
}
use of org.bytedeco.javacpp.annotation.Name 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;
}
Aggregations