MOE Community Edition Gradle Plugin & SDK 1.7.2

Not everything can work due to how Java’s generic work. For example, I cannot make alloc() generic (i.e. public static native <T> NSArray<T> alloc()) because then this will clash with the alloc() in NSObject:


Java requires the static method in chile class that has the same signature as the superclass to also have the same number of generic type peremeters, otherwise it cannot determine which method to invoke.


As for this one:

You have a misunderstandment here. The type parameter of NSArray is marked as __covariant, which means it should ALWAYS be used as NSArray<? extends SomeType> in Java. By marking the type parameter as __covariant, it allows you do things like

NSArray<UIView*> *viewArray = [[NSArray alloc] init];
NSArray<NSObject*> *objArray = viewArray;

the equivalence in Java is:

class A { }
class B extends A { }

List<? extends B> subList = new ArrayList<>();
List<? extends A> supList = subList; // <- this is fine

List<B> bList = new ArrayList<>();
List<A> aList = bList; // Error: java: incompatible types: List<B> cannot be converted to List<A>

This is also the reason of ALL binding methods that take NSArray as parameter always declare the typs as NSArray<? extends SomeType> (with the only exception of NSArray due to how NSString is specially handled by MOE).

However in this case, it might be good enought to make the return type simply not wildcarded, e.g.

public static native NSArray<NSLayoutConstraint> constraintsWithVisualFormatOptionsMetricsViews(
        String format, @NUInt long opts, NSDictionary<String, ?> metrics, NSDictionary<String, ?> views);

because this __covariant thing only matters when you try to assign a value, so as long as the api parameter contains the correct wildcard then it should be perfectly fine, since this is perfectly valid:

List<B> bList = new ArrayList<>();
List<? extends A> aList = bList;

which means when calling an Objective-C method, the __covariant is still honored, and you don’t need to deal with the cast in most of the cases.

The reason of not using <T extends SomeType> NSArray<T> method(); is because this is totally wrong, because the original return type NSArray<? extends SomeType> means the returned array could contain object of type SomeType, but if you set T to a subtype, then when you get the item from the array, you will have a cast error.


For the type issue of the varargs, I’m currently looking at it. Should be fixable.