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 printMethodCallArgument( PrintWriter writer, ExecutableElement method, VariableElement param, Map<VariableElement, TypeInfo> typeinfos_instance, Mode mode, boolean first_parameter, TypeMap type_map) { if (!first_parameter) { writer.print(", "); } AnnotationMirror auto_annotation = Utils.getParameterAutoAnnotation(param); Constant constant_annotation = param.getAnnotation(Constant.class); if (constant_annotation != null) { writer.print(constant_annotation.value()); } else if (auto_annotation != null && mode == Mode.NORMAL) { Class param_type = NativeTypeTranslator.getClassFromType(auto_annotation.getAnnotationType()); if (AutoType.class.equals(param_type)) { final AutoType auto_type_annotation = param.getAnnotation(AutoType.class); final VariableElement auto_parameter = Utils.findParameter(method, auto_type_annotation.value()); final String auto_type = typeinfos_instance.get(auto_parameter).getAutoType(); if (auto_type == null) { throw new RuntimeException( "No auto type for parameter " + param.getSimpleName() + " in method " + method); } writer.print(auto_type); } else if (AutoSize.class.equals(param_type)) { final AutoSize auto_size_annotation = param.getAnnotation(AutoSize.class); if (!auto_size_annotation.useExpression()) { final String auto_parameter_name = auto_size_annotation.value(); final VariableElement auto_target_param = Utils.findParameter(method, auto_parameter_name); final TypeInfo auto_target_type_info = typeinfos_instance.get(auto_target_param); final boolean shift_remaining = !hasAnyParameterAutoTypeAnnotation(method, auto_target_param) && Utils.isParameterMultiTyped(auto_target_param); int shifting = 0; if (shift_remaining) { shifting = getBufferElementSizeExponent(auto_target_type_info.getType()); if (shifting > 0) { writer.print("("); } } if (auto_size_annotation.canBeNull()) { writer.print( "(" + auto_parameter_name + " == null ? 0 : " + auto_parameter_name + ".remaining())"); } else { writer.print(auto_parameter_name + ".remaining()"); } // Shift the remaining if the target parameter is multityped and there's no AutoType to // track type if (shift_remaining && shifting > 0) { writer.print(" << " + shifting); writer.print(")"); } } writer.print(auto_size_annotation.expression()); } else { throw new RuntimeException("Unknown auto annotation " + param_type); } } else { if (mode == Mode.BUFFEROBJECT && param.getAnnotation(BufferObject.class) != null) { writer.print(param.getSimpleName() + Utils.BUFFER_OBJECT_PARAMETER_POSTFIX); } else { Class type = typeinfos_instance.get(param).getType(); Check check_annotation = param.getAnnotation(Check.class); boolean hide_buffer = mode == Mode.AUTOS && getAutoTypeParameter(method, param) != null; if (hide_buffer) { writer.print("0L"); } else { if (type == CharSequence.class || type == CharSequence[].class) { final String offset = Utils.getStringOffset(method, param); writer.print("APIUtil.getBuffer"); if (param.getAnnotation(NullTerminated.class) != null) { writer.print("NT"); } writer.print('('); writer.print(type_map.getAPIUtilParam(true)); writer.print(param.getSimpleName()); if (offset != null) { writer.print(", " + offset); } writer.print(")"); } else { final AutoSize auto_size_annotation = param.getAnnotation(AutoSize.class); if (auto_size_annotation != null) { writer.print(auto_size_annotation.value() + "_"); } final Class buffer_type = Utils.getNIOBufferType(param.asType()); if (buffer_type == null) { writer.print(param.getSimpleName()); } else { writer.print("MemoryUtil.getAddress"); if (check_annotation != null && check_annotation.canBeNull()) { writer.print("Safe"); } writer.print("("); writer.print(param.getSimpleName()); writer.print(")"); } } } if (type != long.class) { PointerWrapper pointer_annotation = param.getAnnotation(PointerWrapper.class); if (pointer_annotation != null) { if (pointer_annotation.canBeNull()) { writer.print(" == null ? 0 : " + param.getSimpleName()); } writer.print(".getPointer()"); } } } } return false; }
/** * Ensures space for an additional pointer value, sets the specified value at the allocated offset * and returns that offset. */ public int pointerParam(PointerWrapper value) { return pointerParam(value.getPointer()); }