Search code examples
javaeclipsextextxtend

Xtend compilation issues with static nested interfaces


I've been trying to solve this very strange bug for hours, and I simply can't figure it out.

I have the following code in its own Xtend source file in a project in Eclipse:

interface Apple {
    def void test() {}
    static interface Green extends Apple {
        override test() {
            Apple.super.test();
        }
    }
}

And for some reason I get a compiler error on the keyword "super" in the above code that says:

Java problem: No enclosing instance of the type Apple is accessible in scope

Upon inspecting the Java source code that Xtend produces, I see that it is creating the nested interface as non-static, as well as using the keyword "this" instead of "super", which would obviously cause this error.

Xtend output (reformatted):

public interface Apple {
    public default void test() {}
    public interface Green extends Apple {
        @Override
        public default void test() {
            Apple.this.test();
        }
    }
}

Why is the Xtend compiler doing this?

Perhaps the weirdest part is that the output of the compiler is inconsistent. When I rename the superinterface, the Java source code generated by Xtend changes semantically.

I'm using the Eclipse Xtend plugin for Xtend 2.9.0 with a source target of Java 8.

Edit: I should note, I am aware that the above code seems to be semantically pointless, and is obviously unnecessary given that the method is inherited. However, this is a simplified case of my actual, more practical, code.


Solution

  • it is creating the nested interface as non-static

    Nested interfaces are always static therefore the explicit static modifier you specified is redundant. (So the Xtend compiler is correct here.)

    using the keyword "this" instead of "super"

    I guess this is an Xtend compiler bug, the corresponding Java source is compiled and executed as expected:

    interface AppleJava {
        default void test() {
            System.out.println("AppleJava.test()");
        }
    
        interface GreenJava extends AppleJava {
            @Override
            default void test() {
                AppleJava.super.test();
                System.out.println("GreenJava.test()");
            }
        }
    }
    
    class Test1 {
        public static void main(String[] args) {
            new AppleJava() {}.test();
            new AppleJava.GreenJava() {}.test();
        }
    }
    

    Result:

    AppleJava.test()
    AppleJava.test()
    GreenJava.test()