Details
-
Bug
-
Status: Closed
-
Minor
-
Resolution: Fixed
-
1.8.3
-
None
Description
Possibly groovy is doing this by design, but I suspect not. When compiling this code:
class Outer { static class Inner { } }
groovy creates a public constructor for the Outer.Inner type (because it doesn't have one) but it marks it synthetic. Synthetic members cannot be called from user written code. So once compiled I can't write this java code:
class Foo { public void m() { new Outer.Inner(); } }
As it will complain the constructor isn't there (it is, but it is synthetic). Javac does not make these constructors synthetic, I can't think of a good reason why groovy should either
To fix it, change the InnerClassVisitor.visitClass method. Where it reads (line 73 for me):
innerClass.addConstructor(PUBLIC_SYNTHETIC, new Parameter[0], null, null);
change it to:
innerClass.addConstructor(ACC_PUBLIC, new Parameter[0], null, null);
This change appears to continue to pass all the tests.
Note you won't see the problem if you compile all the code together (both java and groovy) - I haven't looked but of course the stubs cannot indicate syntheticness before calling javac (and if the stubs contained no ctor in that inner type, it would get the javac behaviour of a non synthetic one). In eclipse the problem won't happen on a full build because default constructors are not marked synthetic by the conversion layer (between groovy and eclipse types). It can be seen on an incremental build in eclipse (of the java code) because it then uses the bytecode form of the groovy types to satisfy dependencies.