Skip to content

Commit

Permalink
Merge pull request #79 from jwharm/virtual-methods
Browse files Browse the repository at this point in the history
Improve virtual methods
  • Loading branch information
jwharm authored Nov 8, 2023
2 parents 578ff70 + 2766e49 commit a62ec30
Show file tree
Hide file tree
Showing 31 changed files with 410 additions and 202 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ public abstract class GenerateSources extends DefaultTask {
void execute() {
try {
Module linux = parse(Platform.LINUX, getInputDirectory().get(), getGirFile().get(),
getUrlPrefix().getOrElse(null), getPatch().getOrElse(null));
getUrlPrefix().getOrNull(), getPatch().getOrNull());
Module windows = parse(Platform.WINDOWS, getInputDirectory().get(), getGirFile().get(),
getUrlPrefix().getOrElse(null), getPatch().getOrElse(null));
getUrlPrefix().getOrNull(), getPatch().getOrNull());
Module macos = parse(Platform.MACOS, getInputDirectory().get(), getGirFile().get(),
getUrlPrefix().getOrElse(null), getPatch().getOrElse(null));
getUrlPrefix().getOrNull(), getPatch().getOrNull());

Module module = new Merge().merge(linux, windows, macos);

Expand Down Expand Up @@ -109,6 +109,9 @@ private static Module parse(Platform platform, Directory sourceDirectory, String
// Flag unsupported va_list methods so they will not be generated
module.flagVaListFunctions();

// Link the type references to the GIR type definition across the GI repositories
module.link();

// Apply patch
if (patch != null) {
patch.patch(r);
Expand All @@ -118,9 +121,6 @@ private static Module parse(Platform platform, Directory sourceDirectory, String
// Gir file not found for this platform: This will generate code with UnsupportedPlatformExceptions
}

// Link the type references to the GIR type definition across the GI repositories
module.link();

return module;
}

Expand Down
24 changes: 12 additions & 12 deletions buildSrc/src/main/java/io/github/jwharm/javagi/generator/Merge.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,10 @@ private void mergeMethods(GirElement multi, List<? extends GirElement> registere
* @param methods the list of methods to add
*/
private <T extends Method> void mergeMethods(GirElement parent, List<T> multi, List<T> methods) {
Set<String> signatures = new HashSet<>(multi.stream().map(Method::getMethodSpecification).toList());
Set<String> signatures = new HashSet<>(multi.stream().map(Method::getNameAndSignature).toList());
Set<String> cIdentifiers = new HashSet<>(multi.stream().map(method -> method.cIdentifier).toList());
for (T method : methods) {
var signature = method.getMethodSpecification();
var signature = method.getNameAndSignature();
var cIdentifier = method.cIdentifier;
if (cIdentifier != null && cIdentifiers.contains(cIdentifier)) {
continue;
Expand All @@ -237,21 +237,21 @@ private <T extends Method> void mergeMethods(GirElement parent, List<T> multi, L
*/
private void setMethodPlatforms(List<? extends Method> methods, List<? extends GirElement> registeredTypes) {
for (Method method : methods) {
String signature = method.getMethodSpecification();
String signature = method.getNameAndSignature();
for (var rt : registeredTypes) {
if (rt == null) {
continue;
}
if (rt.methodList.stream().map(Method::getMethodSpecification).anyMatch(signature::equals)) {
if (rt.methodList.stream().map(Method::getNameAndSignature).anyMatch(signature::equals)) {
method.platforms.add(rt.module().platform);
}
if (rt.virtualMethodList.stream().map(Method::getMethodSpecification).anyMatch(signature::equals)) {
if (rt.virtualMethodList.stream().map(Method::getNameAndSignature).anyMatch(signature::equals)) {
method.platforms.add(rt.module().platform);
}
if (rt.functionList.stream().map(Method::getMethodSpecification).anyMatch(signature::equals)) {
if (rt.functionList.stream().map(Method::getNameAndSignature).anyMatch(signature::equals)) {
method.platforms.add(rt.module().platform);
}
if (rt.constructorList.stream().map(Method::getMethodSpecification).anyMatch(signature::equals)) {
if (rt.constructorList.stream().map(Method::getNameAndSignature).anyMatch(signature::equals)) {
method.platforms.add(rt.module().platform);
}
}
Expand All @@ -265,32 +265,32 @@ private void setMethodPlatforms(List<? extends Method> methods, List<? extends G
*/
private void overrideLongValues(List<? extends Method> methods, List<? extends GirElement> registeredTypes) {
for (Method method : methods) {
String signature = method.getMethodSpecification();
String signature = method.getNameAndSignature();
for (var rt : registeredTypes) {
if (rt == null) {
continue;
}
// Check if this method exists on Windows
if (rt.methodList.stream().map(Method::getMethodSpecification).anyMatch(signature::equals)) {
if (rt.methodList.stream().map(Method::getNameAndSignature).anyMatch(signature::equals)) {
if (rt.module().platform == Platform.WINDOWS) {
// Convert glong/gulong parameters to gint/guint
overrideLongValues(method);
}
}
// Same for virtual methods
if (rt.virtualMethodList.stream().map(Method::getMethodSpecification).anyMatch(signature::equals)) {
if (rt.virtualMethodList.stream().map(Method::getNameAndSignature).anyMatch(signature::equals)) {
if (rt.module().platform == Platform.WINDOWS) {
overrideLongValues(method);
}
}
// Same for functions (static methods)
if (rt.functionList.stream().map(Method::getMethodSpecification).anyMatch(signature::equals)) {
if (rt.functionList.stream().map(Method::getNameAndSignature).anyMatch(signature::equals)) {
if (rt.module().platform == Platform.WINDOWS) {
overrideLongValues(method);
}
}
// Same for constructors
if (rt.constructorList.stream().map(Method::getMethodSpecification).anyMatch(signature::equals)) {
if (rt.constructorList.stream().map(Method::getNameAndSignature).anyMatch(signature::equals)) {
if (rt.module().platform == Platform.WINDOWS) {
overrideLongValues(method);
}
Expand Down
44 changes: 31 additions & 13 deletions buildSrc/src/main/java/io/github/jwharm/javagi/generator/Patch.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,19 +71,21 @@ default void removeType(Repository repo, String type) {
}

default void setReturnType(Repository repo, String type, String name, String typeName, String typeCType, String defaultReturnValue, String doc) {
Method m = findVirtualMethod(repo, type, name);
if (m == null)
m = findMethod(repo, type, name);
if (m != null) {
ReturnValue rv = m.returnValue;
rv.type = new Type(rv, typeName, typeCType);
rv.overrideReturnValue = defaultReturnValue;
if (doc != null) {
rv.doc = new Doc(rv, "1");
rv.doc.contents = doc;
}
} else
System.out.println("Did not change return type of " + type + "." + name + ": Not found");
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) {
if (m == null) {
return;
}
ReturnValue rv = m.returnValue;
rv.type = new Type(rv, typeName, typeCType);
rv.overrideReturnValue = defaultReturnValue;
if (doc != null) {
rv.doc = new Doc(rv, "1");
rv.doc.contents = doc;
}
}

default void setReturnFloating(CallableType ct) {
Expand Down Expand Up @@ -177,6 +179,20 @@ default void removeEnumMember(Repository repo, String type, String member) {
else e.memberList.remove(found);
}

default void addInstanceMethod(Repository repo, String type, String virtualMethod) {
var vm = findVirtualMethod(repo, type, virtualMethod);
if (vm == null) {
return;
}
var method = new Method(vm.parent, vm.name, vm.cIdentifier, vm.deprecated, vm.throws_, vm.shadowedBy, vm.shadows, vm.movedTo);
method.doc = vm.doc;
method.docDeprecated = vm.docDeprecated;
method.parameters = vm.parameters;
method.returnValue = vm.returnValue;
vm.parent.methodList.add(method);
vm.skip = true;
}

default void makeGeneric(Repository repo, String type) {
RegisteredType inst = repo.namespace.registeredTypeMap.get(type);
if (inst != null) {
Expand All @@ -186,13 +202,15 @@ default void makeGeneric(Repository repo, String type) {
for (Parameter p : m.parameters.parameterList) {
if (p.type != null && "org.gnome.gobject.GObject".equals(p.type.qualifiedJavaType)) {
p.type.isGeneric = true;
p.type.init(p.type.name);
}
}
}
if (m.returnValue != null) {
Type returnType = m.returnValue.type;
if (returnType != null && "org.gnome.gobject.GObject".equals(returnType.qualifiedJavaType)) {
returnType.isGeneric = true;
returnType.init(returnType.name);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

public interface CallableType {

GirElement getParent();

Parameters getParameters();
void setParameters(Parameters ps);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ public String getInteropString(String paramName, boolean isPointer, Scope scope)
return "%s.toCallback(%s)".formatted(paramName, arena);
}

@Override
public GirElement getParent() {
return parent;
}

@Override
public Parameters getParameters() {
return parameters;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ protected void generateParentAccessor(SourceWriter writer) throws IOException {
writer.write(" * again. To chain up, call {@code asParent().methodName()}. This will call the native function\n");
writer.write(" * pointer of this virtual method in the typeclass of the parent type.\n");
writer.write(" */\n");
writer.write("public " + qualifiedName + " asParent() {\n");
writer.write("protected " + qualifiedName + " asParent() {\n");
writer.increaseIndent();
if ("1".equals(abstract_)) {
writer.write(qualifiedName + " _parent = new " + qualifiedName + "." + javaName + "Impl(handle());\n");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,18 @@ default void generateFunctionalInterface(SourceWriter writer, String javaName) t
writer.write(" */\n");
}
writer.write("@FunctionalInterface\n");
writer.write("public interface " + javaName + " {\n");
if (! (getParent() instanceof Interface)) {
writer.write("public ");
}
writer.write("interface " + javaName + " {\n");
writer.write("\n");
writer.increaseIndent();

// Generate javadoc for run(...)
Doc doc = getDoc();
if (doc != null)
if (doc != null) {
doc.generate(writer, false);
}

// Deprecation
if ("1".equals(((GirElement) this).deprecated)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,15 @@ public class Constructor extends Method {

public Constructor(GirElement parent, String name, String cIdentifier, String deprecated, String throws_) {
super(parent, name, cIdentifier, deprecated, throws_, null, null, null);
// constructor helper method has private visibility
visibility = "private";
}

public void generate(SourceWriter writer) throws IOException {
if (skip) {
return;
}

String privateMethodName = "construct" + Conversions.toCamelCase(name, true);
writer.write("\n");

Expand Down Expand Up @@ -83,6 +89,10 @@ public void generate(SourceWriter writer) throws IOException {
}

public void generateNamed(SourceWriter writer) throws IOException {
if (skip) {
return;
}

String privateMethodName = "construct" + Conversions.toCamelCase(name, true);
RegisteredType constructed = (RegisteredType) parent;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ public class Function extends Method {

public Function(GirElement parent, String name, String cIdentifier, String deprecated, String throws_, String movedTo) {
super(parent, name, cIdentifier, deprecated, throws_, null, null, movedTo);
visibility = parent instanceof Interface ? "" : "public";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ public FunctionMacro(GirElement parent, String name, String cIdentifier, String
this.throws_ = throws_;
}

@Override
public GirElement getParent() {
return parent;
}

@Override
public Parameters getParameters() {
return parameters;
Expand Down
Loading

0 comments on commit a62ec30

Please sign in to comment.