2005-02-15 06:05:36 -05:00
|
|
|
/*
|
2008-04-07 14:36:09 -04:00
|
|
|
* Copyright (c) 2002-2008 LWJGL Project
|
2005-02-15 06:05:36 -05:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are
|
|
|
|
* met:
|
|
|
|
*
|
|
|
|
* * Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
*
|
|
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* * Neither the name of 'LWJGL' nor the names of
|
|
|
|
* its contributors may be used to endorse or promote products derived
|
|
|
|
* from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
2005-02-20 14:28:34 -05:00
|
|
|
package org.lwjgl.util.generator;
|
2005-02-15 06:05:36 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* Various utility methods to the generator.
|
|
|
|
*
|
|
|
|
* @author elias_naur <elias_naur@users.sourceforge.net>
|
|
|
|
* @version $Revision$
|
2006-03-23 14:32:21 -05:00
|
|
|
* $Id$
|
2005-02-15 06:05:36 -05:00
|
|
|
*/
|
|
|
|
|
|
|
|
import com.sun.mirror.type.*;
|
|
|
|
import java.nio.Buffer;
|
|
|
|
import java.io.*;
|
|
|
|
import java.util.*;
|
|
|
|
|
|
|
|
import com.sun.mirror.declaration.*;
|
|
|
|
|
|
|
|
public class Utils {
|
2005-02-16 11:04:29 -05:00
|
|
|
public static final String TYPEDEF_POSTFIX = "PROC";
|
|
|
|
public static final String FUNCTION_POINTER_VAR_NAME = "function_pointer";
|
|
|
|
public static final String FUNCTION_POINTER_POSTFIX = "_pointer";
|
2005-03-21 03:27:45 -05:00
|
|
|
public static final String CHECKS_CLASS_NAME = "GLChecks";
|
2005-02-16 11:04:29 -05:00
|
|
|
public static final String CONTEXT_CAPS_CLASS_NAME = "ContextCapabilities";
|
2005-02-16 07:58:40 -05:00
|
|
|
public static final String STUB_INITIALIZER_NAME = "initNativeStubs";
|
2005-02-15 12:13:05 -05:00
|
|
|
public static final String BUFFER_OBJECT_METHOD_POSTFIX = "BO";
|
|
|
|
public static final String BUFFER_OBJECT_PARAMETER_POSTFIX = "_buffer_offset";
|
|
|
|
public static final String RESULT_SIZE_NAME = "result_size";
|
|
|
|
public static final String RESULT_VAR_NAME = "__result";
|
2010-01-04 13:47:49 -05:00
|
|
|
public static final String CACHED_BUFFER_LENGTH_NAME = "length";
|
2005-02-15 12:13:05 -05:00
|
|
|
public static final String CACHED_BUFFER_NAME = "old_buffer";
|
|
|
|
private static final String OVERLOADED_METHOD_PREFIX = "n";
|
2005-02-15 06:05:36 -05:00
|
|
|
|
2005-02-16 11:04:29 -05:00
|
|
|
public static String getTypedefName(MethodDeclaration method) {
|
|
|
|
return method.getSimpleName() + TYPEDEF_POSTFIX;
|
|
|
|
}
|
2010-01-04 13:47:49 -05:00
|
|
|
|
2005-02-16 11:04:29 -05:00
|
|
|
public static String getFunctionAddressName(InterfaceDeclaration interface_decl, MethodDeclaration method) {
|
|
|
|
return interface_decl.getSimpleName() + "_" + method.getSimpleName() + FUNCTION_POINTER_POSTFIX;
|
|
|
|
}
|
|
|
|
|
2005-02-16 07:58:40 -05:00
|
|
|
public static boolean isFinal(InterfaceDeclaration d) {
|
|
|
|
Extension extension_annotation = d.getAnnotation(Extension.class);
|
|
|
|
return extension_annotation == null || extension_annotation.isFinal();
|
|
|
|
}
|
|
|
|
|
2005-02-15 06:05:36 -05:00
|
|
|
private static class AnnotationMirrorComparator implements Comparator<AnnotationMirror> {
|
|
|
|
public int compare(AnnotationMirror a1, AnnotationMirror a2) {
|
|
|
|
String n1 = a1.getAnnotationType().getDeclaration().getQualifiedName();
|
|
|
|
String n2 = a2.getAnnotationType().getDeclaration().getQualifiedName();
|
|
|
|
int result = n1.compareTo(n2);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean equals(AnnotationMirror a1, AnnotationMirror a2) {
|
|
|
|
return compare(a1, a2) == 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Collection<AnnotationMirror> getSortedAnnotations(Collection<AnnotationMirror> annotations) {
|
|
|
|
List<AnnotationMirror> annotation_list = new ArrayList<AnnotationMirror>(annotations);
|
|
|
|
Collections.sort(annotation_list, new AnnotationMirrorComparator());
|
|
|
|
return annotation_list;
|
|
|
|
}
|
|
|
|
|
2005-03-21 03:27:45 -05:00
|
|
|
public static String getReferenceName(InterfaceDeclaration interface_decl, MethodDeclaration method, ParameterDeclaration param) {
|
|
|
|
return interface_decl.getSimpleName() + "_" + method.getSimpleName() + "_" + param.getSimpleName();
|
|
|
|
}
|
|
|
|
|
2005-02-15 06:05:36 -05:00
|
|
|
public static boolean isAddressableType(TypeMirror type) {
|
|
|
|
return isAddressableType(getJavaType(type));
|
|
|
|
}
|
2005-02-15 12:13:05 -05:00
|
|
|
|
2005-02-15 06:05:36 -05:00
|
|
|
public static boolean isAddressableType(Class type) {
|
|
|
|
return Buffer.class.isAssignableFrom(type) || String.class.equals(type);
|
|
|
|
}
|
2005-02-15 12:13:05 -05:00
|
|
|
|
2005-02-15 06:05:36 -05:00
|
|
|
public static Class getJavaType(TypeMirror type_mirror) {
|
|
|
|
JavaTypeTranslator translator = new JavaTypeTranslator();
|
|
|
|
type_mirror.accept(translator);
|
|
|
|
return translator.getType();
|
|
|
|
}
|
|
|
|
|
|
|
|
private static boolean hasParameterMultipleTypes(ParameterDeclaration param) {
|
|
|
|
int num_native_annotations = 0;
|
|
|
|
for (AnnotationMirror annotation : param.getAnnotationMirrors())
|
|
|
|
if (NativeTypeTranslator.getAnnotation(annotation, NativeType.class) != null)
|
|
|
|
num_native_annotations++;
|
|
|
|
return num_native_annotations > 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean isParameterMultiTyped(ParameterDeclaration param) {
|
|
|
|
boolean result = Buffer.class.equals(Utils.getJavaType(param.getType()));
|
|
|
|
if (!result && hasParameterMultipleTypes(param))
|
|
|
|
throw new RuntimeException(param + " not defined as java.nio.Buffer but has multiple types");
|
|
|
|
return result;
|
|
|
|
}
|
2005-02-15 12:13:05 -05:00
|
|
|
|
2005-02-15 06:05:36 -05:00
|
|
|
public static ParameterDeclaration findParameter(MethodDeclaration method, String name) {
|
|
|
|
for (ParameterDeclaration param : method.getParameters())
|
|
|
|
if (param.getSimpleName().equals(name))
|
|
|
|
return param;
|
|
|
|
throw new RuntimeException("Parameter " + name + " not found");
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void printDocComment(PrintWriter writer, Declaration decl) {
|
|
|
|
String doc_comment = decl.getDocComment();
|
|
|
|
if (doc_comment != null) {
|
|
|
|
writer.println("\t/**");
|
|
|
|
StringTokenizer doc_lines = new StringTokenizer(doc_comment, "\n");
|
|
|
|
while (doc_lines.hasMoreTokens())
|
|
|
|
writer.println("\t *" + doc_lines.nextToken());
|
|
|
|
writer.println("\t */");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static AnnotationMirror getParameterAutoAnnotation(ParameterDeclaration param) {
|
|
|
|
for (AnnotationMirror annotation : param.getAnnotationMirrors())
|
|
|
|
if (NativeTypeTranslator.getAnnotation(annotation, Auto.class) != null)
|
|
|
|
return annotation;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2005-02-16 11:04:29 -05:00
|
|
|
public static boolean isMethodIndirect(boolean generate_error_checks, boolean context_specific, MethodDeclaration method) {
|
2005-02-15 06:05:36 -05:00
|
|
|
for (ParameterDeclaration param : method.getParameters()) {
|
|
|
|
if (isAddressableType(param.getType()) || getParameterAutoAnnotation(param) != null ||
|
|
|
|
param.getAnnotation(Constant.class) != null)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return hasMethodBufferObjectParameter(method) || method.getAnnotation(Code.class) != null ||
|
|
|
|
method.getAnnotation(CachedResult.class) != null ||
|
2005-02-16 11:04:29 -05:00
|
|
|
(generate_error_checks && method.getAnnotation(NoErrorCheck.class) == null) ||
|
|
|
|
context_specific;
|
2005-02-15 06:05:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
public static String getNativeQualifiedName(String qualified_name) {
|
|
|
|
return qualified_name.replaceAll("\\.", "_");
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String getQualifiedNativeMethodName(String qualified_class_name, String method_name) {
|
|
|
|
return "Java_" + getNativeQualifiedName(qualified_class_name) + "_" + method_name;
|
|
|
|
}
|
|
|
|
|
2005-02-16 11:04:29 -05:00
|
|
|
public static String getQualifiedNativeMethodName(String qualified_class_name, MethodDeclaration method, boolean generate_error_checks, boolean context_specific) {
|
|
|
|
String method_name = getSimpleNativeMethodName(method, generate_error_checks, context_specific);
|
2005-02-15 06:05:36 -05:00
|
|
|
return getQualifiedNativeMethodName(qualified_class_name, method_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static ParameterDeclaration getResultParameter(MethodDeclaration method) {
|
|
|
|
ParameterDeclaration result_param = null;
|
|
|
|
for (ParameterDeclaration param : method.getParameters()) {
|
|
|
|
if (param.getAnnotation(Result.class) != null) {
|
|
|
|
if (result_param != null)
|
|
|
|
throw new RuntimeException("Multiple parameters annotated with Result in method " + method);
|
|
|
|
result_param = param;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result_param;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static TypeMirror getMethodReturnType(MethodDeclaration method) {
|
|
|
|
TypeMirror result_type;
|
|
|
|
ParameterDeclaration result_param = getResultParameter(method);
|
|
|
|
if (result_param != null) {
|
|
|
|
result_type = result_param.getType();
|
|
|
|
} else
|
|
|
|
result_type = method.getReturnType();
|
|
|
|
return result_type;
|
|
|
|
}
|
2005-02-15 12:13:05 -05:00
|
|
|
|
2005-02-16 11:04:29 -05:00
|
|
|
public static boolean needResultSize(MethodDeclaration method) {
|
2006-12-20 14:19:56 -05:00
|
|
|
return getNIOBufferType(getMethodReturnType(method)) != null && method.getAnnotation(AutoResultSize.class) == null;
|
2005-02-16 11:04:29 -05:00
|
|
|
}
|
2010-01-04 13:47:49 -05:00
|
|
|
|
2005-02-16 11:04:29 -05:00
|
|
|
public static void printExtraCallArguments(PrintWriter writer, MethodDeclaration method, String size_parameter_name) {
|
|
|
|
writer.print(size_parameter_name);
|
2005-02-15 06:05:36 -05:00
|
|
|
if (method.getAnnotation(CachedResult.class) != null) {
|
|
|
|
writer.print(", " + CACHED_BUFFER_NAME);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static String getClassName(InterfaceDeclaration interface_decl, String opengl_name) {
|
|
|
|
Extension extension_annotation = interface_decl.getAnnotation(Extension.class);
|
2005-02-15 12:13:05 -05:00
|
|
|
if (extension_annotation != null && !"".equals(extension_annotation.className())) {
|
2005-02-15 06:05:36 -05:00
|
|
|
return extension_annotation.className();
|
|
|
|
}
|
|
|
|
StringBuilder result = new StringBuilder();
|
|
|
|
for (int i = 0; i < opengl_name.length(); i++) {
|
|
|
|
int ch = opengl_name.codePointAt(i);
|
|
|
|
if (ch == '_') {
|
|
|
|
i++;
|
|
|
|
result.appendCodePoint(Character.toUpperCase(opengl_name.codePointAt(i)));
|
|
|
|
} else
|
|
|
|
result.appendCodePoint(ch);
|
|
|
|
}
|
|
|
|
return result.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean hasMethodBufferObjectParameter(MethodDeclaration method) {
|
|
|
|
for (ParameterDeclaration param : method.getParameters()) {
|
|
|
|
if (param.getAnnotation(BufferObject.class) != null) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String getQualifiedClassName(InterfaceDeclaration interface_decl) {
|
|
|
|
return interface_decl.getPackage().getQualifiedName() + "." + getSimpleClassName(interface_decl);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String getSimpleClassName(InterfaceDeclaration interface_decl) {
|
|
|
|
return getClassName(interface_decl, interface_decl.getSimpleName());
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Class<?> getNIOBufferType(TypeMirror t) {
|
|
|
|
Class<?> param_type = getJavaType(t);
|
|
|
|
if (Buffer.class.isAssignableFrom(param_type))
|
|
|
|
return param_type;
|
|
|
|
else
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2005-02-16 11:04:29 -05:00
|
|
|
public static String getSimpleNativeMethodName(MethodDeclaration method, boolean generate_error_checks, boolean context_specific) {
|
2010-03-11 16:06:49 -05:00
|
|
|
String method_name;
|
|
|
|
Alternate alt_annotation = method.getAnnotation(Alternate.class);
|
|
|
|
method_name = alt_annotation == null ? method.getSimpleName() : alt_annotation.value();
|
2005-02-16 11:04:29 -05:00
|
|
|
if (isMethodIndirect(generate_error_checks, context_specific, method))
|
2005-02-15 06:05:36 -05:00
|
|
|
method_name = OVERLOADED_METHOD_PREFIX + method_name;
|
|
|
|
return method_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|