lwjgl/src/java/org/lwjgl/util/generator/RegisterStubsGenerator.java

150 lines
6.3 KiB
Java

/*
* Copyright (c) 2002-2008 LWJGL Project
* 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.
*/
package org.lwjgl.util.generator;
/**
*
* This class generates the initNatives native function.
*
* @author elias_naur <elias_naur@users.sourceforge.net>
* @version $Revision$ $Id$
*/
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
public class RegisterStubsGenerator {
public static void generateMethodsNativeStubBind(PrintWriter writer, TypeElement d, boolean generate_error_checks, boolean context_specific) {
Iterator<? extends ExecutableElement> it = Utils.getMethods(d).iterator();
while ( it.hasNext() ) {
ExecutableElement method = it.next();
Alternate alt_annotation = method.getAnnotation(Alternate.class);
if ( (alt_annotation != null && (!alt_annotation.nativeAlt() || alt_annotation.skipNative())) || method.getAnnotation(Reuse.class) != null ) {
continue;
}
EnumSet<Platform> platforms;
PlatformDependent platform_annotation = method.getAnnotation(PlatformDependent.class);
if ( platform_annotation != null ) {
platforms = EnumSet.copyOf(Arrays.asList(platform_annotation.value()));
} else {
platforms = EnumSet.of(Platform.ALL);
}
for ( Platform platform : platforms ) {
platform.printPrologue(writer);
boolean has_buffer_parameter = Utils.hasMethodBufferObjectParameter(method);
printMethodNativeStubBind(writer, d, method, platform, Mode.NORMAL, it.hasNext() || has_buffer_parameter, generate_error_checks, context_specific);
if ( has_buffer_parameter ) {
printMethodNativeStubBind(writer, d, method, platform, Mode.BUFFEROBJECT, it.hasNext(), generate_error_checks, context_specific);
}
platform.printEpilogue(writer);
}
}
writer.println();
}
private static String getTypeSignature(TypeMirror type) {
SignatureTranslator v = new SignatureTranslator();
type.accept(v, null);
return v.getSignature();
}
private static String getMethodSignature(ExecutableElement method, Mode mode) {
List<? extends VariableElement> params = method.getParameters();
String signature = "(";
for ( VariableElement param : params ) {
if ( param.getAnnotation(Result.class) != null || (param.getAnnotation(Helper.class) != null && !param.getAnnotation(Helper.class).passToNative()) ) {
continue;
}
final Constant constant_annotation = param.getAnnotation(Constant.class);
if ( constant_annotation != null && constant_annotation.isNative() ) {
continue;
}
if ( mode == Mode.BUFFEROBJECT && param.getAnnotation(BufferObject.class) != null ) {
signature += "J";
} else {
signature += getTypeSignature(param.asType());
}
}
final TypeMirror result_type = Utils.getMethodReturnType(method);
final CachedResult cached_result_annotation = method.getAnnotation(CachedResult.class);
final AutoSize auto_size_annotation = method.getAnnotation(AutoSize.class);
final boolean isNIOBuffer = Utils.getNIOBufferType(result_type) != null;
if ( isNIOBuffer && (auto_size_annotation == null || !auto_size_annotation.isNative()) ) {
signature += "J";
}
final String result_type_signature = isNIOBuffer ? "Ljava/nio/ByteBuffer;" : getTypeSignature(result_type);
if ( cached_result_annotation != null ) {
signature += result_type_signature;
}
signature += ")";
signature += result_type_signature;
return signature;
}
private static final Pattern GL_PATTERN = Pattern.compile("gl");
private static void printMethodNativeStubBind(PrintWriter writer, TypeElement d, ExecutableElement method, Platform platform, Mode mode, boolean has_more, boolean generate_error_checks, boolean context_specific) {
writer.print("\t\t{\"" + Utils.getSimpleNativeMethodName(method, generate_error_checks, context_specific));
if ( mode == Mode.BUFFEROBJECT ) {
writer.print(Utils.BUFFER_OBJECT_METHOD_POSTFIX);
}
writer.print("\", \"" + getMethodSignature(method, mode) + "\", (void *)&");
writer.print(Utils.getQualifiedNativeMethodName(Utils.getQualifiedClassName(d), method, generate_error_checks, context_specific));
if ( mode == Mode.BUFFEROBJECT ) {
writer.print(Utils.BUFFER_OBJECT_METHOD_POSTFIX);
}
final Alternate alt_annotation = method.getAnnotation(Alternate.class);
final String methodName = alt_annotation == null ? method.getSimpleName().toString() : alt_annotation.value();
String opengl_handle_name = GL_PATTERN.matcher(methodName).replaceFirst(platform.getPrefix());
writer.print(", \"" + opengl_handle_name + "\", (void *)&" + methodName + ", " + (method.getAnnotation(Optional.class) == null ? "false" : "true") + "}");
if ( has_more ) {
writer.println(",");
}
}
}