Optimize generators

This commit is contained in:
Michael Pfaff 2022-09-08 07:10:40 -04:00
parent 632dac735a
commit 0ebbec4e7f
Signed by: michael
GPG Key ID: CF402C4A012AA9D4
16 changed files with 432 additions and 493 deletions

View File

@ -42,6 +42,7 @@ import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeMirror;
public class FieldsGenerator { public class FieldsGenerator {
private static final Object sync = new Object();
private static void validateField(VariableElement field) { private static void validateField(VariableElement field) {
// Check if field is "public static final" // Check if field is "public static final"
@ -69,7 +70,10 @@ public class FieldsGenerator {
throw new RuntimeException("Field " + field.getSimpleName() + " is not a primitive type or String"); throw new RuntimeException("Field " + field.getSimpleName() + " is not a primitive type or String");
} }
Object field_value = field.getConstantValue(); Object field_value;
synchronized (sync) {
field_value = field.getConstantValue();
}
if ( field_value == null ) { if ( field_value == null ) {
throw new RuntimeException("Field " + field.getSimpleName() + " has no initial value"); throw new RuntimeException("Field " + field.getSimpleName() + " has no initial value");
} }
@ -124,4 +128,4 @@ public class FieldsGenerator {
} }
} }
} }

View File

@ -75,7 +75,8 @@ public class GeneratorProcessor extends AbstractProcessor {
try { try {
TypeMap type_map = (TypeMap)(Class.forName(typemap_classname).newInstance()); TypeMap type_map = (TypeMap)(Class.forName(typemap_classname).newInstance());
ElementFilter.typesIn(roundEnv.getRootElements()).stream().sequential().forEach(file -> { //ElementFilter.typesIn(roundEnv.getRootElements()).stream().sequential().forEach(file -> {
ElementFilter.typesIn(roundEnv.getRootElements()).parallelStream().forEach(file -> {
try { try {
file.accept(new GeneratorVisitor(processingEnv, gen_java_path, gen_native_path, type_map, generate_error_checks, context_specific), null); file.accept(new GeneratorVisitor(processingEnv, gen_java_path, gen_native_path, type_map, generate_error_checks, context_specific), null);
} catch (Exception e) { } catch (Exception e) {

View File

@ -48,6 +48,7 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.*; import javax.lang.model.element.*;
import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeKind;
@ -135,14 +136,16 @@ public class GeneratorVisitor extends ElementKindVisitor6<Void, Void> {
} }
private void validateTypes(ExecutableElement method, List<? extends AnnotationMirror> annotations, TypeMirror type_mirror) { private void validateTypes(ExecutableElement method, List<? extends AnnotationMirror> annotations, TypeMirror type_mirror) {
if (true) {
// TODO: remove if we reimplement validateType.
return;
}
String desc = Utils.getDescriptor(type_mirror);
if ( BUFFER_DESC.equals(desc) ) return;
for ( AnnotationMirror annotation : annotations ) { for ( AnnotationMirror annotation : annotations ) {
NativeType native_type_annotation = NativeTypeTranslator.getAnnotation(annotation, NativeType.class); NativeType native_type_annotation = NativeTypeTranslator.getAnnotation(annotation, NativeType.class);
if ( native_type_annotation != null ) { if ( native_type_annotation != null ) {
Class<? extends Annotation> annotation_type = NativeTypeTranslator.getClassFromType(annotation.getAnnotationType()); Class<? extends Annotation> annotation_type = NativeTypeTranslator.getClassFromType(annotation.getAnnotationType());
String desc = Utils.getDescriptor(type_mirror);
if ( BUFFER_DESC.equals(desc) ) {
continue;
}
validateType(method, annotation_type, desc); validateType(method, annotation_type, desc);
} }
} }
@ -205,34 +208,32 @@ public class GeneratorVisitor extends ElementKindVisitor6<Void, Void> {
private static void generateMethodNativePointers(PrintWriter writer, ExecutableElement method) { private static void generateMethodNativePointers(PrintWriter writer, ExecutableElement method) {
if ( method.getAnnotation(Extern.class) == null ) { if ( method.getAnnotation(Extern.class) == null ) {
writer.print("static "); writer.append("static ");
} }
writer.println(Utils.getTypedefName(method) + " " + method.getSimpleName() + ";"); writer.append(Utils.getTypedefName(method)).append(' ').append(method.getSimpleName()).append(";\n");
} }
private void generateJavaSource(TypeElement d, PrintWriter java_writer) throws IOException { private void generateJavaSource(TypeElement d, PrintWriter java_writer) throws IOException {
java_writer.println("/* MACHINE GENERATED FILE, DO NOT EDIT */"); java_writer.append("/* MACHINE GENERATED FILE, DO NOT EDIT */\n\n");
java_writer.println(); java_writer.append("package ").append(env.getElementUtils().getPackageOf(d).getQualifiedName().toString()).append(";\n\n");
java_writer.append("package ").append(env.getElementUtils().getPackageOf(d).getQualifiedName().toString()).append(";\n"); java_writer.append("import org.lwjgl.*;\n"
java_writer.println(); + "import java.nio.*;\n");
java_writer.println("import org.lwjgl.*;");
java_writer.println("import java.nio.*;");
Imports imports = d.getAnnotation(Imports.class); Imports imports = d.getAnnotation(Imports.class);
if ( imports != null ) { if ( imports != null ) {
for ( String i : imports.value() ) { for ( String i : imports.value() ) {
java_writer.append("import ").append(i).append(";\n"); java_writer.append("import ").append(i).append(";\n");
} }
} }
java_writer.println(); java_writer.append('\n');
Utils.printDocComment(java_writer, d, env); Utils.printDocComment(java_writer, d, env);
if ( d.getAnnotation(Private.class) == null ) { if ( d.getAnnotation(Private.class) == null ) {
java_writer.print("public "); java_writer.append("public ");
} }
boolean is_final = Utils.isFinal(d); boolean is_final = Utils.isFinal(d);
if ( is_final ) { if ( is_final ) {
java_writer.write("final "); java_writer.append("final ");
} }
java_writer.print("class " + Utils.getSimpleClassName(d)); java_writer.append("class ").append(Utils.getSimpleClassName(d));
List<? extends TypeMirror> super_interfaces = d.getInterfaces(); List<? extends TypeMirror> super_interfaces = d.getInterfaces();
if ( super_interfaces.size() > 1 ) { if ( super_interfaces.size() > 1 ) {
throw new RuntimeException(d + " extends more than one interface"); throw new RuntimeException(d + " extends more than one interface");
@ -241,19 +242,19 @@ public class GeneratorVisitor extends ElementKindVisitor6<Void, Void> {
TypeMirror super_interface = super_interfaces.iterator().next(); TypeMirror super_interface = super_interfaces.iterator().next();
java_writer.append(" extends ").append(Utils.getSimpleClassName(env.getElementUtils().getTypeElement(super_interface.toString()))); java_writer.append(" extends ").append(Utils.getSimpleClassName(env.getElementUtils().getTypeElement(super_interface.toString())));
} }
java_writer.println(" {"); java_writer.append(" {\n");
FieldsGenerator.generateFields(env, java_writer, Utils.getFields(d)); FieldsGenerator.generateFields(env, java_writer, Utils.getFields(d));
java_writer.println(); java_writer.append('\n');
if ( is_final ) { if ( is_final ) {
// Write private constructor to avoid instantiation // Write private constructor to avoid instantiation
java_writer.append("\tprivate ").append(Utils.getSimpleClassName(d)).append("() {}\n"); java_writer.append("\tprivate ").append(Utils.getSimpleClassName(d)).append("() {}\n");
} }
if ( Utils.getMethods(d).size() > 0 && !context_specific ) { if ( Utils.getMethods(d).size() > 0 && !context_specific ) {
java_writer.println(); java_writer.append('\n');
java_writer.append("\tstatic native void ").append(Utils.STUB_INITIALIZER_NAME).append("() throws LWJGLException;\n"); java_writer.append("\tstatic native void ").append(Utils.STUB_INITIALIZER_NAME).append("() throws LWJGLException;\n");
} }
JavaMethodsGenerator.generateMethodsJava(env, type_map, java_writer, d, generate_error_checks, context_specific); JavaMethodsGenerator.generateMethodsJava(env, type_map, java_writer, d, generate_error_checks, context_specific);
java_writer.println("}"); java_writer.append("}");
} }
private void generateNativeSource(TypeElement d, long startTime) throws IOException { private void generateNativeSource(TypeElement d, long startTime) throws IOException {
@ -264,34 +265,33 @@ public class GeneratorVisitor extends ElementKindVisitor6<Void, Void> {
StringWriter native_writer1 = new StringWriter(); StringWriter native_writer1 = new StringWriter();
PrintWriter native_writer = new PrintWriter(native_writer1); PrintWriter native_writer = new PrintWriter(native_writer1);
native_writer.println("/* MACHINE GENERATED FILE, DO NOT EDIT */"); native_writer.append("/* MACHINE GENERATED FILE, DO NOT EDIT */\n\n");
native_writer.println(); native_writer.append("#include <jni.h>\n");
native_writer.println("#include <jni.h>");
type_map.printNativeIncludes(native_writer); type_map.printNativeIncludes(native_writer);
native_writer.println(); native_writer.append('\n');
TypedefsGenerator.generateNativeTypedefs(type_map, native_writer, Utils.getMethods(d)); TypedefsGenerator.generateNativeTypedefs(type_map, native_writer, Utils.getMethods(d));
native_writer.println(); native_writer.append('\n');
if (!context_specific) { if (!context_specific) {
generateMethodsNativePointers(native_writer, Utils.getMethods(d)); generateMethodsNativePointers(native_writer, Utils.getMethods(d));
native_writer.println(); native_writer.append('\n');
} }
NativeMethodStubsGenerator.generateNativeMethodStubs(env, type_map, native_writer, d, generate_error_checks, context_specific); NativeMethodStubsGenerator.generateNativeMethodStubs(env, type_map, native_writer, d, generate_error_checks, context_specific);
if (!context_specific) { if (!context_specific) {
native_writer.print("JNIEXPORT void JNICALL " + Utils.getQualifiedNativeMethodName(qualified_interface_name, Utils.STUB_INITIALIZER_NAME)); native_writer.append("JNIEXPORT void JNICALL ").append(Utils.getQualifiedNativeMethodName(qualified_interface_name, Utils.STUB_INITIALIZER_NAME));
native_writer.println("(JNIEnv *env, jclass clazz) {"); native_writer.append("(JNIEnv *env, jclass clazz) {\n");
native_writer.println("\tJavaMethodAndExtFunction functions[] = {"); native_writer.append("\tJavaMethodAndExtFunction functions[] = {\n");
RegisterStubsGenerator.generateMethodsNativeStubBind(native_writer, d, generate_error_checks, context_specific); RegisterStubsGenerator.generateMethodsNativeStubBind(native_writer, d, generate_error_checks, context_specific);
native_writer.println("\t};"); native_writer.append("\t};\n");
native_writer.println("\tint num_functions = NUMFUNCTIONS(functions);"); native_writer.append("\tint num_functions = NUMFUNCTIONS(functions);\n");
native_writer.print("\t"); native_writer.append('\t');
native_writer.print(type_map.getRegisterNativesFunctionName()); native_writer.append(type_map.getRegisterNativesFunctionName());
native_writer.println("(env, clazz, num_functions, functions);"); native_writer.append("(env, clazz, num_functions, functions);\n");
native_writer.println("}"); native_writer.append("}");
} }
saveGeneratedCSource(env, this.gen_native_path, d, native_writer1.toString(), startTime); saveGeneratedCSource(env.getMessager(), this.gen_native_path, d, native_writer1.toString(), startTime);
} }
private static boolean isFileExistingAndIdentical(ProcessingEnvironment env, Path file, String expected) throws IOException { private static boolean isFileExistingAndIdentical(Messager messager, Path file, String expected) throws IOException {
if (!Files.exists(file)) return false; if (!Files.exists(file)) return false;
try (Reader existingIs = Files.newBufferedReader(file, Charset.forName("UTF-8"))) { try (Reader existingIs = Files.newBufferedReader(file, Charset.forName("UTF-8"))) {
@ -302,15 +302,15 @@ public class GeneratorVisitor extends ElementKindVisitor6<Void, Void> {
if (c == -1) return i == expected.length(); if (c == -1) return i == expected.length();
if (expected.length() <= i || c != expected.charAt(i++)) { if (expected.length() <= i || c != expected.charAt(i++)) {
if (expected.length() > (i-1)) { if (expected.length() > (i-1)) {
env.getMessager().printMessage(Kind.NOTE, "mismatch at " + i + ": '" + ((char) c) + '\''); messager.printMessage(Kind.NOTE, "mismatch at " + i + ": '" + ((char) c) + '\'');
} else { } else {
env.getMessager().printMessage(Kind.NOTE, "mismatch at " + i + ": EOF in expected"); messager.printMessage(Kind.NOTE, "mismatch at " + i + ": EOF in expected");
} }
return false; return false;
} }
} while (c != -1); } while (c != -1);
if (i != expected.length()) { if (i != expected.length()) {
env.getMessager().printMessage(Kind.NOTE, "mismatch at " + i + ": EOF in existing"); messager.printMessage(Kind.NOTE, "mismatch at " + i + ": EOF in existing");
return false; return false;
} }
} }
@ -318,84 +318,91 @@ public class GeneratorVisitor extends ElementKindVisitor6<Void, Void> {
return true; return true;
} }
private void doJavaGen(TypeElement e) {
long startTime = System.currentTimeMillis();
StringWriter java_writer = new StringWriter();
try {
generateJavaSource(e, new PrintWriter(java_writer));
} catch (IOException ex) {
throw new RuntimeException("Failed to generate the Java sources for " + e, ex);
}
saveGeneratedJavaSource(env.getMessager(), this.gen_java_path, e, java_writer.toString(), startTime);
}
@Override @Override
public Void visitTypeAsInterface(TypeElement e, Void p) { public Void visitTypeAsInterface(TypeElement e, Void p) {
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
final File input = new File("src/templates/" + e.getQualifiedName().toString().replace('.', '/') + ".java");
final Collection<? extends ExecutableElement> methods = Utils.getMethods(e); final Collection<? extends ExecutableElement> methods = Utils.getMethods(e);
if (methods.isEmpty() && Utils.getFields(e).isEmpty()) { if (methods.isEmpty() && Utils.getFields(e).isEmpty()) {
return DEFAULT_VALUE; return DEFAULT_VALUE;
} }
//env.getMessager().printMessage(Kind.NOTE, "methods count : " + Utils.getMethods(e).size() + " fields count : " + Utils.getFields(e).size(), e); //env.getMessager().printMessage(Kind.NOTE, "methods count : " + Utils.getMethods(e).size() + " fields count : " + Utils.getFields(e).size(), e);
for (ExecutableElement method : methods) { methods.parallelStream().forEach(method -> validateMethod(method));
validateMethod(method);
long elapsed = System.currentTimeMillis() - startTime;
if (elapsed > 5) {
env.getMessager().printMessage(Diagnostic.Kind.WARNING, "Validated " + e + " in " + elapsed + " ms.\n\t**** SIGNIFICANT AMOUNT OF TIME");
} else {
env.getMessager().printMessage(Diagnostic.Kind.NOTE, "Validated " + e + " in " + elapsed + " ms.");
} }
Thread javaGenThread = new Thread((Runnable) () -> { if (methods.size() > 0) {
StringWriter java_writer = new StringWriter(); Thread javaGenThread = new Thread((Runnable) () -> {
try { doJavaGen(e);
generateJavaSource(e, new PrintWriter(java_writer)); });
} catch (IOException ex) { javaGenThread.start();
throw new RuntimeException("Failed to generate the Java sources for " + e, ex);
}
saveGeneratedJavaSource(env, this.gen_java_path, e, java_writer.toString(), startTime);
});
javaGenThread.start();
Thread cGenThread = new Thread((Runnable) () -> {
long startTime1 = System.currentTimeMillis(); long startTime1 = System.currentTimeMillis();
if (methods.size() > 0) { boolean noNative = true;
boolean noNative = true; for (ExecutableElement method : methods) {
for (ExecutableElement method : methods) { Alternate alt_annotation = method.getAnnotation(Alternate.class);
Alternate alt_annotation = method.getAnnotation(Alternate.class); if ((alt_annotation == null || alt_annotation.nativeAlt()) && method.getAnnotation(Reuse.class) == null) {
if ((alt_annotation == null || alt_annotation.nativeAlt()) && method.getAnnotation(Reuse.class) == null) { noNative = false;
noNative = false; break;
break; }
} }
} if (!noNative) {
if (!noNative) { try {
try { generateNativeSource(e, startTime1);
generateNativeSource(e, startTime1); } catch (IOException ex) {
} catch (IOException ex) { throw new RuntimeException(ex);
throw new RuntimeException(ex);
}
} }
} }
});
cGenThread.start();
try { try {
javaGenThread.join(); javaGenThread.join();
cGenThread.join(); } catch (Throwable ex) {
} catch (Throwable ex) { throw new RuntimeException(ex);
throw new RuntimeException(ex); }
} else {
doJavaGen(e);
} }
return DEFAULT_VALUE; return DEFAULT_VALUE;
} }
public static void saveGeneratedJavaSource(ProcessingEnvironment env, Path gen_java_path, TypeElement e, String content, long startTime) { public static void saveGeneratedJavaSource(Messager messager, Path gen_java_path, TypeElement e, String content, long startTime) {
String qualified_interface_name = Utils.getQualifiedClassName(e); String qualified_interface_name = Utils.getQualifiedClassName(e);
saveGeneratedJavaSource(env, gen_java_path, qualified_interface_name, content, startTime); saveGeneratedJavaSource(messager, gen_java_path, qualified_interface_name, content, startTime);
} }
public static void saveGeneratedJavaSource(ProcessingEnvironment env, Path gen_java_path, String qualified_interface_name, String content, long startTime) { public static void saveGeneratedJavaSource(Messager messager, Path gen_java_path, String qualified_interface_name, String content, long startTime) {
final Path output = gen_java_path.resolve(qualified_interface_name.replace('.', '/') + ".java"); final Path output = gen_java_path.resolve(qualified_interface_name.replace('.', '/') + ".java");
saveGeneratedSource(env, "java", qualified_interface_name, output, content, startTime); saveGeneratedSource(messager, "java", qualified_interface_name, output, content, startTime);
} }
public static void saveGeneratedCSource(ProcessingEnvironment env, Path gen_native_path, TypeElement e, String content, long startTime) { public static void saveGeneratedCSource(Messager messager, Path gen_native_path, TypeElement e, String content, long startTime) {
String qualified_interface_name = Utils.getQualifiedClassName(e); String qualified_interface_name = Utils.getQualifiedClassName(e);
final Path output = gen_native_path.resolve(Utils.getNativeQualifiedName(qualified_interface_name) + ".c"); final Path output = gen_native_path.resolve(Utils.getNativeQualifiedName(qualified_interface_name) + ".c");
saveGeneratedSource(env, "c", qualified_interface_name, output, content, startTime); saveGeneratedSource(messager, "c", qualified_interface_name, output, content, startTime);
} }
public static void saveGeneratedSource(ProcessingEnvironment env, String type, String name, Path output, String newStr, long startTime) { public static void saveGeneratedSource(Messager messager, String type, String name, Path output, String newStr, long startTime) {
try { try {
if (isFileExistingAndIdentical(env, output, newStr)) { if (isFileExistingAndIdentical(messager, output, newStr)) {
long elapsed = System.currentTimeMillis() - startTime; long elapsed = System.currentTimeMillis() - startTime;
env.getMessager().printMessage(Diagnostic.Kind.NOTE, "Skipped identical '." + type + "' " + name + " at " + output + " in " + elapsed + " ms."); messager.printMessage(Diagnostic.Kind.NOTE, "Skipped identical '." + type + "' " + name + " at " + output + " in " + elapsed + " ms.");
return; return;
} }
Files.createDirectories(output.getParent()); Files.createDirectories(output.getParent());
@ -404,7 +411,6 @@ public class GeneratorVisitor extends ElementKindVisitor6<Void, Void> {
} catch (IOException ex) { } catch (IOException ex) {
throw new RuntimeException("Failed to create the output file for " + name, ex); throw new RuntimeException("Failed to create the output file for " + name, ex);
} }
//try (Writer java_file_writer = env.getFiler().createSourceFile(Utils.getQualifiedClassName(e), env.getElementUtils().getPackageOf(e)).openWriter()) {
try (Writer java_file_writer = new FileWriter(output.toFile())) { try (Writer java_file_writer = new FileWriter(output.toFile())) {
java_file_writer.write(newStr); java_file_writer.write(newStr);
java_file_writer.flush(); java_file_writer.flush();
@ -413,27 +419,9 @@ public class GeneratorVisitor extends ElementKindVisitor6<Void, Void> {
} }
long elapsed = System.currentTimeMillis() - startTime; long elapsed = System.currentTimeMillis() - startTime;
if (elapsed > 5) { if (elapsed > 5) {
env.getMessager().printMessage(Diagnostic.Kind.WARNING, "Generated '." + type + "' " + name + " at " + output + " in " + elapsed + " ms.\n\t**** SIGNIFICANT AMOUNT OF TIME"); messager.printMessage(Diagnostic.Kind.WARNING, "Generated '." + type + "' " + name + " at " + output + " in " + elapsed + " ms.\n\t**** SIGNIFICANT AMOUNT OF TIME");
} else { } else {
env.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generated '." + type + "' " + name + " at " + output + " in " + elapsed + " ms."); messager.printMessage(Diagnostic.Kind.NOTE, "Generated '." + type + "' " + name + " at " + output + " in " + elapsed + " ms.");
} }
} }
private static ByteBuffer readFile(final File file) throws IOException {
final FileChannel channel = new FileInputStream(file).getChannel();
final long bytesTotal = channel.size();
final ByteBuffer buffer = ByteBuffer.allocateDirect((int)bytesTotal);
long bytesRead = 0;
do {
bytesRead += channel.read(buffer);
} while ( bytesRead < bytesTotal );
buffer.flip();
channel.close();
return buffer;
}
} }

View File

@ -72,7 +72,7 @@ public class JavaMethodsGenerator {
* TODO : fix info multi-type methods print. * TODO : fix info multi-type methods print.
*/ */
private static void generateMethodJava(ProcessingEnvironment env, TypeMap type_map, PrintWriter writer, TypeElement interface_decl, ExecutableElement method, boolean generate_error_checks, boolean context_specific) { private static void generateMethodJava(ProcessingEnvironment env, TypeMap type_map, PrintWriter writer, TypeElement interface_decl, ExecutableElement method, boolean generate_error_checks, boolean context_specific) {
writer.println(); writer.append('\n');
if ( Utils.isMethodIndirect(generate_error_checks, context_specific, method) ) { if ( Utils.isMethodIndirect(generate_error_checks, context_specific, method) ) {
if ( method.getAnnotation(GenerateAutos.class) != null ) { if ( method.getAnnotation(GenerateAutos.class) != null ) {
printMethodWithMultiType(env, type_map, writer, interface_decl, method, TypeInfo.getDefaultTypeInfoMap(method), Mode.AUTOS, generate_error_checks, context_specific); printMethodWithMultiType(env, type_map, writer, interface_decl, method, TypeInfo.getDefaultTypeInfoMap(method), Mode.AUTOS, generate_error_checks, context_specific);
@ -108,25 +108,25 @@ public class JavaMethodsGenerator {
private static void printJavaNativeStub(ProcessingEnvironment env, PrintWriter writer, ExecutableElement method, Mode mode, boolean generate_error_checks, boolean context_specific) { private static void printJavaNativeStub(ProcessingEnvironment env, PrintWriter writer, ExecutableElement method, Mode mode, boolean generate_error_checks, boolean context_specific) {
if ( Utils.isMethodIndirect(generate_error_checks, context_specific, method) ) { if ( Utils.isMethodIndirect(generate_error_checks, context_specific, method) ) {
writer.print("\tstatic native "); writer.append("\tstatic native ");
} else { } else {
Utils.printDocComment(writer, method, env); Utils.printDocComment(writer, method, env);
writer.print("\tpublic static native "); writer.append("\tpublic static native ");
} }
writer.print(getResultType(method, true)); writer.append(getResultType(method, true));
writer.print(" " + Utils.getSimpleNativeMethodName(method, generate_error_checks, context_specific)); writer.append(' ').append(Utils.getSimpleNativeMethodName(method, generate_error_checks, context_specific));
if ( mode == Mode.BUFFEROBJECT ) { if ( mode == Mode.BUFFEROBJECT ) {
writer.print(Utils.BUFFER_OBJECT_METHOD_POSTFIX); writer.append(Utils.BUFFER_OBJECT_METHOD_POSTFIX);
} }
writer.print("("); writer.append('(');
boolean first_parameter = generateParametersJava(writer, method, TypeInfo.getDefaultTypeInfoMap(method), true, true, mode); boolean first_parameter = generateParametersJava(writer, method, TypeInfo.getDefaultTypeInfoMap(method), true, true, mode);
if ( context_specific ) { if ( context_specific ) {
if ( !first_parameter ) { if ( !first_parameter ) {
writer.print(", "); writer.append(", ");
} }
writer.print("long " + Utils.FUNCTION_POINTER_VAR_NAME); writer.append("long ").append(Utils.FUNCTION_POINTER_VAR_NAME);
} }
writer.println(");"); writer.append(");\n");
} }
private static boolean generateParametersJava(PrintWriter writer, ExecutableElement method, Map<VariableElement, TypeInfo> typeinfos_instance, boolean native_stub, final boolean printTypes, Mode mode) { private static boolean generateParametersJava(PrintWriter writer, ExecutableElement method, Map<VariableElement, TypeInfo> typeinfos_instance, boolean native_stub, final boolean printTypes, Mode mode) {
@ -148,13 +148,13 @@ public class JavaMethodsGenerator {
TypeInfo auto_param_type_info = typeinfos_instance.get(auto_parameter); TypeInfo auto_param_type_info = typeinfos_instance.get(auto_parameter);
if ( auto_param_type_info.getSignedness() == Signedness.BOTH ) { if ( auto_param_type_info.getSignedness() == Signedness.BOTH ) {
if ( !first_parameter ) { if ( !first_parameter ) {
writer.print(", "); writer.append(", ");
} }
first_parameter = false; first_parameter = false;
if ( printTypes ) { if ( printTypes ) {
writer.print("boolean "); writer.append("boolean ");
} }
writer.print(TypeInfo.UNSIGNED_PARAMETER_NAME); writer.append(TypeInfo.UNSIGNED_PARAMETER_NAME);
} }
} }
} else if ( param.getAnnotation(Result.class) == null } else if ( param.getAnnotation(Result.class) == null
@ -170,33 +170,33 @@ public class JavaMethodsGenerator {
if ( auto_size_annotation == null || !auto_size_annotation.isNative() ) { if ( auto_size_annotation == null || !auto_size_annotation.isNative() ) {
if ( cached_result_annotation == null || !cached_result_annotation.isRange() ) { if ( cached_result_annotation == null || !cached_result_annotation.isRange() ) {
if ( !first_parameter ) { if ( !first_parameter ) {
writer.print(", "); writer.append(", ");
} }
first_parameter = false; first_parameter = false;
if ( printTypes ) { if ( printTypes ) {
writer.print("long "); writer.append("long ");
} }
writer.print(Utils.RESULT_SIZE_NAME); writer.append(Utils.RESULT_SIZE_NAME);
} }
} }
} }
if ( cached_result_annotation != null ) { if ( cached_result_annotation != null ) {
if ( !first_parameter ) { if ( !first_parameter ) {
writer.print(", "); writer.append(", ");
} }
if ( mode == Mode.CACHEDRESULT ) { if ( mode == Mode.CACHEDRESULT ) {
if ( printTypes ) { if ( printTypes ) {
writer.print("long "); writer.append("long ");
} }
writer.print(Utils.CACHED_BUFFER_LENGTH_NAME + ", "); writer.append(Utils.CACHED_BUFFER_LENGTH_NAME).append(", ");
} }
first_parameter = false; first_parameter = false;
if ( printTypes ) { if ( printTypes ) {
writer.print(getResultType(method, native_stub)); writer.append(getResultType(method, native_stub));
} }
writer.print(" " + Utils.CACHED_BUFFER_NAME); writer.append(' ').append(Utils.CACHED_BUFFER_NAME);
} }
return first_parameter; return first_parameter;
} }
@ -204,7 +204,7 @@ public class JavaMethodsGenerator {
private static boolean generateParameterJava(PrintWriter writer, VariableElement param, TypeInfo type_info, boolean native_stub, final boolean printTypes, boolean first_parameter, Mode mode) { private static boolean generateParameterJava(PrintWriter writer, VariableElement param, TypeInfo type_info, boolean native_stub, final boolean printTypes, boolean first_parameter, Mode mode) {
Class buffer_type = Utils.getNIOBufferType(param.asType()); Class buffer_type = Utils.getNIOBufferType(param.asType());
if ( !first_parameter ) { if ( !first_parameter ) {
writer.print(", "); writer.append(", ");
} }
BufferObject bo_annotation = param.getAnnotation(BufferObject.class); BufferObject bo_annotation = param.getAnnotation(BufferObject.class);
if ( bo_annotation != null && mode == Mode.BUFFEROBJECT ) { if ( bo_annotation != null && mode == Mode.BUFFEROBJECT ) {
@ -212,43 +212,35 @@ public class JavaMethodsGenerator {
throw new RuntimeException("type of " + param + " is not a nio Buffer parameter but is annotated as buffer object"); throw new RuntimeException("type of " + param + " is not a nio Buffer parameter but is annotated as buffer object");
} }
if ( printTypes ) { if ( printTypes ) {
writer.print("long "); writer.append("long ");
} }
writer.print(param.getSimpleName() + Utils.BUFFER_OBJECT_PARAMETER_POSTFIX); writer.append(param.getSimpleName()).append(Utils.BUFFER_OBJECT_PARAMETER_POSTFIX);
} else { } else {
if ( native_stub && param.getAnnotation(PointerWrapper.class) != null ) { if ( native_stub && param.getAnnotation(PointerWrapper.class) != null ) {
writer.print("long "); writer.append("long ");
} else { } else {
Class type = type_info.getType(); Class type = type_info.getType();
if ( native_stub && (type == CharSequence.class || type == CharSequence[].class || type == PointerBuffer.class || Buffer.class.isAssignableFrom(type)) ) { if ( native_stub && (type == CharSequence.class || type == CharSequence[].class || type == PointerBuffer.class || Buffer.class.isAssignableFrom(type)) ) {
writer.print("long "); writer.append("long ");
} else if ( printTypes ) { } else if ( printTypes ) {
writer.print(type.getSimpleName() + " "); writer.append(type.getSimpleName()).append(' ');
} }
} }
AutoSize auto_size_annotation = param.getAnnotation(AutoSize.class); AutoSize auto_size_annotation = param.getAnnotation(AutoSize.class);
if ( auto_size_annotation != null ) { if ( auto_size_annotation != null ) {
writer.print(auto_size_annotation.value() + "_"); writer.append(auto_size_annotation.value()).append('_');
} }
writer.print(param.getSimpleName()); writer.append(param.getSimpleName());
} }
return false; return false;
} }
private static void printBufferObjectCheck(PrintWriter writer, BufferKind kind, Mode mode, boolean context_specific) { private static void printBufferObjectCheck(PrintWriter writer, BufferKind kind, Mode mode, boolean context_specific) {
String bo_check_method_name = kind.toString(); String bo_check_method_name = kind.toString();
writer.print("\t\t" + Utils.CHECKS_CLASS_NAME + ".ensure" + bo_check_method_name); writer.append("\t\t" + Utils.CHECKS_CLASS_NAME + ".ensure").append(bo_check_method_name);
if ( mode == Mode.BUFFEROBJECT ) { writer.append(mode == Mode.BUFFEROBJECT ? "enabled" : "disabled");
writer.print("enabled");
} else {
writer.print("disabled");
}
if ( context_specific ) { writer.append(context_specific ? "(caps);\n" : "();\n");
writer.println("(caps);");
} else {
writer.println("();");
}
} }
private static void printBufferObjectChecks(PrintWriter writer, ExecutableElement method, Mode mode, boolean context_specific) { private static void printBufferObjectChecks(PrintWriter writer, ExecutableElement method, Mode mode, boolean context_specific) {
@ -267,14 +259,14 @@ public class JavaMethodsGenerator {
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) { 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); Utils.printDocComment(writer, method, env);
if ( method.getAnnotation(Deprecated.class) != null ) { if ( method.getAnnotation(Deprecated.class) != null ) {
writer.println("\t@Deprecated"); writer.append("\t@Deprecated\n");
} }
if ( interface_decl.getAnnotation(Private.class) == null && method.getAnnotation(Private.class) == null ) { if ( interface_decl.getAnnotation(Private.class) == null && method.getAnnotation(Private.class) == null ) {
writer.print("\tpublic static "); writer.append("\tpublic static ");
} else { } else {
writer.print("\tstatic "); writer.append("\tstatic ");
} }
writer.print(getResultType(method, false)); writer.append(getResultType(method, false));
StripPostfix strip_annotation = method.getAnnotation(StripPostfix.class); StripPostfix strip_annotation = method.getAnnotation(StripPostfix.class);
String method_name; String method_name;
Alternate alt_annotation = method.getAnnotation(Alternate.class); Alternate alt_annotation = method.getAnnotation(Alternate.class);
@ -282,104 +274,101 @@ public class JavaMethodsGenerator {
if ( strip_annotation != null && mode == Mode.NORMAL ) { if ( strip_annotation != null && mode == Mode.NORMAL ) {
method_name = getPostfixStrippedName(type_map, interface_decl, method); method_name = getPostfixStrippedName(type_map, interface_decl, method);
} }
writer.print(" " + method_name + "("); writer.append(' ').append(method_name).append('(');
generateParametersJava(writer, method, typeinfos_instance, false, true, mode); generateParametersJava(writer, method, typeinfos_instance, false, true, mode);
writer.println(") {"); writer.append(") {\n");
final TypeMirror result_type = Utils.getMethodReturnType(method); final TypeMirror result_type = Utils.getMethodReturnType(method);
boolean has_result = !result_type.equals(env.getTypeUtils().getNoType(TypeKind.VOID)); boolean has_result = !result_type.equals(env.getTypeUtils().getNoType(TypeKind.VOID));
final Reuse reuse_annotation = method.getAnnotation(Reuse.class); final Reuse reuse_annotation = method.getAnnotation(Reuse.class);
if ( reuse_annotation != null ) { if ( reuse_annotation != null ) {
writer.print("\t\t"); writer.append("\t\t");
if ( has_result || method.getAnnotation(GLreturn.class) != null ) { if ( has_result || method.getAnnotation(GLreturn.class) != null ) {
writer.print("return "); writer.append("return ");
} }
writer.print(reuse_annotation.value() + "." + (reuse_annotation.method().length() > 0 ? reuse_annotation.method() : method_name) + "("); writer.append(reuse_annotation.value() + "." + (reuse_annotation.method().length() > 0 ? reuse_annotation.method() : method_name) + "(");
generateParametersJava(writer, method, typeinfos_instance, false, false, mode); generateParametersJava(writer, method, typeinfos_instance, false, false, mode);
writer.println(");\n\t}"); writer.append(");\n\t}\n");
return; return;
} }
if ( context_specific ) { if ( context_specific ) {
type_map.printCapabilitiesInit(writer); type_map.printCapabilitiesInit(writer);
writer.print("\t\tlong " + Utils.FUNCTION_POINTER_VAR_NAME + " = " + type_map.getCapabilities() + "."); writer.append("\t\tlong " + Utils.FUNCTION_POINTER_VAR_NAME + " = ").append(type_map.getCapabilities()).append('.');
writer.println(Utils.getFunctionAddressName(interface_decl, method, true) + ";"); writer.append(Utils.getFunctionAddressName(interface_decl, method, true)).append(";\n");
writer.print("\t\tBufferChecks.checkFunctionAddress("); writer.append("\t\tBufferChecks.checkFunctionAddress(");
writer.println(Utils.FUNCTION_POINTER_VAR_NAME + ");"); writer.append(Utils.FUNCTION_POINTER_VAR_NAME + ");\n");
} }
final Code code_annotation = method.getAnnotation(Code.class); final Code code_annotation = method.getAnnotation(Code.class);
if ( code_annotation != null && code_annotation.value().length() > 0 ) { if ( code_annotation != null && code_annotation.value().length() > 0 ) {
writer.println(code_annotation.value()); writer.append(code_annotation.value()).append('\n');
} }
printBufferObjectChecks(writer, method, mode, context_specific); printBufferObjectChecks(writer, method, mode, context_specific);
printParameterChecks(writer, method, typeinfos_instance, mode, generate_error_checks); printParameterChecks(writer, method, typeinfos_instance, mode, generate_error_checks);
printParameterCaching(writer, interface_decl, method, mode, context_specific); printParameterCaching(writer, interface_decl, method, mode, context_specific);
if ( code_annotation != null && code_annotation.javaBeforeNative().length() > 0 ) { if ( code_annotation != null && code_annotation.javaBeforeNative().length() > 0 ) {
writer.println(code_annotation.javaBeforeNative()); writer.append(code_annotation.javaBeforeNative()).append('\n');
} }
writer.print("\t\t"); writer.append("\t\t");
final PointerWrapper pointer_wrapper_annotation = method.getAnnotation(PointerWrapper.class); final PointerWrapper pointer_wrapper_annotation = method.getAnnotation(PointerWrapper.class);
if ( has_result ) { if ( has_result ) {
writer.print(getResultType(method, false) + " " + Utils.RESULT_VAR_NAME); writer.append(getResultType(method, false)).append(" " + Utils.RESULT_VAR_NAME);
if ( code_annotation != null && code_annotation.tryBlock() ) { if ( code_annotation != null && code_annotation.tryBlock() ) {
writer.print(" = " + getDefaultResultValue(method)); writer.append(" = ").append(getDefaultResultValue(method));
writer.println(";\n\t\ttry {"); writer.append(";\n\t\ttry {\n");
writer.print("\t\t\t" + Utils.RESULT_VAR_NAME); writer.append("\t\t\t" + Utils.RESULT_VAR_NAME);
} }
writer.print(" = "); writer.append(" = ");
if ( pointer_wrapper_annotation != null ) { if ( pointer_wrapper_annotation != null ) {
if ( pointer_wrapper_annotation.factory().length() > 0 ) { if ( pointer_wrapper_annotation.factory().length() > 0 ) {
writer.print(pointer_wrapper_annotation.factory() + "("); writer.append(pointer_wrapper_annotation.factory()).append('(');
} else { } else {
writer.print("new " + getResultType(method, false) + "("); writer.append("new ").append(getResultType(method, false)).append('(');
} }
} }
} else if ( method.getAnnotation(GLreturn.class) != null ) { } else if ( method.getAnnotation(GLreturn.class) != null ) {
has_result = true; has_result = true;
Utils.printGLReturnPre(writer, method, method.getAnnotation(GLreturn.class), type_map); Utils.printGLReturnPre(writer, method, method.getAnnotation(GLreturn.class), type_map);
} }
writer.print(Utils.getSimpleNativeMethodName(method, generate_error_checks, context_specific)); writer.append(Utils.getSimpleNativeMethodName(method, generate_error_checks, context_specific));
if ( mode == Mode.BUFFEROBJECT ) { if ( mode == Mode.BUFFEROBJECT ) {
writer.print(Utils.BUFFER_OBJECT_METHOD_POSTFIX); writer.append(Utils.BUFFER_OBJECT_METHOD_POSTFIX);
} }
writer.print("("); writer.append('(');
boolean first_parameter = printMethodCallArguments(writer, method, typeinfos_instance, mode, type_map); boolean first_parameter = printMethodCallArguments(writer, method, typeinfos_instance, mode, type_map);
if ( context_specific ) { if ( context_specific ) {
if ( !first_parameter ) { if ( !first_parameter ) {
writer.print(", "); writer.append(", ");
} }
writer.print(Utils.FUNCTION_POINTER_VAR_NAME); writer.append(Utils.FUNCTION_POINTER_VAR_NAME);
} }
if ( has_result && pointer_wrapper_annotation != null ) { if ( has_result && pointer_wrapper_annotation != null ) {
writer.print(")"); writer.append(')');
if ( pointer_wrapper_annotation.params().length() > 0 ) { if ( pointer_wrapper_annotation.params().length() > 0 ) {
writer.print(", " + pointer_wrapper_annotation.params()); writer.append(", ").append(pointer_wrapper_annotation.params());
} }
} }
writer.println(");"); writer.append(");\n");
if ( code_annotation != null && code_annotation.javaAfterNative().length() > 0 ) { if ( code_annotation != null && code_annotation.javaAfterNative().length() > 0 ) {
writer.println(code_annotation.javaAfterNative()); writer.append(code_annotation.javaAfterNative()).append('\n');
} }
final String tabs = code_annotation != null && code_annotation.tryBlock() ? "\t\t\t" : "\t\t"; 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 // DISABLED: indirect buffer support
//printNondirectParameterCopies(writer, method, mode); //printNondirectParameterCopies(writer, method, mode);
if ( has_result ) { if ( has_result ) {
if ( method.getAnnotation(GLreturn.class) == null ) { if ( method.getAnnotation(GLreturn.class) == null ) {
if ( ByteBuffer.class.equals(Utils.getJavaType(result_type)) ) { 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. writer.append(tabs).append("return LWJGLUtil.CHECKS && " + Utils.RESULT_VAR_NAME + " == null ? null : " + Utils.RESULT_VAR_NAME + ".order(ByteOrder.nativeOrder());\n"); // safeNewBuffer returns a direct ByteBuffer with BIG_ENDIAN order.
} else { } else {
writer.println(tabs + "return " + Utils.RESULT_VAR_NAME + ";"); writer.append(tabs).append("return " + Utils.RESULT_VAR_NAME + ";\n");
} }
} else { } else {
Utils.printGLReturnPost(writer, method, method.getAnnotation(GLreturn.class), type_map); Utils.printGLReturnPost(writer, method, method.getAnnotation(GLreturn.class), type_map);
@ -387,11 +376,11 @@ public class JavaMethodsGenerator {
} }
if ( code_annotation != null && code_annotation.tryBlock() ) { if ( code_annotation != null && code_annotation.tryBlock() ) {
writer.println("\t\t} finally {"); writer.append("\t\t} finally {\n");
writer.println(code_annotation.javaFinally()); writer.append(code_annotation.javaFinally()).append('\n');
writer.println("\t\t}"); writer.append("\t\t}\n");
} }
writer.println("\t}"); writer.append("\t}\n");
} }
private static String getExtensionPostfix(TypeElement interface_decl) { private static String getExtensionPostfix(TypeElement interface_decl) {
@ -505,13 +494,13 @@ public class JavaMethodsGenerator {
private static boolean printMethodCallArgument(PrintWriter writer, ExecutableElement method, VariableElement param, Map<VariableElement, TypeInfo> typeinfos_instance, Mode mode, boolean first_parameter, TypeMap type_map) { 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 ) { if ( !first_parameter ) {
writer.print(", "); writer.append(", ");
} }
AnnotationMirror auto_annotation = Utils.getParameterAutoAnnotation(param); AnnotationMirror auto_annotation = Utils.getParameterAutoAnnotation(param);
Constant constant_annotation = param.getAnnotation(Constant.class); Constant constant_annotation = param.getAnnotation(Constant.class);
if ( constant_annotation != null ) { if ( constant_annotation != null ) {
writer.print(constant_annotation.value()); writer.append(constant_annotation.value());
} else if ( auto_annotation != null && mode == Mode.NORMAL ) { } else if ( auto_annotation != null && mode == Mode.NORMAL ) {
Class param_type = NativeTypeTranslator.getClassFromType(auto_annotation.getAnnotationType()); Class param_type = NativeTypeTranslator.getClassFromType(auto_annotation.getAnnotationType());
if ( AutoType.class.equals(param_type) ) { if ( AutoType.class.equals(param_type) ) {
@ -521,7 +510,7 @@ public class JavaMethodsGenerator {
if ( auto_type == null ) { if ( auto_type == null ) {
throw new RuntimeException("No auto type for parameter " + param.getSimpleName() + " in method " + method); throw new RuntimeException("No auto type for parameter " + param.getSimpleName() + " in method " + method);
} }
writer.print(auto_type); writer.append(auto_type);
} else if ( AutoSize.class.equals(param_type) ) { } else if ( AutoSize.class.equals(param_type) ) {
final AutoSize auto_size_annotation = param.getAnnotation(AutoSize.class); final AutoSize auto_size_annotation = param.getAnnotation(AutoSize.class);
if ( !auto_size_annotation.useExpression() ) { if ( !auto_size_annotation.useExpression() ) {
@ -533,65 +522,65 @@ public class JavaMethodsGenerator {
if ( shift_remaining ) { if ( shift_remaining ) {
shifting = getBufferElementSizeExponent(auto_target_type_info.getType()); shifting = getBufferElementSizeExponent(auto_target_type_info.getType());
if ( shifting > 0 ) { if ( shifting > 0 ) {
writer.print("("); writer.append('(');
} }
} }
if ( auto_size_annotation.canBeNull() ) { if ( auto_size_annotation.canBeNull() ) {
writer.print("(" + auto_parameter_name + " == null ? 0 : " + auto_parameter_name + ".remaining())"); writer.append('(').append(auto_parameter_name).append(" == null ? 0 : ").append(auto_parameter_name).append(".remaining())");
} else { } else {
writer.print(auto_parameter_name + ".remaining()"); writer.append(auto_parameter_name).append(".remaining()");
} }
// Shift the remaining if the target parameter is multityped and there's no AutoType to track type // Shift the remaining if the target parameter is multityped and there's no AutoType to track type
if ( shift_remaining && shifting > 0 ) { if ( shifting > 0 ) {
writer.print(" << " + shifting); writer.append(" << ").append(String.valueOf(shifting));
writer.print(")"); writer.append(')');
} }
} }
writer.print(auto_size_annotation.expression()); writer.append(auto_size_annotation.expression());
} else { } else {
throw new RuntimeException("Unknown auto annotation " + param_type); throw new RuntimeException("Unknown auto annotation " + param_type);
} }
} else { } else {
if ( mode == Mode.BUFFEROBJECT && param.getAnnotation(BufferObject.class) != null ) { if ( mode == Mode.BUFFEROBJECT && param.getAnnotation(BufferObject.class) != null ) {
writer.print(param.getSimpleName() + Utils.BUFFER_OBJECT_PARAMETER_POSTFIX); writer.append(param.getSimpleName()).append(Utils.BUFFER_OBJECT_PARAMETER_POSTFIX);
} else { } else {
Class type = typeinfos_instance.get(param).getType(); Class type = typeinfos_instance.get(param).getType();
Check check_annotation = param.getAnnotation(Check.class); Check check_annotation = param.getAnnotation(Check.class);
boolean hide_buffer = mode == Mode.AUTOS && getAutoTypeParameter(method, param) != null; boolean hide_buffer = mode == Mode.AUTOS && getAutoTypeParameter(method, param) != null;
if ( hide_buffer ) { if ( hide_buffer ) {
writer.print("0L"); writer.append("0L");
} else { } else {
if ( type == CharSequence.class || type == CharSequence[].class ) { if ( type == CharSequence.class || type == CharSequence[].class ) {
final String offset = Utils.getStringOffset(method, param); final String offset = Utils.getStringOffset(method, param);
writer.print("APIUtil.getBuffer"); writer.append("APIUtil.getBuffer");
if ( param.getAnnotation(NullTerminated.class) != null ) { if ( param.getAnnotation(NullTerminated.class) != null ) {
writer.print("NT"); writer.append("NT");
} }
writer.print('('); writer.append('(');
writer.print(type_map.getAPIUtilParam(true)); writer.append(type_map.getAPIUtilParam(true));
writer.print(param.getSimpleName()); writer.append(param.getSimpleName());
if ( offset != null ) { if ( offset != null ) {
writer.print(", " + offset); writer.append(", ").append(offset);
} }
writer.print(")"); writer.append(')');
} else { } else {
final AutoSize auto_size_annotation = param.getAnnotation(AutoSize.class); final AutoSize auto_size_annotation = param.getAnnotation(AutoSize.class);
if ( auto_size_annotation != null ) { if ( auto_size_annotation != null ) {
writer.print(auto_size_annotation.value() + "_"); writer.append(auto_size_annotation.value()).append('_');
} }
final Class buffer_type = Utils.getNIOBufferType(param.asType()); final Class buffer_type = Utils.getNIOBufferType(param.asType());
if ( buffer_type == null ) { if ( buffer_type == null ) {
writer.print(param.getSimpleName()); writer.append(param.getSimpleName());
} else { } else {
writer.print("MemoryUtil.getAddress"); writer.append("MemoryUtil.getAddress");
if ( check_annotation != null && check_annotation.canBeNull() ) { if ( check_annotation != null && check_annotation.canBeNull() ) {
writer.print("Safe"); writer.append("Safe");
} }
writer.print("("); writer.append('(');
writer.print(param.getSimpleName()); writer.append(param.getSimpleName());
writer.print(")"); writer.append(')');
} }
} }
} }
@ -599,9 +588,9 @@ public class JavaMethodsGenerator {
PointerWrapper pointer_annotation = param.getAnnotation(PointerWrapper.class); PointerWrapper pointer_annotation = param.getAnnotation(PointerWrapper.class);
if ( pointer_annotation != null ) { if ( pointer_annotation != null ) {
if ( pointer_annotation.canBeNull() ) { if ( pointer_annotation.canBeNull() ) {
writer.print(" == null ? 0 : " + param.getSimpleName()); writer.append(" == null ? 0 : ").append(param.getSimpleName());
} }
writer.print(".getPointer()"); writer.append(".getPointer()");
} }
} }
} }
@ -629,7 +618,7 @@ public class JavaMethodsGenerator {
AutoSize auto_size_annotation = method.getAnnotation(AutoSize.class); AutoSize auto_size_annotation = method.getAnnotation(AutoSize.class);
if ( auto_size_annotation == null || !auto_size_annotation.isNative() ) { if ( auto_size_annotation == null || !auto_size_annotation.isNative() ) {
if ( !first_parameter ) { if ( !first_parameter ) {
writer.print(", "); writer.append(", ");
} }
first_parameter = false; first_parameter = false;
@ -657,21 +646,21 @@ public class JavaMethodsGenerator {
&& cachedReference != null && cachedReference != null
&& (mode != Mode.BUFFEROBJECT || param.getAnnotation(BufferObject.class) == null) && (mode != Mode.BUFFEROBJECT || param.getAnnotation(BufferObject.class) == null)
&& param.getAnnotation(Result.class) == null ) { && param.getAnnotation(Result.class) == null ) {
writer.print("\t\tif ( LWJGLUtil.CHECKS ) StateTracker."); writer.append("\t\tif ( LWJGLUtil.CHECKS ) StateTracker.");
if ( context_specific ) { if ( context_specific ) {
writer.print("getReferences(caps)."); writer.append("getReferences(caps).");
} else { } else {
writer.print("getTracker()."); writer.append("getTracker().");
} }
if ( cachedReference.name().length() > 0 ) { if ( cachedReference.name().length() > 0 ) {
writer.print(cachedReference.name()); writer.append(cachedReference.name());
} else { } else {
writer.print(Utils.getReferenceName(interface_decl, method, param)); writer.append(Utils.getReferenceName(interface_decl, method, param));
} }
if ( cachedReference.index().length() > 0 ) { if ( cachedReference.index().length() > 0 ) {
writer.print("[" + cachedReference.index() + "]"); writer.append('[').append(cachedReference.index()).append(']');
} }
writer.println(" = " + param.getSimpleName() + ";"); writer.append(" = ").append(param.getSimpleName()).append(";\n");
} }
} }
} }
@ -686,12 +675,11 @@ public class JavaMethodsGenerator {
final int shifting = getBufferElementSizeExponent(typeinfos.get(param).getType()); final int shifting = getBufferElementSizeExponent(typeinfos.get(param).getType());
final Check check_annotation = param.getAnnotation(Check.class); final Check check_annotation = param.getAnnotation(Check.class);
writer.print("\t\tlong " + param.getSimpleName() + "_size = "); writer.append("\t\tlong ").append(param.getSimpleName()).append("_size = ");
if ( check_annotation == null || !check_annotation.canBeNull() ) { if ( check_annotation != null && check_annotation.canBeNull() ) {
writer.println(param.getSimpleName() + ".remaining() << " + shifting + ";"); writer.append(param.getSimpleName()).append(" == null ? 0 : ");
} else {
writer.println(param.getSimpleName() + " == null ? 0 : " + param.getSimpleName() + ".remaining() << " + shifting + ";");
} }
writer.append(param.getSimpleName()).append(".remaining() << ").append(String.valueOf(shifting)).append(";\n");
} }
} }
} }
@ -716,7 +704,7 @@ public class JavaMethodsGenerator {
printParameterCheck(writer, method, param.getSimpleName().toString(), typeinfo.getType().getSimpleName(), check_value, can_be_null, param.getAnnotation(NullTerminated.class), generate_error_checks); 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) ) { } else if ( String.class.equals(java_type) ) {
if ( !can_be_null ) { if ( !can_be_null ) {
writer.println("\t\tBufferChecks.checkNotNull(" + param.getSimpleName() + ");"); writer.append("\t\tBufferChecks.checkNotNull(").append(param.getSimpleName()).append(");\n");
} }
} else if ( java_type.isArray() ) { } else if ( java_type.isArray() ) {
printArrayParameterCheck(writer, param.getSimpleName().toString(), check_value, can_be_null); printArrayParameterCheck(writer, param.getSimpleName().toString(), check_value, can_be_null);
@ -731,44 +719,43 @@ public class JavaMethodsGenerator {
private static void printParameterCheck(PrintWriter writer, ExecutableElement method, String name, String type, String check_value, boolean can_be_null, NullTerminated null_terminated, boolean generate_error_checks) { private static void printParameterCheck(PrintWriter writer, ExecutableElement method, String name, String type, String check_value, boolean can_be_null, NullTerminated null_terminated, boolean generate_error_checks) {
String tabs; String tabs;
if ( can_be_null ) { if ( can_be_null ) {
writer.print("\t\tif (" + name + " != null)"); writer.append("\t\tif (").append(name).append(" != null)");
if ( null_terminated != null ) { if ( null_terminated != null ) {
writer.println(" {"); writer.append(" {\n");
} else { } else {
writer.println(); writer.append('\n');
} }
tabs = "\t\t\t"; tabs = "\t\t\t";
} else { } else {
tabs = "\t\t"; tabs = "\t\t";
} }
writer.print(tabs + "BufferChecks.check"); writer.append(tabs).append("BufferChecks.check");
if ( check_value != null && check_value.length() > 0 ) { if ( check_value != null && check_value.length() > 0 ) {
writer.print("Buffer"); writer.append("Buffer");
if ( "Buffer".equals(type) ) { if ( "Buffer".equals(type) ) {
writer.print("Size"); // Check size only, Buffer.isDirect() was added in 1.6, cannot use yet. TODO: Remove? writer.append("Size"); // Check size only, Buffer.isDirect() was added in 1.6, cannot use yet. TODO: Remove?
} }
writer.print("(" + name + ", " + check_value); writer.append('(').append(name).append(", ").append(check_value);
} else { } else {
writer.print("Direct(" + name); writer.append("Direct(").append(name);
} }
writer.println(");"); writer.append(");\n");
if ( can_be_null && generate_error_checks ) { if ( can_be_null && generate_error_checks ) {
final Check check_annotation = method.getAnnotation(Check.class); final Check check_annotation = method.getAnnotation(Check.class);
if ( check_annotation != null && check_annotation.value().equals(name) ) { if ( check_annotation != null && check_annotation.value().equals(name) ) {
writer.println("\t\telse"); writer.append("\t\telse\n");
writer.println("\t\t\t" + name + " = APIUtil.getBufferIntDebug();"); // Use an exclusive buffer here writer.append("\t\t\t").append(name).append(" = APIUtil.getBufferIntDebug();\n"); // Use an exclusive buffer here
} }
} }
if ( null_terminated != null ) { if ( null_terminated != null ) {
writer.print(tabs + "BufferChecks.checkNullTerminated("); writer.append(tabs).append("BufferChecks.checkNullTerminated(");
writer.print(name); writer.append(name);
if ( null_terminated.value().length() > 0 ) { if ( null_terminated.value().length() > 0 ) {
writer.print(", "); writer.append(", ").append(null_terminated.value());
writer.print(null_terminated.value());
} }
writer.println(");"); writer.append(");\n");
if ( can_be_null ) { if ( can_be_null ) {
writer.println("\t\t}"); writer.append("\t\t}\n");
} }
} }
} }
@ -776,17 +763,17 @@ public class JavaMethodsGenerator {
private static void printArrayParameterCheck(PrintWriter writer, String name, String check_value, boolean can_be_null) { private static void printArrayParameterCheck(PrintWriter writer, String name, String check_value, boolean can_be_null) {
String tabs; String tabs;
if ( can_be_null ) { if ( can_be_null ) {
writer.println("\t\tif (" + name + " != null)"); writer.append("\t\tif (").append(name).append(" != null)\n");
tabs = "\t\t\t"; tabs = "\t\t\t";
} else { } else {
tabs = "\t\t"; tabs = "\t\t";
} }
writer.print(tabs + "BufferChecks.checkArray(" + name); writer.append(tabs).append("BufferChecks.checkArray(").append(name);
if ( check_value != null && check_value.length() > 0 ) { if ( check_value != null && check_value.length() > 0 ) {
writer.print(", " + check_value); writer.append(", ").append(check_value);
} }
writer.println(");"); writer.append(");\n");
} }
private static String getResultType(ExecutableElement method, boolean native_stub) { private static String getResultType(ExecutableElement method, boolean native_stub) {

View File

@ -84,13 +84,13 @@ public class NativeMethodStubsGenerator {
private static void generateParameter(PrintWriter writer, VariableElement param, Mode mode) { private static void generateParameter(PrintWriter writer, VariableElement param, Mode mode) {
writer.print(", "); writer.print(", ");
if ( mode == Mode.BUFFEROBJECT && param.getAnnotation(BufferObject.class) != null ) { if ( mode == Mode.BUFFEROBJECT && param.getAnnotation(BufferObject.class) != null ) {
writer.print("jlong " + param.getSimpleName() + Utils.BUFFER_OBJECT_PARAMETER_POSTFIX); writer.append("jlong ").append(param.getSimpleName()).append(Utils.BUFFER_OBJECT_PARAMETER_POSTFIX);
} else if ( param.getAnnotation(PointerWrapper.class) != null ) { } else if ( param.getAnnotation(PointerWrapper.class) != null ) {
writer.print("jlong " + param.getSimpleName()); writer.append("jlong ").append(param.getSimpleName());
} else { } else {
JNITypeTranslator translator = new JNITypeTranslator(); JNITypeTranslator translator = new JNITypeTranslator();
param.asType().accept(translator, null); param.asType().accept(translator, null);
writer.print(translator.getSignature() + " " + param.getSimpleName()); writer.append(translator.getSignature()).append(' ').append(param.getSimpleName());
} }
} }
@ -127,15 +127,15 @@ public class NativeMethodStubsGenerator {
if ( context_specific ) { if ( context_specific ) {
writer.print(", jlong " + Utils.FUNCTION_POINTER_VAR_NAME); writer.print(", jlong " + Utils.FUNCTION_POINTER_VAR_NAME);
} }
writer.println(") {"); writer.append(") {\n");
generateBufferParameterAddresses(type_map, writer, method, mode); generateBufferParameterAddresses(type_map, writer, method, mode);
Alternate alt_annotation = method.getAnnotation(Alternate.class); Alternate alt_annotation = method.getAnnotation(Alternate.class);
if ( context_specific ) { if ( context_specific ) {
String typedef_name = Utils.getTypedefName(method); String typedef_name = Utils.getTypedefName(method);
writer.print("\t" + typedef_name + " " + (alt_annotation == null ? method.getSimpleName() : alt_annotation.value())); writer.append('\t').append(typedef_name).append(' ').append(alt_annotation == null ? method.getSimpleName() : alt_annotation.value());
writer.print(" = (" + typedef_name + ")((intptr_t)"); writer.append(" = (").append(typedef_name).append(")((intptr_t)");
writer.println(Utils.FUNCTION_POINTER_VAR_NAME + ");"); writer.append(Utils.FUNCTION_POINTER_VAR_NAME + ");\n");
} }
final Code code_annotation = method.getAnnotation(Code.class); final Code code_annotation = method.getAnnotation(Code.class);
@ -146,29 +146,28 @@ public class NativeMethodStubsGenerator {
printResultParam(type_map, writer, method, result_type, true); printResultParam(type_map, writer, method, result_type, true);
if ( code_annotation != null && code_annotation.nativeAfterVars().length() > 0 ) if ( code_annotation != null && code_annotation.nativeAfterVars().length() > 0 )
writer.println(code_annotation.nativeAfterVars()); writer.append(code_annotation.nativeAfterVars()).append('\n');
generatePointerArrayInits(type_map, writer, method.getParameters()); generatePointerArrayInits(type_map, writer, method.getParameters());
if ( code_annotation != null && code_annotation.nativeBeforeCall().length() > 0 ) if ( code_annotation != null && code_annotation.nativeBeforeCall().length() > 0 )
writer.println(code_annotation.nativeBeforeCall()); writer.append(code_annotation.nativeBeforeCall()).append('\n');
writer.print("\t"); writer.print("\t");
if ( resultPreDeclare ) if ( resultPreDeclare )
writer.print(Utils.RESULT_VAR_NAME + " = "); writer.print(Utils.RESULT_VAR_NAME + " = ");
else if ( hasResult ) else if ( hasResult )
printResultParam(type_map, writer, method, result_type, false); printResultParam(type_map, writer, method, result_type, false);
writer.print((alt_annotation == null ? method.getSimpleName() : alt_annotation.value()) + "("); writer.append(alt_annotation == null ? method.getSimpleName() : alt_annotation.value()).append('(');
generateCallParameters(writer, type_map, method.getParameters()); generateCallParameters(writer, type_map, method.getParameters());
writer.print(")"); writer.append(");\n");
writer.println(";");
if ( code_annotation != null && code_annotation.nativeAfterCall().length() > 0 ) if ( code_annotation != null && code_annotation.nativeAfterCall().length() > 0 )
writer.println(code_annotation.nativeAfterCall()); writer.append(code_annotation.nativeAfterCall()).append('\n');
generateStringDeallocations(writer, method.getParameters()); generateStringDeallocations(writer, method.getParameters());
if ( !result_type.equals(env.getTypeUtils().getNoType(TypeKind.VOID)) ) { if ( !result_type.equals(env.getTypeUtils().getNoType(TypeKind.VOID)) ) {
writer.print("\treturn "); writer.append("\treturn ");
Class java_result_type = Utils.getJavaType(result_type); Class java_result_type = Utils.getJavaType(result_type);
if ( Buffer.class.isAssignableFrom(java_result_type) ) { if ( Buffer.class.isAssignableFrom(java_result_type) ) {
if ( cached_result_annotation != null ) if ( cached_result_annotation != null )
@ -194,10 +193,9 @@ public class NativeMethodStubsGenerator {
if ( Buffer.class.isAssignableFrom(java_result_type) || if ( Buffer.class.isAssignableFrom(java_result_type) ||
String.class.equals(java_result_type) ) String.class.equals(java_result_type) )
writer.print(")"); writer.print(")");
writer.println(";"); writer.append(";\n");
} }
writer.println("}"); writer.append("}\n");
writer.println();
} }
private static void printResultParam(final TypeMap type_map, final PrintWriter writer, final ExecutableElement method, final TypeMirror result_type, final boolean preDeclare) { private static void printResultParam(final TypeMap type_map, final PrintWriter writer, final ExecutableElement method, final TypeMirror result_type, final boolean preDeclare) {
@ -207,11 +205,11 @@ public class NativeMethodStubsGenerator {
result_type.accept(result_translator, null); result_type.accept(result_translator, null);
if ( preDeclare ) if ( preDeclare )
writer.print("\t"); writer.print("\t");
writer.print(result_translator.getSignature() + " " + Utils.RESULT_VAR_NAME); writer.append(result_translator.getSignature()).append(' ').append(Utils.RESULT_VAR_NAME);
if ( preDeclare ) if ( preDeclare )
writer.println(";"); writer.append(";\n");
else else
writer.print(result_param == null ? " = " : ";\n\t"); writer.append(result_param == null ? " = " : ";\n\t");
} }
private static void generateCallParameters(PrintWriter writer, TypeMap type_map, List<? extends VariableElement> params) { private static void generateCallParameters(PrintWriter writer, TypeMap type_map, List<? extends VariableElement> params) {
@ -224,7 +222,7 @@ public class NativeMethodStubsGenerator {
if ( first ) if ( first )
first = false; first = false;
else else
writer.print(", "); writer.append(", ");
generateCallParameter(writer, type_map, param); generateCallParameter(writer, type_map, param);
} }
@ -237,31 +235,31 @@ public class NativeMethodStubsGenerator {
final Constant constant_annotation = param.getAnnotation(Constant.class); final Constant constant_annotation = param.getAnnotation(Constant.class);
if ( constant_annotation != null && constant_annotation.isNative() ) { if ( constant_annotation != null && constant_annotation.isNative() ) {
writer.print(constant_annotation.value()); writer.append(constant_annotation.value());
return; return;
} }
boolean is_indirect = param.getAnnotation(Indirect.class) != null; boolean is_indirect = param.getAnnotation(Indirect.class) != null;
if ( is_indirect || param.getAnnotation(PointerArray.class) != null ) { if ( is_indirect || param.getAnnotation(PointerArray.class) != null ) {
writer.print("("); writer.append('(');
final NativeTypeTranslator translator = new NativeTypeTranslator(type_map, param); final NativeTypeTranslator translator = new NativeTypeTranslator(type_map, param);
param.asType().accept(translator, null); param.asType().accept(translator, null);
writer.print(translator.getSignature()); writer.append(translator.getSignature());
writer.print("*)"); writer.append("*)");
} }
if ( param.getAnnotation(PointerWrapper.class) != null ) if ( param.getAnnotation(PointerWrapper.class) != null )
writer.print("(" + param.getAnnotation(PointerWrapper.class).value() + ")(intptr_t)"); writer.append('(').append(param.getAnnotation(PointerWrapper.class).value()).append(")(intptr_t)");
if ( param.getAnnotation(Result.class) != null || is_indirect ) if ( param.getAnnotation(Result.class) != null || is_indirect )
writer.print("&"); writer.append('&');
if ( param.getAnnotation(Result.class) != null ) { if ( param.getAnnotation(Result.class) != null ) {
writer.print(Utils.RESULT_VAR_NAME); writer.append(Utils.RESULT_VAR_NAME);
} else { } else {
writer.print(param.getSimpleName()); writer.append(param.getSimpleName());
if ( param.getAnnotation(PointerArray.class) != null ) if ( param.getAnnotation(PointerArray.class) != null )
writer.print(getPointerArrayName(Utils.getJavaType(param.asType()))); writer.append(getPointerArrayName(Utils.getJavaType(param.asType())));
else if ( Utils.isAddressableType(param.asType()) ) else if ( Utils.isAddressableType(param.asType()) )
writer.print(BUFFER_ADDRESS_POSTFIX); writer.append(BUFFER_ADDRESS_POSTFIX);
} }
} }
@ -269,9 +267,9 @@ public class NativeMethodStubsGenerator {
for ( VariableElement param : params ) { for ( VariableElement param : params ) {
final Class java_type = Utils.getJavaType(param.asType()); final Class java_type = Utils.getJavaType(param.asType());
if ( java_type.equals(String.class) && param.getAnnotation(Result.class) == null ) if ( java_type.equals(String.class) && param.getAnnotation(Result.class) == null )
writer.println("\tfree(" + param.getSimpleName() + BUFFER_ADDRESS_POSTFIX + ");"); writer.append("\tfree(" + param.getSimpleName() + BUFFER_ADDRESS_POSTFIX + ");\n");
else if ( param.getAnnotation(PointerArray.class) != null ) // Free the string array mem else if ( param.getAnnotation(PointerArray.class) != null ) // Free the string array mem
writer.println("\tfree(" + param.getSimpleName() + getPointerArrayName(java_type) + ");"); writer.append("\tfree(" + param.getSimpleName() + getPointerArrayName(java_type) + ");\n");
} }
} }
@ -298,22 +296,22 @@ public class NativeMethodStubsGenerator {
final String native_type = translator.getSignature(); final String native_type = translator.getSignature();
if ( !java_type.isArray() || CharSequence.class.isAssignableFrom(java_type.getComponentType()) ) { if ( !java_type.isArray() || CharSequence.class.isAssignableFrom(java_type.getComponentType()) ) {
writer.print("\t" + native_type + param.getSimpleName()); writer.append('\t').append(native_type).append(param.getSimpleName());
writer.print(BUFFER_ADDRESS_POSTFIX + " = ("); writer.append(BUFFER_ADDRESS_POSTFIX + " = (");
writer.print(native_type); writer.append(native_type);
writer.print(")(intptr_t)"); writer.append(")(intptr_t)");
if ( mode == Mode.BUFFEROBJECT && param.getAnnotation(BufferObject.class) != null ) { if ( mode == Mode.BUFFEROBJECT && param.getAnnotation(BufferObject.class) != null ) {
writer.print("offsetToPointer(" + param.getSimpleName() + Utils.BUFFER_OBJECT_PARAMETER_POSTFIX + ")"); writer.append("offsetToPointer(").append(param.getSimpleName()).append(Utils.BUFFER_OBJECT_PARAMETER_POSTFIX + ')');
} else { } else {
if ( Buffer.class.isAssignableFrom(java_type) || java_type.equals(CharSequence.class) || java_type.equals(CharSequence[].class) || PointerBuffer.class.isAssignableFrom(java_type) ) { if ( Buffer.class.isAssignableFrom(java_type) || java_type.equals(CharSequence.class) || java_type.equals(CharSequence[].class) || PointerBuffer.class.isAssignableFrom(java_type) ) {
writer.print(param.getSimpleName()); writer.append(param.getSimpleName());
} else if ( java_type.equals(String.class) ) { } else if ( java_type.equals(String.class) ) {
writer.print("GetStringNativeChars(env, " + param.getSimpleName() + ")"); writer.append("GetStringNativeChars(env, ").append(param.getSimpleName()).append(')');
} else if ( array_annotation == null ) } else if ( array_annotation == null )
throw new RuntimeException("Illegal type " + java_type); throw new RuntimeException("Illegal type " + java_type);
} }
writer.println(";"); writer.append(";\n");
} }
if ( array_annotation != null ) { if ( array_annotation != null ) {
@ -327,8 +325,8 @@ public class NativeMethodStubsGenerator {
// Declare loop counters and allocate object array // Declare loop counters and allocate object array
if ( !ptrLoopDeclared ) { if ( !ptrLoopDeclared ) {
writer.println("\tint " + n + "_i;"); writer.append("\tint ").append(n).append("_i;\n");
writer.println("\tjobject " + n + "_object;"); writer.append("\tjobject ").append(n).append("_object;\n");
ptrLoopDeclared = true; ptrLoopDeclared = true;
} }
} else { } else {
@ -339,16 +337,16 @@ public class NativeMethodStubsGenerator {
// Declare loop counters and allocate string array // Declare loop counters and allocate string array
if ( !strLoopDeclared ) { if ( !strLoopDeclared ) {
writer.println("\tint " + n + "_i;"); writer.append("\tint ").append(n).append("_i;\n");
writer.println("\t" + arrayType + n + "_address;"); writer.append("\t").append(arrayType).append(n).append("_address;\n");
strLoopDeclared = true; strLoopDeclared = true;
} }
} }
writer.print("\t" + arrayType + "*" + param.getSimpleName() + n + " = "); writer.append('\t').append(arrayType).append('*').append(param.getSimpleName()).append(n).append(" = ");
if ( check_annotation != null && check_annotation.canBeNull() ) if ( check_annotation != null && check_annotation.canBeNull() )
writer.print(array_annotation.value() + " == 0 ? NULL : "); writer.append(array_annotation.value()).append(" == 0 ? NULL : ");
writer.println("(" + arrayType + "*) malloc(" + array_annotation.value() + " * sizeof(" + arrayType + "));"); writer.append('(').append(arrayType).append("*) malloc(").append(array_annotation.value()).append(" * sizeof(" + arrayType + "));\n");
} }
} }
@ -381,32 +379,33 @@ public class NativeMethodStubsGenerator {
final String n = getPointerArrayName(java_type); final String n = getPointerArrayName(java_type);
if ( POINTER_LIST_NAME.equals(n) ) { if ( POINTER_LIST_NAME.equals(n) ) {
// Init vars // Init vars
writer.println("\t" + n + "_i = 0;"); writer.append('\t').append(n).append("_i = 0;\n");
// Fill pointer array with the buffer pointers // Fill pointer array with the buffer pointers
writer.println("\twhile ( " + n + "_i < " + pointerArray_annotation.value() + " ) {"); writer.append("\twhile ( ").append(n).append("_i < ").append(pointerArray_annotation.value()).append(" ) {\n");
writer.println("\t\t" + n + "_object = (*env)->GetObjectArrayElement(env, " + param.getSimpleName() + ", " + n + "_i);"); writer.append("\t\t").append(n).append("_object = (*env)->GetObjectArrayElement(env, ").append(param.getSimpleName()).append(", ").append(n).append("_i);\n");
writer.print("\t\t" + param.getSimpleName() + n + "[" + n + "_i++] = (" + translator.getSignature(true) + ")"); writer.append("\t\t").append(param.getSimpleName()).append(n).append('[').append(n).append("_i++] = (").append(translator.getSignature(true)).append(')');
if ( Buffer.class.isAssignableFrom(component_type) ) if ( Buffer.class.isAssignableFrom(component_type) )
writer.println("(*env)->GetDirectBufferAddress(env, " + n + "_object);"); writer.append("(*env)->GetDirectBufferAddress(env, ");
else else
writer.println("(intptr_t)getPointerWrapperAddress(env, " + n + "_object);"); writer.append("(intptr_t)getPointerWrapperAddress(env, ");
writer.println("\t}"); writer.append(n).append("_object);\n")
.append("\t}\n");
} else { } else {
final String lengths = pointerArray_annotation.lengths(); final String lengths = pointerArray_annotation.lengths();
// Init vars // Init vars
writer.println("\t" + n + "_i = 0;"); writer.append('\t').append(n).append("_i = 0;\n");
writer.println("\t" + n + "_address = (" + translator.getSignature(true) + ")" + param.getSimpleName() + BUFFER_ADDRESS_POSTFIX + ";"); writer.append('\t').append(n).append("_address = (").append(translator.getSignature(true)).append(')').append(param.getSimpleName()).append(BUFFER_ADDRESS_POSTFIX + ";\n");
// Fill string array with the string pointers // Fill string array with the string pointers
writer.println("\twhile ( " + n + "_i < " + pointerArray_annotation.value() + " ) {"); writer.append("\twhile ( ").append(n).append("_i < ").append(pointerArray_annotation.value()).append(" ) {\n");
if ( lengths.length() == 0 ) { if ( lengths.length() == 0 ) {
writer.println("\t\t" + param.getSimpleName() + n + "[" + n + "_i++] = " + n + "_address;"); writer.append("\t\t").append(param.getSimpleName()).append(n).append('[').append(n).append("_i++] = ").append(n).append("_address;\n");
writer.println("\t\t" + n + "_address += strlen((const char *)" + n + "_address) + 1;"); writer.append("\t\t").append(n).append("_address += strlen((const char *)").append(n).append("_address) + 1;\n");
} else { } else {
writer.println("\t\t" + param.getSimpleName() + n + "[" + n + "_i] = " + n + "_address;"); writer.append("\t\t").append(param.getSimpleName()).append(n).append('[').append(n).append("_i] = ").append(n).append("_address;\n");
writer.println("\t\t" + n + "_address += " + lengths + BUFFER_ADDRESS_POSTFIX + "[" + n + "_i++];"); writer.append("\t\t").append(n).append("_address += ").append(lengths).append(BUFFER_ADDRESS_POSTFIX + "[").append(n).append("_i++];\n");
} }
writer.println("\t}"); writer.append("\t}\n");
} }
} }
} }

View File

@ -214,7 +214,10 @@ public class NativeTypeTranslator extends SimpleTypeVisitor6<Void, Void> {
* @discuss compare (DeclaredType).getAnnotation(Class) and (Element).getAnnotation(Class), they mean different Annotation's. * @discuss compare (DeclaredType).getAnnotation(Class) and (Element).getAnnotation(Class), they mean different Annotation's.
*/ */
public static <T extends Annotation> T getAnnotation(AnnotationMirror annotation, Class<T> type) { public static <T extends Annotation> T getAnnotation(AnnotationMirror annotation, Class<T> type) {
return annotation.getAnnotationType().asElement().getAnnotation(type); Element e = annotation.getAnnotationType().asElement();
synchronized (e) {
return e.getAnnotation(type);
}
} }
private static Class translateAnnotation(AnnotationMirror annotation) { private static Class translateAnnotation(AnnotationMirror annotation) {

View File

@ -51,7 +51,6 @@ public interface TypeMap {
void printCapabilitiesInit(PrintWriter writer); void printCapabilitiesInit(PrintWriter writer);
String getCapabilities(); String getCapabilities();
String getAPIUtilParam(boolean comma); String getAPIUtilParam(boolean comma);
void printErrorCheckMethod(PrintWriter writer, ExecutableElement method, String tabs);
String getRegisterNativesFunctionName(); String getRegisterNativesFunctionName();
TypeKind getPrimitiveTypeFromNativeType(Class<? extends Annotation> native_type); TypeKind getPrimitiveTypeFromNativeType(Class<? extends Annotation> native_type);
String getTypedefPostfix(); String getTypedefPostfix();

View File

@ -206,11 +206,11 @@ public class Utils {
String doc_comment = pe.getElementUtils().getDocComment(decl); String doc_comment = pe.getElementUtils().getDocComment(decl);
if ( doc_comment != null ) { if ( doc_comment != null ) {
final String tab = (decl instanceof TypeElement) ? "" : "\t"; final String tab = (decl instanceof TypeElement) ? "" : "\t";
writer.println(tab + "/**"); writer.append(tab).append("/**\n");
if ( overloadsComment != null ) { if ( overloadsComment != null ) {
writer.println("\t * " + overloadsComment); writer.append("\t * ").append(overloadsComment).append('\n');
writer.println("\t * <p>"); writer.append("\t * <p>").append('\n');
} }
final StringTokenizer doc_lines = new StringTokenizer(doc_comment, "\n", true); final StringTokenizer doc_lines = new StringTokenizer(doc_comment, "\n", true);
@ -219,18 +219,18 @@ public class Utils {
final String t = doc_lines.nextToken(); final String t = doc_lines.nextToken();
if ( "\n".equals(t) ) { if ( "\n".equals(t) ) {
if ( lastWasNL ) { if ( lastWasNL ) {
writer.println(tab + " * <p>"); writer.append(tab).append(" * <p>").append('\n');
} }
lastWasNL = true; lastWasNL = true;
} else { } else {
writer.println(tab + " * " + t); writer.append(tab).append(" * ").append(t).append('\n');
lastWasNL = false; lastWasNL = false;
} }
} }
writer.println(tab + " */"); writer.append(tab).append(" */\n");
} else if ( overloadsComment != null ) { } else if ( overloadsComment != null ) {
writer.println("\t/** " + overloadsComment + " */"); writer.append("\t/** ").append(overloadsComment).append(" */\n");
} }
} }
@ -331,9 +331,9 @@ public class Utils {
} }
public static void printExtraCallArguments(PrintWriter writer, ExecutableElement method, String size_parameter_name) { public static void printExtraCallArguments(PrintWriter writer, ExecutableElement method, String size_parameter_name) {
writer.print(size_parameter_name); writer.append(size_parameter_name);
if ( method.getAnnotation(CachedResult.class) != null ) { if ( method.getAnnotation(CachedResult.class) != null ) {
writer.print(", " + CACHED_BUFFER_NAME); writer.append(", ").append(CACHED_BUFFER_NAME);
} }
} }
@ -451,10 +451,9 @@ public class Utils {
if ( "String".equals(return_type) ) { if ( "String".equals(return_type) ) {
if ( !return_annotation.forceMaxLength() ) { if ( !return_annotation.forceMaxLength() ) {
writer.println("IntBuffer " + return_annotation.value() + "_length = APIUtil.getLengths(" + type_map.getAPIUtilParam(false) + ");"); writer.append("IntBuffer ").append(return_annotation.value()).append("_length = APIUtil.getLengths(").append(type_map.getAPIUtilParam(false)).append(");\n\t\t");
writer.print("\t\t");
} }
writer.print("ByteBuffer " + return_annotation.value() + " = APIUtil.getBufferByte(" + type_map.getAPIUtilParam(true) + return_annotation.maxLength()); writer.append("ByteBuffer ").append(return_annotation.value()).append(" = APIUtil.getBufferByte(").append(type_map.getAPIUtilParam(true)).append(return_annotation.maxLength());
/* /*
Params that use the return buffer will advance its position while filling it. When we return, the position will be Params that use the return buffer will advance its position while filling it. When we return, the position will be
at the right spot for grabbing the returned string bytes. We only have to make sure that the original buffer was at the right spot for grabbing the returned string bytes. We only have to make sure that the original buffer was
@ -462,24 +461,27 @@ public class Utils {
*/ */
final String offset = getStringOffset(method, null); final String offset = getStringOffset(method, null);
if ( offset != null ) { if ( offset != null ) {
writer.print(" + " + offset); writer.append(" + ").append(offset);
} }
writer.println(");"); writer.append(");\n");
} else { } else {
final String buffer_type = "Boolean".equals(return_type) ? "Byte" : return_type; final String buffer_type = "Boolean".equals(return_type) ? "Byte" : return_type;
writer.print(buffer_type + "Buffer " + return_annotation.value() + " = APIUtil.getBuffer" + buffer_type + "(" + type_map.getAPIUtilParam(false)); writer.append(buffer_type).append("Buffer ").append(return_annotation.value()).append(" = APIUtil.getBuffer").append(buffer_type).append('(').append(type_map.getAPIUtilParam(false));
if ( "Byte".equals(buffer_type) ) { if ( "Byte".equals(buffer_type) ) {
writer.print((type_map.getAPIUtilParam(false).length() > 0 ? ", " : "") + "1"); if (type_map.getAPIUtilParam(false).length() > 0) {
writer.append(", ");
}
writer.append('1');
} }
writer.println(");"); writer.append(");\n");
} }
final Code code_annotation = method.getAnnotation(Code.class); final Code code_annotation = method.getAnnotation(Code.class);
if ( code_annotation != null && code_annotation.tryBlock() ) { if ( code_annotation != null && code_annotation.tryBlock() ) {
writer.println("\t\ttry {"); writer.append("\t\ttry {\n");
writer.print("\t\t\t"); writer.append("\t\t\t");
} else { } else {
writer.print("\t\t"); writer.append("\t\t");
} }
} }
@ -487,33 +489,33 @@ public class Utils {
final String return_type = getMethodReturnType(method, return_annotation, true); final String return_type = getMethodReturnType(method, return_annotation, true);
if ( "String".equals(return_type) ) { if ( "String".equals(return_type) ) {
writer.print("\t\t" + return_annotation.value() + ".limit("); writer.append("\t\t").append(return_annotation.value()).append(".limit(");
final String offset = getStringOffset(method, null); final String offset = getStringOffset(method, null);
if ( offset != null ) { if ( offset != null ) {
writer.print(offset + " + "); writer.append(offset).append(" + ");
} }
if ( return_annotation.forceMaxLength() ) { if ( return_annotation.forceMaxLength() ) {
writer.print(return_annotation.maxLength()); writer.append(return_annotation.maxLength());
} else { } else {
writer.print(return_annotation.value() + "_length.get(0)"); writer.append(return_annotation.value()).append("_length.get(0)");
} }
writer.println(");"); writer.append(");\n");
writer.println("\t\treturn APIUtil.getString(" + type_map.getAPIUtilParam(true) + return_annotation.value() + ");"); writer.append("\t\treturn APIUtil.getString(").append(type_map.getAPIUtilParam(true)).append(return_annotation.value()).append(");\n");
} else { } else {
writer.print("\t\treturn " + return_annotation.value() + ".get(0)"); writer.append("\t\treturn ").append(return_annotation.value()).append(".get(0)");
if ( "Boolean".equals(return_type) ) { if ( "Boolean".equals(return_type) ) {
writer.print(" == 1"); writer.append(" == 1");
} }
writer.println(";"); writer.append(";\n");
} }
} }
public static Collection<VariableElement> getFields(TypeElement d) { public static Collection<VariableElement> getFields(TypeElement d) {
return ElementFilter.fieldsIn(new LinkedHashSet<Element>(d.getEnclosedElements())); return ElementFilter.fieldsIn(d.getEnclosedElements());
} }
public static Collection<ExecutableElement> getMethods(TypeElement d) { public static Collection<ExecutableElement> getMethods(TypeElement d) {
return ElementFilter.methodsIn(new LinkedHashSet<Element>(d.getEnclosedElements())); return ElementFilter.methodsIn(d.getEnclosedElements());
} }
} }

View File

@ -190,11 +190,6 @@ public class ALTypeMap implements TypeMap {
return ""; return "";
} }
@Override
public void printErrorCheckMethod(final PrintWriter writer, final ExecutableElement method, final String tabs) {
writer.println(tabs + "Util.checkALError();");
}
@Override @Override
public String getRegisterNativesFunctionName() { public String getRegisterNativesFunctionName() {
return "extal_InitializeClass"; return "extal_InitializeClass";

View File

@ -134,7 +134,7 @@ public class CLGeneratorProcessor extends AbstractProcessor {
} }
writer.println("}"); writer.println("}");
saveGeneratedJavaSource(processingEnv, genJavaPath, "org.lwjgl.opencl." + CLCAPS_CLASS_NAME, writer1.toString(), startTime); saveGeneratedJavaSource(processingEnv.getMessager(), genJavaPath, "org.lwjgl.opencl." + CLCAPS_CLASS_NAME, writer1.toString(), startTime);
} }
private void generateCLPDCapabilitiesSource(Path genJavaPath, Set<TypeElement> templates, final Class<? extends Annotation> capsType, final String capsName, final Class<? extends PointerWrapper> objectType, final String objectName) throws IOException { private void generateCLPDCapabilitiesSource(Path genJavaPath, Set<TypeElement> templates, final Class<? extends Annotation> capsType, final String capsName, final Class<? extends PointerWrapper> objectType, final String objectName) throws IOException {
@ -161,6 +161,6 @@ public class CLGeneratorProcessor extends AbstractProcessor {
CLPDCapabilitiesGenerator.generateToString(writer, templates, capsType); CLPDCapabilitiesGenerator.generateToString(writer, templates, capsType);
writer.println("}"); writer.println("}");
saveGeneratedJavaSource(processingEnv, genJavaPath, "org.lwjgl.opencl." + capsName, writer1.toString(), startTime); saveGeneratedJavaSource(processingEnv.getMessager(), genJavaPath, "org.lwjgl.opencl." + capsName, writer1.toString(), startTime);
} }
} }

View File

@ -96,29 +96,6 @@ public class CLTypeMap implements TypeMap {
return ""; return "";
} }
@Override
public void printErrorCheckMethod(final PrintWriter writer, final ExecutableElement method, final String tabs) {
final Check check = method.getAnnotation(Check.class);
if ( check != null ) // Get the error code from an IntBuffer output parameter
writer.println(tabs + "Util.checkCLError(" + check.value() + ".get(" + check.value() + ".position()));");
else {
final Class return_type = Utils.getJavaType(method.getReturnType());
if ( return_type == int.class )
writer.println(tabs + "Util.checkCLError(__result);");
else {
boolean hasErrCodeParam = false;
for ( final VariableElement param : method.getParameters() ) {
if ( "errcode_ret".equals(param.getSimpleName().toString()) && Utils.getJavaType(param.asType()) == IntBuffer.class ) {
hasErrCodeParam = true;
break;
}
}
if ( hasErrCodeParam )
throw new RuntimeException("A method is missing the @Check annotation: " + method.toString());
}
}
}
@Override @Override
public String getRegisterNativesFunctionName() { public String getRegisterNativesFunctionName() {
return "extcl_InitializeClass"; return "extcl_InitializeClass";
@ -285,4 +262,4 @@ public class CLTypeMap implements TypeMap {
public String getAutoTypeFromAnnotation(AnnotationMirror annotation) { public String getAutoTypeFromAnnotation(AnnotationMirror annotation) {
return null; return null;
} }
} }

View File

@ -62,19 +62,18 @@ public class GLCapabilitiesGenerator {
private static final String CORE_PREFIX = "Open"; private static final String CORE_PREFIX = "Open";
public static void generateClassPrologue(PrintWriter writer, boolean context_specific, boolean generate_error_checks) { public static void generateClassPrologue(PrintWriter writer, boolean context_specific, boolean generate_error_checks) {
writer.println("public class " + Utils.CONTEXT_CAPS_CLASS_NAME + " {"); writer.append("public class " + Utils.CONTEXT_CAPS_CLASS_NAME + " {\n");
writer.println("\tstatic final boolean DEBUG = " + Boolean.toString(generate_error_checks) + ";"); writer.append("\tstatic final boolean DEBUG = ").append(Boolean.toString(generate_error_checks)).append(";\n");
writer.println("\tfinal APIUtil util = new APIUtil();"); writer.append("\tfinal APIUtil util = new APIUtil();\n");
writer.println("\tfinal StateTracker tracker = new StateTracker();"); writer.append("\tfinal StateTracker tracker = new StateTracker();\n\n");
writer.println();
if ( !context_specific ) { if ( !context_specific ) {
writer.println("\tprivate static boolean " + STUBS_LOADED_NAME + " = false;"); writer.append("\tprivate static boolean " + STUBS_LOADED_NAME + " = false;\n");
} }
} }
public static void generateInitializerPrologue(PrintWriter writer) { public static void generateInitializerPrologue(PrintWriter writer) {
writer.println("\t" + Utils.CONTEXT_CAPS_CLASS_NAME + "(boolean forwardCompatible) throws LWJGLException {"); writer.append("\t" + Utils.CONTEXT_CAPS_CLASS_NAME + "(boolean forwardCompatible) throws LWJGLException {\n");
writer.println("\t\tSet<String> " + CACHED_EXTS_VAR_NAME + " = " + ALL_INIT_METHOD_NAME + "(forwardCompatible);"); writer.append("\t\tSet<String> " + CACHED_EXTS_VAR_NAME + " = " + ALL_INIT_METHOD_NAME + "(forwardCompatible);\n");
} }
private static String translateFieldName(String interface_name) { private static String translateFieldName(String interface_name) {
@ -90,34 +89,34 @@ public class GLCapabilitiesGenerator {
throw new RuntimeException(d + " extends more than one other interface"); throw new RuntimeException(d + " extends more than one other interface");
if ( super_interfaces.size() == 1 ) { if ( super_interfaces.size() == 1 ) {
TypeMirror super_interface = super_interfaces.iterator().next(); TypeMirror super_interface = super_interfaces.iterator().next();
writer.print("\t\tif (" + CACHED_EXTS_VAR_NAME + ".contains(\""); writer.append("\t\tif (").append(CACHED_EXTS_VAR_NAME).append(".contains(\"");
writer.println(translateFieldName(d.getSimpleName().toString()) + "\"))"); writer.append(translateFieldName(d.getSimpleName().toString())).append("\"))\n");
writer.print("\t\t\t"); writer.append("\t\t\t");
generateAddExtension(writer, env.getElementUtils().getTypeElement(super_interface.toString())); generateAddExtension(writer, env.getElementUtils().getTypeElement(super_interface.toString()));
} }
} }
public static void generateInitializer(PrintWriter writer, TypeElement d, ProcessingEnvironment env) { public static void generateInitializer(PrintWriter writer, TypeElement d, ProcessingEnvironment env) {
String translated_field_name = translateFieldName(d.getSimpleName().toString()); String translated_field_name = translateFieldName(d.getSimpleName().toString());
writer.print("\t\tthis." + translated_field_name + " = "); writer.append("\t\tthis.").append(translated_field_name).append(" = ");
writer.print(CACHED_EXTS_VAR_NAME + ".contains(\""); writer.append(CACHED_EXTS_VAR_NAME + ".contains(\"");
writer.print(translated_field_name + "\")"); writer.append(translated_field_name).append("\")");
List<? extends TypeMirror> super_interfaces = d.getInterfaces(); List<? extends TypeMirror> super_interfaces = d.getInterfaces();
if ( super_interfaces.size() > 1 ) if ( super_interfaces.size() > 1 )
throw new RuntimeException(d + " extends more than one other interface"); throw new RuntimeException(d + " extends more than one other interface");
if ( super_interfaces.size() == 1 ) { if ( super_interfaces.size() == 1 ) {
TypeMirror super_interface = super_interfaces.iterator().next(); TypeMirror super_interface = super_interfaces.iterator().next();
writer.println(); writer.append('\n');
writer.print("\t\t\t&& " + CACHED_EXTS_VAR_NAME + ".contains(\""); writer.append("\t\t\t&& ").append(CACHED_EXTS_VAR_NAME).append(".contains(\"");
writer.print(translateFieldName(env.getElementUtils().getTypeElement(super_interface.toString()).getSimpleName().toString()) + "\")"); writer.append(translateFieldName(env.getElementUtils().getTypeElement(super_interface.toString()).getSimpleName().toString())).append("\")");
} }
Alias alias_annotation = d.getAnnotation(Alias.class); Alias alias_annotation = d.getAnnotation(Alias.class);
if ( alias_annotation != null ) { if ( alias_annotation != null ) {
writer.println(); writer.append('\n');
writer.print("\t\t\t|| " + CACHED_EXTS_VAR_NAME + ".contains(\""); writer.append("\t\t\t|| ").append(CACHED_EXTS_VAR_NAME).append(".contains(\"");
writer.print(translateFieldName(alias_annotation.value()) + "\")"); writer.append(translateFieldName(alias_annotation.value())).append("\")");
} }
writer.println(";"); writer.append(";\n");
} }
private static String getAddressesInitializerName(String class_name) { private static String getAddressesInitializerName(String class_name) {
@ -125,48 +124,47 @@ public class GLCapabilitiesGenerator {
} }
public static void generateInitStubsPrologue(PrintWriter writer, boolean context_specific) { public static void generateInitStubsPrologue(PrintWriter writer, boolean context_specific) {
writer.println("\tprivate Set<String> " + ALL_INIT_METHOD_NAME + "(boolean forwardCompatible) throws LWJGLException {"); writer.append("\tprivate Set<String> ").append(ALL_INIT_METHOD_NAME).append("(boolean forwardCompatible) throws LWJGLException {\n");
// Load the basic pointers we need to detect OpenGL version and supported extensions. // Load the basic pointers we need to detect OpenGL version and supported extensions.
writer.println("\t\tglGetError = GLContext.getFunctionAddress(\"glGetError\");"); writer.append("\t\tglGetError = GLContext.getFunctionAddress(\"glGetError\");\n");
writer.println("\t\tglGetString = GLContext.getFunctionAddress(\"glGetString\");"); writer.append("\t\tglGetString = GLContext.getFunctionAddress(\"glGetString\");\n");
// Initialize GL11.glGetIntegerv and GL30.glGetStringi here, in case we have created an OpenGL 3.0 context. // Initialize GL11.glGetIntegerv and GL30.glGetStringi here, in case we have created an OpenGL 3.0 context.
// (they will be used in GLContext.getSupportedExtensions) // (they will be used in GLContext.getSupportedExtensions)
writer.println("\t\tglGetIntegerv = GLContext.getFunctionAddress(\"glGetIntegerv\");"); writer.append("\t\tglGetIntegerv = GLContext.getFunctionAddress(\"glGetIntegerv\");\n");
writer.println("\t\tglGetStringi = GLContext.getFunctionAddress(\"glGetStringi\");"); writer.append("\t\tglGetStringi = GLContext.getFunctionAddress(\"glGetStringi\");\n");
// Get the supported extensions set. // Get the supported extensions set.
writer.println("\t\tGLContext.setCapabilities(this);"); writer.append("\t\tGLContext.setCapabilities(this);\n");
writer.println("\t\tSet<String> " + CACHED_EXTS_VAR_NAME + " = new HashSet<String>(256);"); writer.append("\t\tSet<String> " + CACHED_EXTS_VAR_NAME + " = new HashSet<String>(256);\n");
writer.println("\t\tint " + PROFILE_MASK_VAR_NAME + " = GLContext.getSupportedExtensions(" + CACHED_EXTS_VAR_NAME + ");"); writer.append("\t\tint " + PROFILE_MASK_VAR_NAME + " = GLContext.getSupportedExtensions(" + CACHED_EXTS_VAR_NAME + ");\n");
// Force forward compatible mode when OpenGL version is 3.1 or higher and ARB_compatibility is not available. // Force forward compatible mode when OpenGL version is 3.1 or higher and ARB_compatibility is not available.
writer.println("\t\tif ( supported_extensions.contains(\"OpenGL31\") && !(supported_extensions.contains(\"GL_ARB_compatibility\") || (profileMask & GL32.GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0) )"); writer.append("\t\tif ( supported_extensions.contains(\"OpenGL31\") && !(supported_extensions.contains(\"GL_ARB_compatibility\") || (profileMask & GL32.GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0) )\n");
writer.println("\t\t\tforwardCompatible = true;"); writer.append("\t\t\tforwardCompatible = true;\n");
if ( !context_specific ) { if ( !context_specific ) {
writer.println("\t\tif (" + STUBS_LOADED_NAME + ")"); writer.append("\t\tif (" + STUBS_LOADED_NAME + ")\n");
writer.println("\t\t\treturn GLContext.getSupportedExtensions();"); writer.append("\t\t\treturn GLContext.getSupportedExtensions();\n");
writer.println("\t\torg.lwjgl.opengl.GL11." + Utils.STUB_INITIALIZER_NAME + "();"); writer.append("\t\torg.lwjgl.opengl.GL11." + Utils.STUB_INITIALIZER_NAME + "();\n");
} else { } else {
writer.println("\t\tif (!" + getAddressesInitializerName("GL11") + "(forwardCompatible))"); writer.append("\t\tif (!").append(getAddressesInitializerName("GL11")).append("(forwardCompatible))\n");
writer.println("\t\t\tthrow new LWJGLException(\"GL11 not supported\");"); writer.append("\t\t\tthrow new LWJGLException(\"GL11 not supported\");\n");
} }
} }
public static void generateInitStubsEpilogue(PrintWriter writer, boolean context_specific) { public static void generateInitStubsEpilogue(PrintWriter writer, boolean context_specific) {
if ( !context_specific ) { if ( !context_specific ) {
writer.println("\t\t" + STUBS_LOADED_NAME + " = true;"); writer.append("\t\t" + STUBS_LOADED_NAME + " = true;\n");
} }
writer.println("\t\treturn " + CACHED_EXTS_VAR_NAME + ";"); writer.append("\t\treturn " + CACHED_EXTS_VAR_NAME + ";\n");
writer.println("\t}"); writer.append("\t}\n");
} }
public static void generateUnloadStubs(ProcessingEnvironment env, PrintWriter writer, TypeElement d) { public static void generateUnloadStubs(ProcessingEnvironment env, PrintWriter writer, TypeElement d) {
if ( Utils.getMethods(d).size() > 0 ) { if ( Utils.getMethods(d).size() > 0 ) {
writer.print("\t\tGLContext.resetNativeStubs(" + Utils.getSimpleClassName(d)); writer.append("\t\tGLContext.resetNativeStubs(").append(Utils.getSimpleClassName(d)).append(".class);\n");
writer.println(".class);");
} }
} }
@ -176,44 +174,41 @@ public class GLCapabilitiesGenerator {
final Alias alias_annotation = d.getAnnotation(Alias.class); final Alias alias_annotation = d.getAnnotation(Alias.class);
if ( d.getAnnotation(ForceInit.class) != null ) if ( d.getAnnotation(ForceInit.class) != null )
writer.println("\t\t" + CACHED_EXTS_VAR_NAME + ".add(\"" + translateFieldName(d.getSimpleName().toString()) + "\");"); writer.append("\t\t" + CACHED_EXTS_VAR_NAME + ".add(\"").append(translateFieldName(d.getSimpleName().toString())).append("\");\n");
writer.print("\t\tif ("); writer.append("\t\tif (");
if ( alias_annotation != null ) if ( alias_annotation != null )
writer.print("("); writer.append('(');
writer.print(CACHED_EXTS_VAR_NAME + ".contains(\""); writer.append(CACHED_EXTS_VAR_NAME + ".contains(\"");
writer.print(translateFieldName(d.getSimpleName().toString()) + "\")"); writer.append(translateFieldName(d.getSimpleName().toString())).append("\")");
if ( alias_annotation != null ) { if ( alias_annotation != null ) {
writer.print(" || " + CACHED_EXTS_VAR_NAME + ".contains(\""); writer.append(" || " + CACHED_EXTS_VAR_NAME + ".contains(\"");
writer.print(translateFieldName(alias_annotation.value()) + "\"))"); writer.append(translateFieldName(alias_annotation.value())).append("\"))");
} }
writer.print(" && !" + getAddressesInitializerName(d.getSimpleName().toString()) + "("); writer.append(" && !").append(getAddressesInitializerName(d.getSimpleName().toString())).append('(');
if ( d.getAnnotation(DeprecatedGL.class) != null ) if ( d.getAnnotation(DeprecatedGL.class) != null )
writer.print("forwardCompatible"); writer.append("forwardCompatible");
if ( d.getAnnotation(Dependent.class) != null ) { if ( d.getAnnotation(Dependent.class) != null ) {
if ( d.getAnnotation(DeprecatedGL.class) != null ) if ( d.getAnnotation(DeprecatedGL.class) != null )
writer.print(","); writer.append(",");
writer.print("supported_extensions"); writer.append("supported_extensions");
} }
if ( alias_annotation != null ) { if ( alias_annotation != null ) {
writer.println(")) {"); writer.append(")) {\n");
writer.print("\t\t\tremove(" + CACHED_EXTS_VAR_NAME + ", \""); writer.append("\t\t\tremove(" + CACHED_EXTS_VAR_NAME + ", \"").append(translateFieldName(alias_annotation.value())).append("\");\n");
writer.println(translateFieldName(alias_annotation.value()) + "\");");
} else } else
writer.println("))"); writer.append("))\n");
writer.print("\t\t\tremove(" + CACHED_EXTS_VAR_NAME + ", \""); writer.append("\t\t\tremove(" + CACHED_EXTS_VAR_NAME + ", \"").append(translateFieldName(d.getSimpleName().toString())).append("\");\n");
writer.println(translateFieldName(d.getSimpleName().toString()) + "\");");
if ( alias_annotation != null ) if ( alias_annotation != null )
writer.println("\t\t}"); writer.append("\t\t}\n");
} else { } else {
writer.print("\t\tGLContext." + Utils.STUB_INITIALIZER_NAME + "(" + Utils.getSimpleClassName(d)); writer.append("\t\tGLContext." + Utils.STUB_INITIALIZER_NAME + "(").append(Utils.getSimpleClassName(d));
writer.println(".class, " + CACHED_EXTS_VAR_NAME + ", \"" + translateFieldName(d.getSimpleName().toString()) + "\");"); writer.append(".class, " + CACHED_EXTS_VAR_NAME + ", \"").append(translateFieldName(d.getSimpleName().toString())).append("\");\n");
} }
} }
} }
private static void generateAddExtension(PrintWriter writer, TypeElement d) { private static void generateAddExtension(PrintWriter writer, TypeElement d) {
writer.print(CACHED_EXTS_VAR_NAME + ".add(\""); writer.append(CACHED_EXTS_VAR_NAME + ".add(\"").append(translateFieldName(d.getSimpleName().toString())).append("\");\n");
writer.println(translateFieldName(d.getSimpleName().toString()) + "\");");
} }
public static void generateAddressesInitializers(ProcessingEnvironment env, PrintWriter writer, TypeElement d) { public static void generateAddressesInitializers(ProcessingEnvironment env, PrintWriter writer, TypeElement d) {
@ -221,24 +216,24 @@ public class GLCapabilitiesGenerator {
if ( !methods.hasNext() ) if ( !methods.hasNext() )
return; return;
writer.print("\tprivate boolean " + getAddressesInitializerName(d.getSimpleName().toString()) + "("); writer.append("\tprivate boolean ").append(getAddressesInitializerName(d.getSimpleName().toString())).append('(');
boolean optional; boolean optional;
boolean deprecated = d.getAnnotation(DeprecatedGL.class) != null; boolean deprecated = d.getAnnotation(DeprecatedGL.class) != null;
Dependent dependent = d.getAnnotation(Dependent.class); Dependent dependent = d.getAnnotation(Dependent.class);
if ( deprecated ) if ( deprecated )
writer.print("boolean forwardCompatible"); writer.append("boolean forwardCompatible");
if ( dependent != null ) { if ( dependent != null ) {
if ( deprecated ) if ( deprecated )
writer.print(","); writer.append(',');
writer.print("Set<String> supported_extensions"); writer.append("Set<String> supported_extensions");
} }
Alias alias_annotation = d.getAnnotation(Alias.class); Alias alias_annotation = d.getAnnotation(Alias.class);
boolean aliased = alias_annotation != null && alias_annotation.postfix().length() > 0; boolean aliased = alias_annotation != null && alias_annotation.postfix().length() > 0;
writer.println(") {"); writer.append(") {\n");
writer.println("\t\treturn "); writer.append("\t\treturn \n");
boolean first = true; boolean first = true;
while ( methods.hasNext() ) { while ( methods.hasNext() ) {
@ -247,7 +242,7 @@ public class GLCapabilitiesGenerator {
continue; continue;
if ( !first ) if ( !first )
writer.println(" &"); writer.append(" &\n");
else else
first = false; first = false;
@ -255,58 +250,57 @@ public class GLCapabilitiesGenerator {
deprecated = method.getAnnotation(DeprecatedGL.class) != null; deprecated = method.getAnnotation(DeprecatedGL.class) != null;
dependent = method.getAnnotation(Dependent.class); dependent = method.getAnnotation(Dependent.class);
writer.print("\t\t\t("); writer.append("\t\t\t(");
if ( optional ) if ( optional )
writer.print('('); writer.append('(');
if ( deprecated ) if ( deprecated )
writer.print("forwardCompatible || "); writer.append("forwardCompatible || ");
if ( dependent != null ) { if ( dependent != null ) {
if ( dependent.value().indexOf(',') == -1 ) if ( dependent.value().indexOf(',') == -1 )
writer.print("!supported_extensions.contains(\"" + dependent.value() + "\") || "); writer.append("!supported_extensions.contains(\"").append(dependent.value()).append("\") || ");
else { else {
writer.print("!(false"); writer.append("!(false");
for ( String extension : dependent.value().split(",") ) for ( String extension : dependent.value().split(",") )
writer.print(" || supported_extensions.contains(\"" + extension + "\")"); writer.append(" || supported_extensions.contains(\"").append(extension).append("\")");
writer.print(") || "); writer.append(") || ");
} }
} }
if ( deprecated || dependent != null ) if ( deprecated || dependent != null )
writer.print('('); writer.append('(');
writer.print(Utils.getFunctionAddressName(d, method) + " = "); writer.append(Utils.getFunctionAddressName(d, method)).append(" = ");
PlatformDependent platform_dependent = method.getAnnotation(PlatformDependent.class); PlatformDependent platform_dependent = method.getAnnotation(PlatformDependent.class);
if ( platform_dependent != null ) { if ( platform_dependent != null ) {
EnumSet<Platform> platform_set = EnumSet.copyOf(Arrays.asList(platform_dependent.value())); EnumSet<Platform> platform_set = EnumSet.copyOf(Arrays.asList(platform_dependent.value()));
writer.print("GLContext.getPlatformSpecificFunctionAddress(\""); writer.append("GLContext.getPlatformSpecificFunctionAddress(\"");
writer.print(Platform.ALL.getPrefix() + "\", "); writer.append(Platform.ALL.getPrefix()).append("\", ");
writer.print("new String[]{"); writer.append("new String[]{");
Iterator<Platform> platforms = platform_set.iterator(); Iterator<Platform> platforms = platform_set.iterator();
while ( platforms.hasNext() ) { while ( platforms.hasNext() ) {
writer.print("\"" + platforms.next().getOSPrefix() + "\""); writer.append("\"").append(platforms.next().getOSPrefix()).append("\"");
if ( platforms.hasNext() ) if ( platforms.hasNext() )
writer.print(", "); writer.append(", ");
} }
writer.print("}, new String[]{"); writer.append("}, new String[]{");
platforms = platform_set.iterator(); platforms = platform_set.iterator();
while ( platforms.hasNext() ) { while ( platforms.hasNext() ) {
writer.print("\"" + platforms.next().getPrefix() + "\""); writer.append("\"").append(platforms.next().getPrefix()).append("\"");
if ( platforms.hasNext() ) if ( platforms.hasNext() )
writer.print(", "); writer.append(", ");
} }
writer.print("}, "); writer.append("}, ");
} else if ( aliased ) { } else if ( aliased ) {
writer.print("GLContext.getFunctionAddress(new String[] {\"" + method.getSimpleName() + "\",\"" + method.getSimpleName() + alias_annotation.postfix() + "\"})) != 0"); writer.append("GLContext.getFunctionAddress(new String[] {\"").append(method.getSimpleName()).append("\",\"").append(method.getSimpleName()).append(alias_annotation.postfix()).append("\"})) != 0");
} else } else
writer.print("GLContext.getFunctionAddress("); writer.append("GLContext.getFunctionAddress(");
if ( !aliased ) if ( !aliased )
writer.print("\"" + method.getSimpleName() + "\")) != 0"); writer.append("\"").append(method.getSimpleName()).append("\")) != 0");
if ( deprecated || dependent != null ) if ( deprecated || dependent != null )
writer.print(')'); writer.append(')');
if ( optional ) if ( optional )
writer.print(" || true)"); writer.append(" || true)");
} }
writer.println(";"); writer.append(";\n");
writer.println("\t}"); writer.append("\t}\n");
writer.println();
} }
public static void generateSymbolAddresses(ProcessingEnvironment env, PrintWriter writer, TypeElement d) { public static void generateSymbolAddresses(ProcessingEnvironment env, PrintWriter writer, TypeElement d) {
@ -316,14 +310,14 @@ public class GLCapabilitiesGenerator {
continue; continue;
if ( first ) { if ( first ) {
writer.println("\t// " + d.getSimpleName()); writer.append("\t// ").append(d.getSimpleName()).append('\n');
first = false; first = false;
} }
writer.println("\tlong " + Utils.getFunctionAddressName(d, method) + ";"); writer.append("\tlong ").append(Utils.getFunctionAddressName(d, method)).append(";\n");
} }
} }
public static void generateField(PrintWriter writer, TypeElement d) { public static void generateField(PrintWriter writer, TypeElement d) {
writer.println("\tpublic final boolean " + translateFieldName(d.getSimpleName().toString()) + ";"); writer.append("\tpublic final boolean ").append(translateFieldName(d.getSimpleName().toString())).append(";\n");
} }
} }

View File

@ -107,11 +107,6 @@ public class GLESTypeMap implements TypeMap {
return ""; return "";
} }
@Override
public void printErrorCheckMethod(final PrintWriter writer, final ExecutableElement method, final String tabs) {
writer.println(tabs + "Util.checkGLError();");
}
@Override @Override
public String getRegisterNativesFunctionName() { public String getRegisterNativesFunctionName() {
return "extgl_InitializeClass"; return "extgl_InitializeClass";

View File

@ -123,7 +123,7 @@ public class GLGeneratorProcessor extends AbstractProcessor {
} }
writer.println("\tprivate static void remove(Set supported_extensions, String extension) {"); writer.println("\tprivate static void remove(Set supported_extensions, String extension) {");
writer.println("\t\tLWJGLUtil.log(extension + \" was reported as available but an entry point is missing\");"); writer.println("\t\tLWJGLUtil.logger().log(() -> extension + \" was reported as available but an entry point is missing\");");
writer.println("\t\tsupported_extensions.remove(extension);"); writer.println("\t\tsupported_extensions.remove(extension);");
writer.println("\t}\n"); writer.println("\t}\n");
@ -169,6 +169,6 @@ public class GLGeneratorProcessor extends AbstractProcessor {
writer.println("\t}"); writer.println("\t}");
writer.println("}"); writer.println("}");
saveGeneratedJavaSource(env, genJavaPath, "org.lwjgl.opengl." + Utils.CONTEXT_CAPS_CLASS_NAME, writer1.toString(), startTime); saveGeneratedJavaSource(env.getMessager(), genJavaPath, "org.lwjgl.opengl." + Utils.CONTEXT_CAPS_CLASS_NAME, writer1.toString(), startTime);
} }
} }

View File

@ -196,7 +196,7 @@ public class GLReferencesGeneratorProcessor extends AbstractProcessor {
writer.println("\t}"); writer.println("\t}");
writer.println("}"); writer.println("}");
saveGeneratedJavaSource(env, genJavaPath, "org.lwjgl.opengl." + REFERENCES_CLASS_NAME, writer1.toString(), startTime); saveGeneratedJavaSource(env.getMessager(), genJavaPath, "org.lwjgl.opengl." + REFERENCES_CLASS_NAME, writer1.toString(), startTime);
} }
} }

View File

@ -113,11 +113,6 @@ public class GLTypeMap implements TypeMap {
return comma ? "caps, " : "caps"; return comma ? "caps, " : "caps";
} }
@Override
public void printErrorCheckMethod(final PrintWriter writer, final ExecutableElement method, final String tabs) {
writer.println(tabs + "Util.checkGLError();");
}
@Override @Override
public String getRegisterNativesFunctionName() { public String getRegisterNativesFunctionName() {
return "extgl_InitializeClass"; return "extgl_InitializeClass";