groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jochen Theodorou <blackd...@gmx.org>
Subject Re: Advice on compiler bug workaround
Date Sat, 20 Feb 2016 15:35:32 GMT
On 20.02.2016 13:19, Ralph Johnson wrote:
[...]
> One file has dozens of errors, all of the form "Unexpected
> MOP methods in the class node for
> com.metaficient.xxx.YYY(super$2$toString)" where the xxx.YYY is always a
> different class in the web app (not in the much bigger library), the
> number 2 is usually a different small integer, and "toString" is often
> "toString" but often a different method name, like "getStaticMetaClass",
> "setReadOnly", or "addItem".  The other file has just one error,
> "internal compiler error".

first an explanation what super$2$toString means and what it was/is used 
for. Groovy needs to invoke methods, but prior to invokedynamic there is 
no means of invoking a method from outside, you have overridden and 
where you want to invoke the overriden version.

Example, you make a class extending Object, in which you overwrite 
toString() and in there you call super.toString() to get the object 
variant. Would we use reflection to simulate the toSring call we would 
end up in a stack overflow error, since we would not be able to call 
Object#toString, and would always end up calling our new toString. This 
is why we have those super$X$M methods, where X should be the "distance" 
to Object, and M stands for the method. These methods do a special 
invocation just like the JVM would do using the invokespecial bytecode 
(such an invocation is normally only legal in the same class hierarchy). 
In our example you would get something like super$1$toString() then.

This logic has one important drawback, if you add or remove an ancestor, 
you get into trouble.So in Java if you have A extends B, you can easily 
make a change in which B will then extend C, without having to recompile 
A in many cases. In Groovy this will not work, since it now can happen, 
that the call to such a super method will call the wrong method in the 
hierarchy.

Now imagine A extends B extends C extends D, and you remove C. removing 
B would require recompilation in Java as well, but in Groovy removing C 
will require you recompiling A as well.

Now.. how do we get to "Unexpected MOP methods"? Most likely it means 
the hierarchy changed by the removal or addition of a class and you did 
not yet recompile all needed classes. Remember, in a case of A extends B 
extends C extends D, removing D will require the compilation of C in 
Java and Groovy, but in Groovy also of A and B. And if you don't 
recompile them together, you need first to recompile C, then B and then 
A. Since you do not compile using a build tool it seems, it is possible, 
that Eclipse tries to compile in the wrong order here... especially if 
the Java rules are applied only.

>  The other file has just one error, "internal compiler error".

that sounds like a bug in the compiler

> Another state is where it tells me it can't build the library and so
> can't build the apps.  But then it doesn't tell me anything about why it
> can't build the library.

Without error message I cannot do much... but I do advice using a build 
tool outside of the IDE. You would get an error message there.

> The system was working in the morning, and then it broke.  I know which
> class I was editing, so I can go back to an earlier version if
> necessary. However, the code was boring.

Well, what kind of change did you do?

bye Jochen

Mime
View raw message