Skip to content

Commit

Permalink
Make types that inherit from a generic base type also generic
Browse files Browse the repository at this point in the history
  • Loading branch information
jwharm committed Jul 16, 2024
1 parent e463d9b commit 701e0cf
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public final class ClassNames {
public static final ClassName PLATFORM = get(PKG_INTEROP, "Platform");

public static final ClassName AUTO_CLOSEABLE = get(PKG_GIO, "AutoCloseable");
public static final ClassName LIST_MODEL_LIST = get(PKG_GIO, "ListModelList");
public static final ClassName LIST_MODEL_JAVA_LIST = get(PKG_GIO, "ListModelJavaList");

public static final ClassName BUILDER = get(PKG_GOBJECT, "Builder");
public static final ClassName BUILDER_INTERFACE = get(PKG_GOBJECT, "BuilderInterface");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ public TypeSpec generate() {

Class parentClass = cls.parentClass();
if (parentClass != null)
builder.superclass(parentClass.typeName());
builder.superclass(parentClass.generic()
? ParameterizedTypeName.get(parentClass.typeName(),
ClassNames.GENERIC_T)
: parentClass.typeName());
else
builder.superclass(ClassNames.TYPE_INSTANCE);

Expand All @@ -66,7 +69,7 @@ public TypeSpec generate() {
if (impl.get() instanceof Interface iface)
builder.addSuperinterface(iface.generic()
? ParameterizedTypeName.get(iface.typeName(),
ClassNames.GOBJECT)
ClassNames.GENERIC_T)
: iface.typeName());

if (cls.autoCloseable())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ public TypeSpec generate() {
if (prereq.get() instanceof Interface iface)
builder.addSuperinterface(iface.generic()
? ParameterizedTypeName.get(iface.typeName(),
ClassNames.GOBJECT)
ClassNames.GENERIC_T)
: iface.typeName());

if ("GListModel".equals(inf.cType()))
if (inf.listInterface())
builder.addSuperinterface(
ParameterizedTypeName.get(ClassNames.LIST_MODEL_LIST,
ParameterizedTypeName.get(ClassNames.LIST_MODEL_JAVA_LIST,
ClassNames.GENERIC_T));

if (inf.generic())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,8 @@ public static String getName(Callable func) {
}

public static boolean isGeneric(Callable func) {
return switch(func.parent()) {
case Class c -> c.generic();
case Interface i -> i.generic();
case Record r -> r.generic();
default -> false;
};
return func.parent() instanceof RegisteredType rt
&& rt.generic();
}

public MethodGenerator(Callable func, String name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,23 +146,24 @@ protected TypeSpec implClass() {
TypeSpec.Builder spec = TypeSpec.classBuilder(nested)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC);

if (rt instanceof Interface i) {
TypeName superInterface = i.generic()
TypeName base = rt.generic()
? ParameterizedTypeName.get(rt.typeName(), ClassNames.GOBJECT)
: rt.typeName();

if (rt instanceof Interface i) {
spec.addJavadoc("The $T type represents a native instance of the $T interface.",
nested,
rt.typeName())
.superclass(getInterfaceSuperclass(i))
.addSuperinterface(superInterface)
.addSuperinterface(base)
.addStaticBlock(staticBlock());
}

if (rt instanceof Class)
spec.addJavadoc("The $T type represents a native instance of the abstract $T class.",
nested,
rt.typeName())
.superclass(rt.typeName());
.superclass(base);

return spec.addMethod(MethodSpec.constructorBuilder()
.addJavadoc("""
Expand All @@ -178,11 +179,12 @@ protected TypeSpec implClass() {
}

private TypeName getInterfaceSuperclass(Interface i) {
for (var prerequisite : i.prerequisites()) {
var target = prerequisite.get();
if (target instanceof Class)
return target.typeName();
}
for (var prerequisite : i.prerequisites())
if (prerequisite.get() instanceof Class c)
return c.generic()
? ParameterizedTypeName.get(c.typeName(),
ClassNames.GOBJECT)
: c.typeName();
return ClassNames.GOBJECT;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,14 @@ public RegisteredType mergeWith(RegisteredType rt) {
}

public boolean generic() {
return attrBool("java-gi-generic", false);
if (attrBool("java-gi-generic", false))
return true;

for (var impl : implements_())
if (impl.get().generic())
return true;

return false;
}

public boolean autoCloseable() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,14 @@ public Interface mergeWith(RegisteredType rt) {
}

public boolean generic() {
return attrBool("java-gi-generic", false);
if (attrBool("java-gi-generic", false))
return true;

for (var prereq : prerequisites())
if (prereq.get() instanceof Interface i && i.generic())
return true;

return false;
}

@Override
Expand All @@ -79,6 +86,10 @@ public boolean hasProperties() {
return children().stream().anyMatch(Property.class::isInstance);
}

public boolean listInterface() {
return attrBool("java-gi-list-interface", false);
}

public List<Prerequisite> prerequisites() {
return filter(children(), Prerequisite.class);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ public sealed interface RegisteredType
InfoAttrs infoAttrs();
InfoElements infoElements();

default boolean generic() {
return false;
}

default ClassName typeName() {
return toJavaQualifiedType(name(), namespace());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,11 @@ public GirElement patch(GirElement element, String namespace) {
* Make GListModel and GListStore generic (replacing all GObject
* arguments with generic type {@code <T extends GObject>}).
*/
if (element instanceof Interface i && "ListModel".equals(i.name())
|| element instanceof Class c && "ListStore".equals(c.name()))
if (element instanceof Interface i && "ListModel".equals(i.name()))
return element.withAttribute("java-gi-generic", "1")
.withAttribute("java-gi-list-interface", "1");

if (element instanceof Class c && "ListStore".equals(c.name()))
return element.withAttribute("java-gi-generic", "1");

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
*
* @param <E> The item type must be a GObject.
*/
public interface ListModelList<E extends GObject> extends List<E> {
public interface ListModelJavaList<E extends GObject> extends List<E> {

int getNItems();
E getItem(int position);
Expand Down Expand Up @@ -319,15 +319,15 @@ default List<E> subList(int fromIndex, int toIndex) {
if (fromIndex < 0 || toIndex > size() || fromIndex > toIndex)
throw new IndexOutOfBoundsException();

return new ListModelList<>() {
return new ListModelJavaList<>() {
@Override
public int getNItems() {
return toIndex - fromIndex;
}

@Override
public E getItem(int position) {
return ListModelList.this.getItem(position + fromIndex);
return ListModelJavaList.this.getItem(position + fromIndex);
}
};
}
Expand Down

0 comments on commit 701e0cf

Please sign in to comment.