Applying a change and related undo throws exception! [message #654528] |
Wed, 16 February 2011 08:42 |
Kivanc Muslu Messages: 153 Registered: November 2010 |
Senior Member |
|
|
Edit: More information: My problematic change is instanceof RenameCompilationUnitChange.
Hi all,
Let's say that I have the following class:
public class WrongClassNameDefinately {}
defined in a file called WrongClassName.java
In this case (as a user), Eclipse creates a quick fix with 2 proposal:
Let's assume that I applied 'Change compilation name to WrongClassNameDefinately.java'. In this case, Eclipse deleted the current file and creates a new file with almost same content in the same package. If, after this quick fix application, I press cmd+z (undo), then Eclipse correctly fixes things back.
I want to do the same thing using the Eclipse API programmatically. What I want (at higher level) is the following:
1- Apply Change that represents 'Change compilation unit to ...' using Change.perform(). This change is retrieved using QuickFixProcessor and going through ChangeCorrectionProposal. Performing the change also creates the undo.
2- Do some calculation. This is not time consuming.
3- Apply the undo.
If I execute the above algorithm for the above change, I always get the following exception (while trying to apply the undo):
WrongClassName.java [in <default> [in src [in -630562215_0]]] does not exist
org.eclipse.jdt.internal.core.MultiOperation.processElements(MultiOperation.java:175)
org.eclipse.jdt.internal.core.CopyResourceElementsOperation.processElements(CopyResourceElementsOperation.java:417)
org.eclipse.jdt.internal.core.MultiOperation.executeOperation(MultiOperation.java:90)
org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:728)
org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1975)
org.eclipse.jdt.internal.core.JavaModelOperation.runOperation(JavaModelOperation.java:793)
org.eclipse.jdt.internal.core.JavaModel.rename(JavaModel.java:285)
org.eclipse.jdt.internal.core.CompilationUnit.rename(CompilationUnit.java:1264)
org.eclipse.jdt.internal.corext.refactoring.changes.RenameCompilationUnitChange.doRename(RenameCompilationUnitChange.java:59)
org.eclipse.jdt.internal.corext.refactoring.AbstractJavaElementRenameChange.perform(AbstractJavaElementRenameChange.java:86)
edu.uw.quickfix.speculation.util.Aux.performChangeAndSave(Aux.java:495)
edu.uw.quickfix.speculation.util.QuickFixPreCalculator.applyUndo(QuickFixPreCalculator.java:351)
edu.uw.quickfix.speculation.util.QuickFixPreCalculator.processProposal(QuickFixPreCalculator.java:275)
edu.uw.quickfix.speculation.util.QuickFixPreCalculator.processProblemLocation(QuickFixPreCalculator.java:223)
edu.uw.quickfix.speculation.util.QuickFixPreCalculator.doWork2(QuickFixPreCalculator.java:201)
edu.uw.quickfix.speculation.util.BlockableMortalThread.doWork(BlockableMortalThread.java:98)
edu.uw.quickfix.speculation.util.MortalThread.run(MortalThread.java:44)
By sheer luck, I discovered that (while debugging), this does not happen if there is a delay between change application and undo application. So, if I change the algorithm to below:
1- Apply Change that represents 'Change compilation unit to ...' using Change.perform(). This change is retrieved using QuickFixProcessor and going through ChangeCorrectionProposal. Performing the change also creates the undo.
2- Do some calculation. This is not time consuming.
3- Thread.sleep(100)
4- Apply the undo.
Then the same code works without any problems at all. This is great, however I have 2 problems (questions):
1- For somebody understands the internal of change and undo application, what is the reason beyond this? Thread.yield() or a lower value for sleep (like 10) does not seem to work. I also have no idea if 100 is a valid value for all changes, or if the wait value is change specific.
2- My plugin should compute 50-100 changes in a pass. I am well aware that only changes that create this problem (up to now) are the changes that actually delete and create files or folders, however even for this subset sleeping 100 milliseconds for each proposal is a great performance issue for me. Is there another workaround for this problem I am having?
3- Is there a way to distinguish these category of Changes (that delete and create files and folders)? Like, are they extend a common class that I can check, so that I will only sleep for these instances?
Thanks in advance, best regards,
[Updated on: Wed, 16 February 2011 09:11] Report message to a moderator
|
|
|
|
Re: Applying a change and related undo throws exception! [message #655291 is a reply to message #655160] |
Sat, 19 February 2011 00:29 |
Kivanc Muslu Messages: 153 Registered: November 2010 |
Senior Member |
|
|
Hi Markus,
Thanks for the reply.
All changes are done by my background thread (i.e., a daemon), however to make a change applicable, before applying a change, I first open the file in Eclipse editor using Eclipse UI thread. I don't think this would create the problem since it doesn't create a problem with other changes (that does not delete or create files), and the API I use to execute code in Eclipse UI thread is blocking (i.e., it blocks my daemon until Eclipse UI thread opens the file in the editor).
As I described, I don't think that I can generate a user test case for this (since you cannot move the mouse or click keyboard as fast as a program can do). However, I think I can create a simple program that always throws an exception when trying to apply a RenameCompilationUnit change to a file and trying to undo it.
I am not sure how simple the problem I can create can be though. I use the QuickFixProcessor of Eclipse itself to get the IJavaCompletionProposal (which is a ChangeCorrectionProposal) and get Change and Undo objects that represents the modification. I have never tried coding them from scratch.
Would a simple example (i.e., plug-in) with a simple project in its workspace that would throw an exception every time a quick fix is clicked help as a bug report? Or should I make it completely non-interactive (i.e., all Change, Undo etc., are calculated in advance, and program applies it directly).
By the way, do you know why the file that the Change will be applied must be open in an Eclipse editor (if not the change is not applied, neither I receive a notification or exception)? I also find out this by luck.
Thank you,
[Updated on: Sat, 19 February 2011 00:30] Report message to a moderator
|
|
|
Powered by
FUDForum. Page generated in 0.03023 seconds