Eclipse save actions befuddled by Lombok

307 views
Skip to first unread message

Daniel Aborg

unread,
Aug 3, 2009, 9:44:47 AM8/3/09
to Project Lombok
Hi,

Very interested in the Lombok project, fantastic idea. Have been
experimenting with adding it to our project and ran into some fun
behaviour with Eclipse's save participants - thought I'd post a
message and see if you have any ideas.


I'm trying it out with this simple class:

@Data(staticConstructor="of")
public class Pair<S, T> {
private final S first;
private final T second;
}

The code that Lombok generates seems fine - but as soon as you edit
the file and try to save Eclipse throws a hissy fit about its save
actions going completely bonkers and dying spectacular and confused
little deaths.

In particular the 'Add final modifier to method parameters' save
action seems to be causing all kinds of problems, spuriously adding
and removing 'final' modifiers at the top of the file and then dying
with various exceptions. The two messages I've seen are:

* The save participant 'org.eclipse.jdt.ui.postsavelistener.cleanup'
caused an exception: org.eclipse.core.runtime.CoreException: The fix
'Add final' generated a null change.

* The save participant 'org.eclipse.jdt.ui.postsavelistener.cleanup'
caused an exception: org.eclipse.text.edits.MalformedTreeException:
Overlapping text edits


So obviously we can just disable that save action but I thought I'd
check if there's some way to sort the problem out first. Is this a
bug in Eclipse, or Lombok, or is this just the state of the nation
when using Lombok with Eclipse? Is there anything that can be done to
fix it? Should I raise an Eclipse bug?

Happy to make a contribution if I had an idea where to start looking.
My initial poking about indicates that @EqualsAndHashCode on its own
causes Eclipse to insert a 'final' modifier at the top of the file
whenever you save if you have 'Add final modifier to method
parameters' as a save action - which doesn't make much sense to me.
I'm assuming that the exceptions are caused by some combination of
further code generated by @Data and save actions stepping on each
others toes trying to change nonexisting source.

Any thoughts from more experienced Lombokers?

Cheers,

Daniel

Reinier Zwitserloot

unread,
Aug 3, 2009, 10:20:39 AM8/3/09
to Project Lombok
For eclipse to believe those methods exist, they have to be in the
tree, but unfortunately eclipse uses the same tree for refactors and
save actions. The problem is that the nodes generated by Lombok point
at bogus locations in the sourcefile; either "0" (top of file) or the
annotation. That's why eclipse is adding "final" in all the wrong
places.

Generated methods have a flag set; the only reasonable fix I can think
of is to patch more of eclipse's code, such as save actions, to skip
generated methods.

Daniel Aborg

unread,
Aug 3, 2009, 11:25:46 AM8/3/09
to Project Lombok
On Aug 3, 3:20 pm, Reinier Zwitserloot <reini...@gmail.com> wrote:
> Generated methods have a flag set; the only reasonable fix I can think
> of is to patch more of eclipse's code, such as save actions, to skip
> generated methods.

That's kind of what I expected, and it sounds like a good idea in
general - but is going to take quite some time to come through.

So here's a question - looking at it from another point of view, would
it be possible to modify the nodes that Lombok generates so they don't
trip Eclipse up? What I'm thinking is that Eclipse is upset about
method parameters not being final, so immediately I'm then wondering
if there's anything we can do with the code Lombok generates to stop
Eclipse from being upset about it.

Now, I don't really know enough about what Lombok does to be able to
reason properly about this so I'm sure my ignorance is going to shine
through a bit here, but it seems to me that if Eclipse has a way to
detect that parameters in the generated code are non-final, then
shouldn't we be able to generate the code so Eclipse sees the
parameters as final? Is the final modifier a flag that can be set on
the generated code? Or is it a case of Eclipse ending up with the
wrong defaults because there's just no data available about final
modifiers at that stage?

Cheers,

Daniel

Reinier Zwitserloot

unread,
Aug 3, 2009, 1:10:08 PM8/3/09
to Project Lombok
We can certainly make all method parameters final. It's invisible code
anyways, and it's probably technically more correct. I can't think of
any method lombok currently generates that changes any of its
parameters, and I can't think of any code cleanup action in eclipse
that REMOVES 'final' from parameters, so it should be completely
harmless.

You'll have to edit just about every Handle*.java file, both for
eclipse and javac (consistency between the two is important) though
the change is bordering on the trivial: On eclipse, you can check how
e.g. the HandleGetter.java code sets the 'public' flag on methods.
Setting flags on an Argument object is similar. (hint: binary-or the
"flags" field of a LocalDeclaration object with
ClassFileConstants.FINAL).

For javac, you'll have to take the JCVariableDecl object, and sets its
flags.modifiers field (flags = a tuple of a long with bits, along with
a list of annotations. final is not an annotation, so you want the
bits, which is flags.modifiers) with Flags.FINAL. That's really all
there should be to it.

I think we actually set the final flag on the 'final int PRIME = 31;'
local declaration for createHashCode() for both javac and eclipse,
actually. You can look at them to see how to do it. (They are VERY
similar to method arguments - "Argument" is a subclass of
"LocalDeclaration" in eclipse, and on javac, they are BOTH represented
by JCVariableDecl objects!)

I'll gladly apply a patch and add your name to the credit roll if
you're so inclined :)

Daniel Aborg

unread,
Aug 4, 2009, 4:57:11 AM8/4/09
to Project Lombok
Excellent! I'll get on that right away then. :-)

Cheers,

Daniel

Daniel Aborg

unread,
Aug 4, 2009, 12:20:32 PM8/4/09
to Project Lombok
Thanks for the hints, definitely very helpful!

I can confirm that declaring the method parameters final does indeed
make Eclipse happy. I'll send a pull request when I've had a chance to
update all the Handlers. :-)

Cheers,

Daniel

Jaroslav Záruba

unread,
Nov 28, 2014, 4:56:41 PM11/28/14
to project...@googlegroups.com
I have ust ran into the same issue with 
private final @Getter(lazy=true) URIResolver uriResolver =...
:(

Any suggestions please?
Reply all
Reply to author
Forward
0 new messages