Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return type overrides #81

Merged
merged 2 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ dependencies {
}

group = 'io.github.jwharm.javagi'
version = '0.8.0'
version = '0.8.1-SNAPSHOT'

java {
if (! System.getenv('CI')) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
37 changes: 27 additions & 10 deletions buildSrc/src/main/java/io/github/jwharm/javagi/model/Method.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -168,6 +168,8 @@ public void generate(SourceWriter writer) throws IOException {
return;
}

ReturnValue returnValue = getReturnValueOverride();

writer.write("\n");

// Documentation
Expand All @@ -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) {
Expand All @@ -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");
}

Expand All @@ -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(") ");
}

Expand All @@ -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();
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@
public class ReturnValue extends Parameter {

public boolean returnsFloatingReference;
public Type overrideReturnType;
public String overrideReturnValue;

public ReturnValue(GirElement parent, String transferOwnership, String nullable, String scope) {
super(parent, null, transferOwnership, nullable,
null, null, null, null, null, null, scope);

returnsFloatingReference = false;
overrideReturnType = null;
overrideReturnValue = null;
}

Expand Down Expand Up @@ -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"))) {

Expand Down Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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) + "[]";
Expand Down Expand Up @@ -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 */";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}

Expand Down Expand Up @@ -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;
Expand All @@ -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()");
Expand Down Expand Up @@ -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");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}");
}
}