Skip to content

Commit

Permalink
Compare parameter types for virtual methods and their invoker methods (
Browse files Browse the repository at this point in the history
…fixes #175)
  • Loading branch information
jwharm committed Jan 3, 2025
1 parent 167b6f2 commit fa6efa7
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public VirtualMethod invokerFor() {
.filter(VirtualMethod.class::isInstance)
.map(VirtualMethod.class::cast)
.filter(vm -> name().equals(vm.attr("invoker")))
.filter(vm -> vm.equalTypeSignature(this))
.findAny()
.orElse(null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,50 @@ public Method invoker() {
.filter(Method.class::isInstance)
.map(Method.class::cast)
.filter(m -> invoker.equals(m.name()))
.filter(this::equalTypeSignature)
.findAny()
.orElse(null);
}

public String overrideVisibility() {
return attr("java-gi-override-visibility");
}

/*
* Check if the invoker method has the same type signature as this virtual
* method.
*
* We deliberately don't compare the return types, because two Java methods
* with the same name and parameter types but different return types will
* not compile.
*/
boolean equalTypeSignature(Method m) {
// Compare instance parameter type
if (different(parameters().instanceParameter(),
m.parameters().instanceParameter()))
return false;

// Compare exceptions
if (throws_() != m.throws_())
return false;

List<Parameter> params1 = parameters().parameters();
List<Parameter> params2 = m.parameters().parameters();

// Compare number of parameters
if (params1.size() != params2.size())
return false;

// Compare parameter types
for (int i = 0; i < params1.size(); i++)
if (different(params1.get(i), params2.get(i)))
return false;

return true;
}

// Return true when these types would be different in Java
private boolean different(TypedValue a, TypedValue b) {
return !a.anyType().typeName().equals(b.anyType().typeName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -131,22 +131,6 @@ public GirElement patch(GirElement element, String namespace) {
return r;
}

/*
* GObject.notify() is defined as a virtual method with an invoker
* method, but the parameters are different. Remove the invoker
* attribute, so they will be treated as separate methods.
*/
if (element instanceof VirtualMethod vm
&& "notify".equals(vm.name())
&& "Object".equals(vm.parameters()
.instanceParameter()
.type().name()))
return new VirtualMethod(
Map.of("name", "notify"),
vm.children(),
vm.platforms()
);

/*
* Workaround for https://gitlab.gnome.org/GNOME/glib/-/issues/3524
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public GirElement patch(GirElement element, String namespace) {

/*
* File.prefixMatches() is defined as a virtual method with invoker
* method hasPrefix(), but the parameters are different. Remove the
* method hasPrefix(), but the parameters are swapped. Remove the
* invoker attribute, so they will be treated as separate methods.
*/
if (element instanceof VirtualMethod vm
Expand Down

0 comments on commit fa6efa7

Please sign in to comment.