private static void generateCallParameter(
     PrintWriter writer, TypeMap type_map, ParameterDeclaration param) {
   boolean is_indirect = param.getAnnotation(Indirect.class) != null;
   if (is_indirect || param.getAnnotation(StringList.class) != null) {
     writer.print("(");
     NativeTypeTranslator translator = new NativeTypeTranslator(type_map, param);
     param.getType().accept(translator);
     writer.print(translator.getSignature());
     writer.print("*)");
   }
   if (param.getAnnotation(GLpointer.class) != null)
     writer.print("(" + param.getAnnotation(GLpointer.class).value() + ")(intptr_t)");
   if (param.getAnnotation(Result.class) != null || is_indirect) writer.print("&");
   if (param.getAnnotation(Result.class) != null) {
     writer.print(Utils.RESULT_VAR_NAME);
   } else {
     writer.print(param.getSimpleName());
     if (param.getAnnotation(StringList.class) != null) writer.print(STRING_LIST_POSTFIX);
     else if (Utils.isAddressableType(param.getType())) writer.print(BUFFER_ADDRESS_POSTFIX);
   }
 }
Exemple #2
0
 public String getAutoTypeFromAnnotation(AnnotationMirror annotation) {
   Class annotation_class = NativeTypeTranslator.getClassFromType(annotation.getAnnotationType());
   if (annotation_class.equals(GLint.class)) return "GL11.GL_INT";
   else if (annotation_class.equals(GLbyte.class)) return "GL11.GL_BYTE";
   else if (annotation_class.equals(GLshort.class)) return "GL11.GL_SHORT";
   if (annotation_class.equals(GLuint.class)) return "GL11.GL_UNSIGNED_INT";
   else if (annotation_class.equals(GLubyte.class)) return "GL11.GL_UNSIGNED_BYTE";
   else if (annotation_class.equals(GLushort.class)) return "GL11.GL_UNSIGNED_SHORT";
   else if (annotation_class.equals(GLfloat.class)) return "GL11.GL_FLOAT";
   else if (annotation_class.equals(GLdouble.class)) return "GL11.GL_DOUBLE";
   else return null;
 }
 private static VariableElement getAutoTypeParameter(
     ExecutableElement method, VariableElement target_parameter) {
   for (VariableElement param : method.getParameters()) {
     AnnotationMirror auto_annotation = Utils.getParameterAutoAnnotation(param);
     if (auto_annotation != null) {
       Class annotation_type =
           NativeTypeTranslator.getClassFromType(auto_annotation.getAnnotationType());
       String parameter_name;
       if (annotation_type.equals(AutoType.class)) {
         parameter_name = param.getAnnotation(AutoType.class).value();
       } else if (annotation_type.equals(AutoSize.class)) {
         parameter_name = param.getAnnotation(AutoSize.class).value();
       } else {
         throw new RuntimeException("Unknown annotation type " + annotation_type);
       }
       if (target_parameter.getSimpleName().toString().equals(parameter_name)) {
         return param;
       }
     }
   }
   return null;
 }
  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;
  }
  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();
  }