diff --git a/buildSrc/src/main/groovy/java-gi.library-conventions.gradle b/buildSrc/src/main/groovy/java-gi.library-conventions.gradle index 9df26d60..a2660dfc 100644 --- a/buildSrc/src/main/groovy/java-gi.library-conventions.gradle +++ b/buildSrc/src/main/groovy/java-gi.library-conventions.gradle @@ -31,7 +31,7 @@ dependencies { } group = 'io.github.jwharm.javagi' -version = '0.8.0' +version = '0.8.1-SNAPSHOT' java { if (! System.getenv('CI')) { diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/generator/Patch.java b/buildSrc/src/main/java/io/github/jwharm/javagi/generator/Patch.java index 8a27ae2d..5d3fcfb9 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/generator/Patch.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/generator/Patch.java @@ -70,17 +70,12 @@ default void removeType(Repository repo, String type) { System.out.println("Did not remove " + type + ": Not found"); } - default void setReturnType(Repository repo, String type, String name, String typeName, String typeCType, String defaultReturnValue, String doc) { - setReturnType(findVirtualMethod(repo, type, name), typeName, typeCType, defaultReturnValue, doc); - setReturnType(findMethod(repo, type, name), typeName, typeCType, defaultReturnValue, doc); - } - - private void setReturnType(Method m, String typeName, String typeCType, String defaultReturnValue, String doc) { + default void setReturnType(Method m, String typeName, String typeCType, String defaultReturnValue, String doc) { if (m == null) { return; } ReturnValue rv = m.returnValue; - rv.type = new Type(rv, typeName, typeCType); + rv.overrideReturnType = new Type(rv, typeName, typeCType); rv.overrideReturnValue = defaultReturnValue; if (doc != null) { rv.doc = new Doc(rv, "1"); diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/model/GirElement.java b/buildSrc/src/main/java/io/github/jwharm/javagi/model/GirElement.java index 58938872..2d2a0a5e 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/model/GirElement.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/model/GirElement.java @@ -74,6 +74,10 @@ public GirElement(GirElement parent) { previouslyCreated = this; } + public Type getType() { + return this.type; + } + public Namespace getNamespace() { if (this instanceof Repository r) { return r.namespace; diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/model/Method.java b/buildSrc/src/main/java/io/github/jwharm/javagi/model/Method.java index ccd6bbdb..d0e44301 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/model/Method.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/model/Method.java @@ -91,7 +91,7 @@ public String getMethodDeclaration() { if (this instanceof Constructor) { writer.write("MemorySegment"); } else { - getReturnValue().writeType(writer, true); + getReturnValueOverride().writeType(writer, true); } // Method name @@ -168,6 +168,8 @@ public void generate(SourceWriter writer) throws IOException { return; } + ReturnValue returnValue = getReturnValueOverride(); + writer.write("\n"); // Documentation @@ -193,11 +195,6 @@ public void generate(SourceWriter writer) throws IOException { // Check for unsupported platforms generatePlatformCheck(writer); - // FunctionDescriptor of the native function signature - writer.write("FunctionDescriptor _fdesc = "); - boolean varargs = generateFunctionDescriptor(writer); - writer.write(";\n"); - // Generate try-with-resources? boolean hasScope = allocatesMemory(); if (hasScope) { @@ -216,8 +213,8 @@ public void generate(SourceWriter writer) throws IOException { } // Variable declaration for return value - String carrierType = Conversions.getCarrierType(getReturnValue().type); - if (! (returnValue.type != null && returnValue.type.isVoid())) { + String carrierType = returnValue.getCarrierType(); + if (! returnValue.isVoid()) { writer.write(carrierType + " _result;\n"); } @@ -239,13 +236,18 @@ public void generate(SourceWriter writer) throws IOException { writer.increaseIndent(); } + // FunctionDescriptor of the native function signature + writer.write("FunctionDescriptor _fdesc = "); + boolean varargs = generateFunctionDescriptor(writer); + writer.write(";\n"); + // Log the method call log(cIdentifier, writer); // Generate the return type - if (! (returnValue.type != null && returnValue.type.isVoid())) { + if (! (getReturnValue().type != null && getReturnValue().type.isVoid())) { writer.write("_result = ("); - writer.write(carrierType); + writer.write(Conversions.getCarrierType(getReturnValue().type)); writer.write(") "); } @@ -258,6 +260,11 @@ public void generate(SourceWriter writer) throws IOException { } writer.write(");\n"); + // Set default return value (if applicable) + if (getReturnValue().overrideReturnValue != null) { + writer.write("_result = " + getReturnValue().overrideReturnValue + ";\n"); + } + // End of if/else block for virtual/named method call if (linkedVirtualMethod != null) { writer.decreaseIndent(); @@ -330,6 +337,16 @@ public ReturnValue getReturnValue() { return returnValue; } + private ReturnValue getReturnValueOverride() { + if (linkedVirtualMethod != null) { + if (returnValue.getType() != null && returnValue.isVoid() + && linkedVirtualMethod.returnValue.getType() != null) { + return linkedVirtualMethod.returnValue; + } + } + return returnValue; + } + @Override public void setReturnValue(ReturnValue rv) { this.returnValue = rv; diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/model/ReturnValue.java b/buildSrc/src/main/java/io/github/jwharm/javagi/model/ReturnValue.java index ed0988e3..50b74244 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/model/ReturnValue.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/model/ReturnValue.java @@ -27,6 +27,7 @@ public class ReturnValue extends Parameter { public boolean returnsFloatingReference; + public Type overrideReturnType; public String overrideReturnValue; public ReturnValue(GirElement parent, String transferOwnership, String nullable, String scope) { @@ -34,6 +35,7 @@ public ReturnValue(GirElement parent, String transferOwnership, String nullable, null, null, null, null, null, null, scope); returnsFloatingReference = false; + overrideReturnType = null; overrideReturnValue = null; } @@ -85,16 +87,11 @@ public void generate(SourceWriter writer) throws IOException { * @throws IOException Thrown when an error occurs while writing */ public void generateReturnStatement(SourceWriter writer) throws IOException { + Type type = overrideReturnType == null ? this.type : overrideReturnType; if (type != null && type.isVoid()) { return; } - // Return value hard-coded in PatchSet? - if (overrideReturnValue != null) { - writer.write("return " + overrideReturnValue + ";\n"); - return; - } - // When transfer-ownership="none", we must take a reference if (isGObject() && "none".equals(transferOwnership) && (! parent.name.equals("ref"))) { @@ -142,4 +139,21 @@ public void generateReturnStatement(SourceWriter writer) throws IOException { writer.write(";\n"); } } + + @Override + public Type getType() { + return overrideReturnType != null ? overrideReturnType : super.getType(); + } + + public boolean isVoid() { + if (overrideReturnType != null) + return (overrideReturnType.isVoid()); + return (type != null && type.isVoid()); + } + + public String getCarrierType() { + if (overrideReturnType != null) + return Conversions.getCarrierType(overrideReturnType); + return Conversions.getCarrierType(type); + } } diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/model/Variable.java b/buildSrc/src/main/java/io/github/jwharm/javagi/model/Variable.java index d9994e98..0b833d8d 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/model/Variable.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/model/Variable.java @@ -80,6 +80,7 @@ private String getAnnotations(Type type, boolean writeAnnotations) { } private String getType(boolean writeAnnotations) { + Type type = getType(); if (type != null && type.isActuallyAnArray()) return getAnnotations(type, writeAnnotations) + getType(type) + "[]"; @@ -205,6 +206,8 @@ private String marshalJavaArrayToNative(Array array, String identifier) { } private String marshalNativeToJava(String identifier, boolean upcall) { + Type type = getType(); + if (type != null && type.cType != null && type.cType.equals("gfloat**")) return "null /* unsupported */"; diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/model/VirtualMethod.java b/buildSrc/src/main/java/io/github/jwharm/javagi/model/VirtualMethod.java index 47285137..fe1a5b8a 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/model/VirtualMethod.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/model/VirtualMethod.java @@ -76,14 +76,10 @@ public void generate(SourceWriter writer) throws IOException { writer.write("MemorySegment _gerror = _arena.allocate(ValueLayout.ADDRESS);\n"); } - // Function descriptor - writer.write("FunctionDescriptor _fdesc = "); - generateFunctionDescriptor(writer); - writer.write(";\n"); - // Variable declaration for return value - String carrierType = Conversions.getCarrierType(getReturnValue().type); - if (! (returnValue.type != null && returnValue.type.isVoid())) { + // Variable declaration for return value + String carrierType = returnValue.getCarrierType(); + if (! returnValue.isVoid()) { writer.write(carrierType + " _result;\n"); } @@ -127,6 +123,13 @@ public void generate(SourceWriter writer) throws IOException { public void generateInvocation(SourceWriter writer) throws IOException { Record classStruct = null; String className = null; + + // FunctionDescriptor of the native function signature + writer.write("FunctionDescriptor _fdesc = "); + boolean varargs = generateFunctionDescriptor(writer); + writer.write(";\n"); + + // Lookup the function table if (parent instanceof Class c) { classStruct = c.classStruct; className = c.javaName; @@ -137,6 +140,7 @@ public void generateInvocation(SourceWriter writer) throws IOException { if (classStruct == null) { throw new IOException("Cannot find typestruct for " + parent.name); } + writer.write("MemorySegment _func = Overrides.lookupVirtualMethodParent(handle(), " + classStruct.javaName + ".getMemoryLayout(), \"" + name + "\""); if (parent instanceof Interface) { writer.write(", " + className + ".getType()"); @@ -167,5 +171,10 @@ public void generateInvocation(SourceWriter writer) throws IOException { parameters.marshalJavaToNative(writer, throws_); } writer.write(");\n"); + + // Set default return value (if applicable) + if (returnValue.overrideReturnValue != null) { + writer.write("_result = " + returnValue.overrideReturnValue + ";\n"); + } } } diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/patches/GioPatch.java b/buildSrc/src/main/java/io/github/jwharm/javagi/patches/GioPatch.java index f2c800a0..248a443f 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/patches/GioPatch.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/patches/GioPatch.java @@ -16,8 +16,6 @@ public void patch(Repository repo) { renameMethod(repo, "BufferedInputStream", "read_byte", "read_int"); renameMethod(repo, "IOModule", "load", "load_module"); - setReturnType(repo, "ActionGroup", "activate_action", "gboolean", "gboolean", "true", "always %TRUE"); - // Override of static method removeVirtualMethod(repo, "SocketControlMessage", "get_type"); diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/patches/GstAudioPatch.java b/buildSrc/src/main/java/io/github/jwharm/javagi/patches/GstAudioPatch.java index e2feb4ef..613b1d48 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/patches/GstAudioPatch.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/patches/GstAudioPatch.java @@ -9,8 +9,8 @@ public class GstAudioPatch implements Patch { @Override public void patch(Repository repo) { - // Override with different return type - setReturnType(repo, "AudioSink", "stop", "gboolean", "gboolean", "true", "always %TRUE"); + // Override with different return type (BaseSink.stop() returns boolean) + setReturnType(findVirtualMethod(repo, "AudioSink", "stop"), "gboolean", "gboolean", "1", "always %TRUE"); // A GstFraction cannot automatically be put into a GValue removeProperty(repo, "AudioAggregator", "output-buffer-duration-fraction"); diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/patches/GstVideoPatch.java b/buildSrc/src/main/java/io/github/jwharm/javagi/patches/GstVideoPatch.java index b5bccc98..c0dbfec8 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/patches/GstVideoPatch.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/patches/GstVideoPatch.java @@ -7,6 +7,6 @@ public class GstVideoPatch implements Patch { @Override public void patch(Repository repo) { - setReturnType(repo, "VideoOverlay", "set_render_rectangle", "none", "void", null, null); + setReturnType(findVirtualMethod(repo, "VideoOverlay", "set_render_rectangle"), "gboolean", "gboolean", "1", null); } } diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/patches/GtkPatch.java b/buildSrc/src/main/java/io/github/jwharm/javagi/patches/GtkPatch.java index 1b2ad2a1..6cbd09bf 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/patches/GtkPatch.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/patches/GtkPatch.java @@ -15,8 +15,9 @@ public void patch(Repository repo) { if (repo.module.platform != Platform.WINDOWS) renameMethod(repo, "PrintUnixDialog", "get_settings", "get_print_settings"); renameMethod(repo, "Widget", "activate", "activate_widget"); + renameMethod(repo, "Widget", "activate_action", "activate_action_if_exists"); - setReturnType(repo, "MediaStream", "play", "none", "void", null, null); + setReturnType(findMethod(repo, "MediaStream", "play"), "gboolean", "gboolean", "1", null); // These calls return floating references setReturnFloating(findMethod(repo, "FileFilter", "to_gvariant")); diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/patches/SoupPatch.java b/buildSrc/src/main/java/io/github/jwharm/javagi/patches/SoupPatch.java index 741d90d2..c2caa765 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/patches/SoupPatch.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/patches/SoupPatch.java @@ -7,6 +7,6 @@ public class SoupPatch implements Patch { @Override public void patch(Repository repo) { - setReturnType(repo, "AuthDomain", "challenge", "none", "void", null, null); + setReturnType(findMethod(repo, "AuthDomain", "challenge"), "utf8", "char*", "null", "Always {@code null}"); } }