jsweet
jsweet copied to clipboard
Iterable interface cannot be extended
This is a regression, as it was working in 2.3.7.
I suspect the default methods in Iterable are the issue, but it is just a guess.
Paste this code into the live sandbox to demonstrate the spurious compile error:
package org.jsweet;
import static def.dom.Globals.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
public class HelloWorld {
public static void main(String[] args) {
WrappedList list = new WrappedListImpl(); // WrappedList interface inherits the iterable method, and yet...
for( int num : list ) { // TSC fails with "property 'iterator' does not exist on type 'WrappedList'"
System.out.println( num );
}
}
}
public interface WrappedList extends Iterable<Integer> {
public void doSomething();
}
public class WrappedListImpl implements WrappedList {
private List<Integer> nums = new ArrayList<>();
public WrappedListImpl() {
this.nums.add( 3 );
this.nums.add( 5 );
this.nums.add( 8 );
}
public Iterator<Integer> iterator() {
return this.nums.iterator();
}
public void doSomething() {
}
}
It seems that the extends Iterable<Integer>
gets erased by design:
https://github.com/cincheo/jsweet/blob/ac8ef70abdd7665bb61fa82af53c09baa9c789f5/transpiler/src/main/java/org/jsweet/transpiler/Java2TypeScriptTranslator.java#L1722
I don't understand why this is designed in this way. Can someone explain? If the interface extension is erased, shouldn't its methods be inlined?
Standard JSweet behavior (without j4ts) is to remove java references and replace it with a JS implementation. Since Iterable is not a JS type, it won't appear at runtime.
What you see in the code you linked above is a call to an adapter, which allows to switch behavior when necessary, for instance if you need to keep some type in a specific project. By default, the RemoveJavaDependenciesAdapter
is used, but any implementation can be used.
Is it a problem that this super interface gets erased in TypeScript? I honestly doubt this is related to this issue?
I believe the error comes from the TypeScript compiler:
Line 11: property 'iterator' does not exist on type 'WrappedList'
If you look at the generated TypeScript, you can see that the problem is a TS source issue with the missing iterator()
method.
I'll take a look at RemoveJavaDependenciesAdapter
. It seems wrong to remove superinterfaces without inlining them, in general. I suspect many of my JSweet transpile errors are a result of this.
Yes, methods are supposed to be inlined indeed. This sounds like a bug.
You will find somewhere in the translator some code to handle inlining of default methods specifically.