private static void printParameterCaching( PrintWriter writer, TypeElement interface_decl, ExecutableElement method, Mode mode, boolean context_specific) { for (VariableElement param : method.getParameters()) { Class java_type = Utils.getJavaType(param.asType()); CachedReference cachedReference = param.getAnnotation(CachedReference.class); if (Buffer.class.isAssignableFrom(java_type) && cachedReference != null && (mode != Mode.BUFFEROBJECT || param.getAnnotation(BufferObject.class) == null) && param.getAnnotation(Result.class) == null) { writer.print("\t\tif ( LWJGLUtil.CHECKS ) StateTracker."); if (context_specific) { writer.print("getReferences(caps)."); } else { writer.print("getTracker()."); } if (cachedReference.name().length() > 0) { writer.print(cachedReference.name()); } else { writer.print(Utils.getReferenceName(interface_decl, method, param)); } if (cachedReference.index().length() > 0) { writer.print("[" + cachedReference.index() + "]"); } writer.println(" = " + param.getSimpleName() + ";"); } } }
private static String getResultType(ExecutableElement method, boolean native_stub) { if (native_stub && method.getAnnotation(PointerWrapper.class) != null) { return "long"; } else if (!native_stub && method.getAnnotation(GLreturn.class) != null) { return Utils.getMethodReturnType(method, method.getAnnotation(GLreturn.class), false); } else { return Utils.getJavaType(Utils.getMethodReturnType(method)).getSimpleName(); } }
private static void generateStringDeallocations( PrintWriter writer, Collection<ParameterDeclaration> params) { for (ParameterDeclaration param : params) { if (Utils.getJavaType(param.getType()).equals(String.class) && param.getAnnotation(Result.class) == null) writer.println("\tfree(" + param.getSimpleName() + BUFFER_ADDRESS_POSTFIX + ");"); else if (param.getAnnotation(StringList.class) != null) // Free the string array mem writer.println("\tfree(" + param.getSimpleName() + STRING_LIST_POSTFIX + ");"); } }
private static String getDefaultResultValue(ExecutableElement method) { if (method.getAnnotation(GLreturn.class) != null) { final String type = Utils.getMethodReturnType(method, method.getAnnotation(GLreturn.class), false); if ("boolean".equals(type)) { return "false"; } else if (Character.isLowerCase(type.charAt(0))) { return "0"; } else { return "null"; } } else { final Class type = Utils.getJavaType(Utils.getMethodReturnType(method)); if (type.isPrimitive()) { if (type == boolean.class) { return "false"; } else { return "0"; } } else { return "null"; } } }
private static void printParameterChecks( PrintWriter writer, ExecutableElement method, Map<VariableElement, TypeInfo> typeinfos, Mode mode, final boolean generate_error_checks) { if (mode == Mode.NORMAL) { final GenerateAutos gen_autos_annotation = method.getAnnotation(GenerateAutos.class); if (gen_autos_annotation != null && gen_autos_annotation.sizeVariables().length > 0) { // For the auto-generated parameters, declare and init a size variable (that can be reused // by @Code) for (final VariableElement param : method.getParameters()) { if (Arrays.binarySearch( gen_autos_annotation.sizeVariables(), param.getSimpleName().toString()) >= 0) { final int shifting = getBufferElementSizeExponent(typeinfos.get(param).getType()); final Check check_annotation = param.getAnnotation(Check.class); writer.print("\t\tlong " + param.getSimpleName() + "_size = "); if (check_annotation == null || !check_annotation.canBeNull()) { writer.println(param.getSimpleName() + ".remaining() << " + shifting + ";"); } else { writer.println( param.getSimpleName() + " == null ? 0 : " + param.getSimpleName() + ".remaining() << " + shifting + ";"); } } } } } for (VariableElement param : method.getParameters()) { Class java_type = Utils.getJavaType(param.asType()); if (java_type.isArray() || (Utils.isAddressableType(java_type) && (mode != Mode.BUFFEROBJECT || param.getAnnotation(BufferObject.class) == null) && (mode != Mode.AUTOS || getAutoTypeParameter(method, param) == null) && param.getAnnotation(Result.class) == null && !Utils.isReturnParameter(method, param))) { String check_value = null; boolean can_be_null = false; Check check_annotation = param.getAnnotation(Check.class); if (check_annotation != null) { check_value = check_annotation.value(); can_be_null = check_annotation.canBeNull(); } if ((Buffer.class.isAssignableFrom(java_type) || PointerBuffer.class.isAssignableFrom(java_type)) && param.getAnnotation(Constant.class) == null) { TypeInfo typeinfo = typeinfos.get(param); printParameterCheck( writer, method, param.getSimpleName().toString(), typeinfo.getType().getSimpleName(), check_value, can_be_null, param.getAnnotation(NullTerminated.class), generate_error_checks); } else if (String.class.equals(java_type)) { if (!can_be_null) { writer.println("\t\tBufferChecks.checkNotNull(" + param.getSimpleName() + ");"); } } else if (java_type.isArray()) { printArrayParameterCheck( writer, param.getSimpleName().toString(), check_value, can_be_null); } } } if (method.getAnnotation(CachedResult.class) != null) { printParameterCheck( writer, method, Utils.CACHED_BUFFER_NAME, null, null, true, null, generate_error_checks); } }
private static void printMethodWithMultiType( ProcessingEnvironment env, TypeMap type_map, PrintWriter writer, TypeElement interface_decl, ExecutableElement method, Map<VariableElement, TypeInfo> typeinfos_instance, Mode mode, boolean generate_error_checks, boolean context_specific) { Utils.printDocComment(writer, method, env); if (method.getAnnotation(Deprecated.class) != null) { writer.println("\t@Deprecated"); } if (interface_decl.getAnnotation(Private.class) == null && method.getAnnotation(Private.class) == null) { writer.print("\tpublic static "); } else { writer.print("\tstatic "); } writer.print(getResultType(method, false)); StripPostfix strip_annotation = method.getAnnotation(StripPostfix.class); String method_name; Alternate alt_annotation = method.getAnnotation(Alternate.class); method_name = alt_annotation == null || alt_annotation.javaAlt() ? method.getSimpleName().toString() : alt_annotation.value(); if (strip_annotation != null && mode == Mode.NORMAL) { method_name = getPostfixStrippedName(type_map, interface_decl, method); } writer.print(" " + method_name + "("); generateParametersJava(writer, method, typeinfos_instance, false, true, mode); writer.println(") {"); final TypeMirror result_type = Utils.getMethodReturnType(method); boolean has_result = !result_type.equals(env.getTypeUtils().getNoType(TypeKind.VOID)); final Reuse reuse_annotation = method.getAnnotation(Reuse.class); if (reuse_annotation != null) { writer.print("\t\t"); if (has_result || method.getAnnotation(GLreturn.class) != null) { writer.print("return "); } writer.print( reuse_annotation.value() + "." + (reuse_annotation.method().length() > 0 ? reuse_annotation.method() : method_name) + "("); generateParametersJava(writer, method, typeinfos_instance, false, false, mode); writer.println(");\n\t}"); return; } if (context_specific) { type_map.printCapabilitiesInit(writer); writer.print( "\t\tlong " + Utils.FUNCTION_POINTER_VAR_NAME + " = " + type_map.getCapabilities() + "."); writer.println(Utils.getFunctionAddressName(interface_decl, method, true) + ";"); writer.print("\t\tBufferChecks.checkFunctionAddress("); writer.println(Utils.FUNCTION_POINTER_VAR_NAME + ");"); } final Code code_annotation = method.getAnnotation(Code.class); if (code_annotation != null && code_annotation.value().length() > 0) { writer.println(code_annotation.value()); } printBufferObjectChecks(writer, method, mode, context_specific); printParameterChecks(writer, method, typeinfos_instance, mode, generate_error_checks); printParameterCaching(writer, interface_decl, method, mode, context_specific); if (code_annotation != null && code_annotation.javaBeforeNative().length() > 0) { writer.println(code_annotation.javaBeforeNative()); } writer.print("\t\t"); final PointerWrapper pointer_wrapper_annotation = method.getAnnotation(PointerWrapper.class); if (has_result) { writer.print(getResultType(method, false) + " " + Utils.RESULT_VAR_NAME); if (code_annotation != null && code_annotation.tryBlock()) { writer.print(" = " + getDefaultResultValue(method)); writer.println(";\n\t\ttry {"); writer.print("\t\t\t" + Utils.RESULT_VAR_NAME); } writer.print(" = "); if (pointer_wrapper_annotation != null) { if (pointer_wrapper_annotation.factory().length() > 0) { writer.print(pointer_wrapper_annotation.factory() + "("); } else { writer.print("new " + getResultType(method, false) + "("); } } } else if (method.getAnnotation(GLreturn.class) != null) { has_result = true; Utils.printGLReturnPre(writer, method, method.getAnnotation(GLreturn.class), type_map); } writer.print(Utils.getSimpleNativeMethodName(method, generate_error_checks, context_specific)); if (mode == Mode.BUFFEROBJECT) { writer.print(Utils.BUFFER_OBJECT_METHOD_POSTFIX); } writer.print("("); boolean first_parameter = printMethodCallArguments(writer, method, typeinfos_instance, mode, type_map); if (context_specific) { if (!first_parameter) { writer.print(", "); } writer.print(Utils.FUNCTION_POINTER_VAR_NAME); } if (has_result && pointer_wrapper_annotation != null) { writer.print(")"); if (pointer_wrapper_annotation.params().length() > 0) { writer.print(", " + pointer_wrapper_annotation.params()); } } writer.println(");"); if (code_annotation != null && code_annotation.javaAfterNative().length() > 0) { writer.println(code_annotation.javaAfterNative()); } final String tabs = code_annotation != null && code_annotation.tryBlock() ? "\t\t\t" : "\t\t"; if (generate_error_checks && method.getAnnotation(NoErrorCheck.class) == null) { type_map.printErrorCheckMethod(writer, method, tabs); } // DISABLED: indirect buffer support // printNondirectParameterCopies(writer, method, mode); if (has_result) { if (method.getAnnotation(GLreturn.class) == null) { if (ByteBuffer.class.equals(Utils.getJavaType(result_type))) { writer.println( tabs + "return LWJGLUtil.CHECKS && " + Utils.RESULT_VAR_NAME + " == null ? null : " + Utils.RESULT_VAR_NAME + ".order(ByteOrder.nativeOrder());"); // safeNewBuffer returns a direct // ByteBuffer with BIG_ENDIAN order. } else { writer.println(tabs + "return " + Utils.RESULT_VAR_NAME + ";"); } } else { Utils.printGLReturnPost(writer, method, method.getAnnotation(GLreturn.class), type_map); } } if (code_annotation != null && code_annotation.tryBlock()) { writer.println("\t\t} finally {"); writer.println(code_annotation.javaFinally()); writer.println("\t\t}"); } writer.println("\t}"); }
private static boolean generateBufferParameterAddress( TypeMap type_map, PrintWriter writer, MethodDeclaration method, ParameterDeclaration param, Mode mode, boolean loopDeclared) { NativeTypeTranslator translator = new NativeTypeTranslator(type_map, param); param.getType().accept(translator); writer.print("\t" + translator.getSignature() + param.getSimpleName()); writer.print(BUFFER_ADDRESS_POSTFIX + " = (("); writer.print(translator.getSignature()); Check check_annotation = param.getAnnotation(Check.class); writer.print(")"); if (mode == Mode.BUFFEROBJECT && param.getAnnotation(BufferObject.class) != null) { writer.print( "offsetToPointer(" + param.getSimpleName() + Utils.BUFFER_OBJECT_PARAMETER_POSTFIX + "))"); } else { Class java_type = Utils.getJavaType(param.getType()); if (Buffer.class.isAssignableFrom(java_type) || java_type.equals(CharSequence.class) || java_type.equals(CharSequence[].class)) { boolean explicitly_byte_sized = java_type.equals(Buffer.class) || translator.getAnnotationType().equals(type_map.getVoidType()); if (explicitly_byte_sized) writer.print("(((char *)"); if (method.getAnnotation(GenerateAutos.class) != null || (check_annotation != null && check_annotation.canBeNull())) { writer.print("safeGetBufferAddress(env, " + param.getSimpleName()); } else { writer.print("(*env)->GetDirectBufferAddress(env, " + param.getSimpleName()); } writer.print("))"); writer.print(" + " + param.getSimpleName() + BUFFER_POSITION_POSTFIX); if (explicitly_byte_sized) writer.print("))"); } else if (java_type.equals(String.class)) { writer.print("GetStringNativeChars(env, " + param.getSimpleName() + "))"); } else throw new RuntimeException("Illegal type " + java_type); } writer.println(";"); if (param.getAnnotation(StringList.class) != null) { if (Utils.getJavaType(param.getType()) != CharSequence[].class && (param.getAnnotation(GLchar.class) == null || param.getAnnotation(NullTerminated.class) == null || param.getAnnotation(NullTerminated.class).value().length() == 0)) throw new RuntimeException( "StringList annotation can only be applied on null-terminated GLchar buffers."); if ("_str".equals(param.getSimpleName())) throw new RuntimeException( "The name '_str' is not valid for arguments annotated with StringList"); // Declare loop counters and allocate string array if (!loopDeclared) { writer.println("\tunsigned int _str_i;"); writer.println("\tGLchar *_str_address;"); loopDeclared = true; } writer.println( "\tGLchar **" + param.getSimpleName() + STRING_LIST_POSTFIX + " = (GLchar **) malloc(" + param.getAnnotation(StringList.class).value() + "*sizeof(GLchar*));"); } return loopDeclared; }
private static void generateMethodStub( AnnotationProcessorEnvironment env, TypeMap type_map, PrintWriter writer, String interface_name, MethodDeclaration method, Mode mode, boolean generate_error_checks, boolean context_specific) { if (!context_specific && method.getAnnotation(Alternate.class) == null) writer.print("static "); else writer.print("JNIEXPORT "); TypeMirror result_type = Utils.getMethodReturnType(method); if (method.getAnnotation(GLpointer.class) != null) { writer.print("jlong"); } else { JNITypeTranslator translator = new JNITypeTranslator(); result_type.accept(translator); writer.print(translator.getSignature()); } writer.print(" JNICALL "); writer.print( Utils.getQualifiedNativeMethodName( interface_name, method, generate_error_checks, context_specific)); if (mode == Mode.BUFFEROBJECT) writer.print(Utils.BUFFER_OBJECT_METHOD_POSTFIX); writer.print("(JNIEnv *env, jclass clazz"); generateParameters(writer, method.getParameters(), mode); if (Utils.getNIOBufferType(result_type) != null) { CachedResult cached_result_annotation = method.getAnnotation(CachedResult.class); if (cached_result_annotation == null || !cached_result_annotation.isRange()) writer.print(", jlong " + Utils.RESULT_SIZE_NAME); if (cached_result_annotation != null) writer.print(", jobject " + Utils.CACHED_BUFFER_NAME); } if (context_specific) { writer.print(", jlong " + Utils.FUNCTION_POINTER_VAR_NAME); } writer.println(") {"); generateBufferParameterAddresses(type_map, writer, method, mode); Alternate alt_annotation = method.getAnnotation(Alternate.class); if (context_specific) { String typedef_name = Utils.getTypedefName(method); writer.print( "\t" + typedef_name + " " + (alt_annotation == null ? method.getSimpleName() : alt_annotation.value())); writer.print(" = (" + typedef_name + ")((intptr_t)"); writer.println(Utils.FUNCTION_POINTER_VAR_NAME + ");"); } generateStringListInits(writer, method.getParameters()); writer.print("\t"); if (!result_type.equals(env.getTypeUtils().getVoidType())) { Declaration return_declaration; ParameterDeclaration result_param = Utils.getResultParameter(method); if (result_param != null) return_declaration = result_param; else return_declaration = method; NativeTypeTranslator native_translator = new NativeTypeTranslator(type_map, return_declaration); result_type.accept(native_translator); writer.print(native_translator.getSignature() + " " + Utils.RESULT_VAR_NAME); if (result_param != null) { writer.println(";"); writer.print("\t"); } else writer.print(" = "); } writer.print((alt_annotation == null ? method.getSimpleName() : alt_annotation.value()) + "("); generateCallParameters(writer, type_map, method.getParameters()); writer.print(")"); writer.println(";"); generateStringDeallocations(writer, method.getParameters()); if (!result_type.equals(env.getTypeUtils().getVoidType())) { writer.print("\treturn "); Class java_result_type = Utils.getJavaType(result_type); if (Buffer.class.isAssignableFrom(java_result_type)) { if (method.getAnnotation(CachedResult.class) != null) writer.print("safeNewBufferCached(env, "); else writer.print("safeNewBuffer(env, "); } else if (String.class.equals(java_result_type)) { writer.print("NewStringNativeUnsigned(env, "); } else if (method.getAnnotation(GLpointer.class) != null) { writer.print("(intptr_t)"); } writer.print(Utils.RESULT_VAR_NAME); if (Buffer.class.isAssignableFrom(java_result_type)) { writer.print(", "); if (method.getAnnotation(CachedResult.class) != null && method.getAnnotation(CachedResult.class).isRange()) Utils.printExtraCallArguments( writer, method, method.getAnnotation(AutoResultSize.class).value()); else Utils.printExtraCallArguments(writer, method, Utils.RESULT_SIZE_NAME); } if (Buffer.class.isAssignableFrom(java_result_type) || String.class.equals(java_result_type)) writer.print(")"); writer.println(";"); } writer.println("}"); writer.println(); }