Description
I was doing a bit of code cleanup and removing "duplicate" implement calls and noticed that ZC stopped recognizing that one of my native classes implements a different native interface due to not doing any flattening of implemented interfaces. A basic setup class structure wise that fails to find that A implements C
is as follows:
public class A implements B {
}
public interface B extends C {
}
public interface C {
}
I am fairly certain this is due to how implemented interfaces are collected here, as Class#getAnnotatedInterfaces
only gets directly declared interfaces. I did some basic testing (outside of ZC/CrT so I haven't yet validated this actually fixes the issue I ran into but I am fairly certain it does) and I believe adjusting fillImplementedInterfaces
to behave like:
private void fillImplementedInterfaces(Class<?> cls, HighLevelDefinition definition, JavaClass javaClass) {
Set<AnnotatedType> interfaces = new LinkedHashSet<>();
addAllAnnotatedInterfaces(interfaces, cls);
for (AnnotatedType iface : interfaces) {
if (shouldLoadType(iface.getType())) {
TypeID type = typeConverter.loadType(typeConversionContext.context, iface);
ImplementationMember member = new ImplementationMember(CodePosition.NATIVE, definition, Modifiers.PUBLIC, type);
definition.members.add(member);
typeConversionContext.compiled.setImplementationInfo(member, new JavaImplementation(true, javaClass));
}
}
}
private void addAllAnnotatedInterfaces(Set<AnnotatedType> interfaces, Class<?> cls) {
for (AnnotatedType iface : cls.getAnnotatedInterfaces()) {
interfaces.add(iface);
Type type = iface.getType();
while (type instanceof ParameterizedType) {
type = ((ParameterizedType) type).getRawType();
}
if (type instanceof Class) {
addAllAnnotatedInterfaces(interfaces, (Class<?>) type);
}
}
}
Will properly get all parent interfaces, except I am unsure how shouldLoadType
behaves and whether this will cause issues in cases where B
is registered to ZC so it knows about A
, B
, and C
and not just A
and C
, as I feel like this may cause it to have C
effectively be registered as both B
and C
, though that might happen already if the implementations are manually declared?