| Summary: | [rename] package rename corrupts files | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Ferry Huberts <mailings> | ||||||||||||||||||||||
| Component: | UI | Assignee: | JDT-UI-Inbox <jdt-ui-inbox> | ||||||||||||||||||||||
| Status: | RESOLVED NOT_ECLIPSE | QA Contact: | |||||||||||||||||||||||
| Severity: | major | ||||||||||||||||||||||||
| Priority: | P3 | CC: | daniel_megert, markus.kell.r | ||||||||||||||||||||||
| Version: | 3.7.1 | ||||||||||||||||||||||||
| Target Milestone: | --- | ||||||||||||||||||||||||
| Hardware: | PC | ||||||||||||||||||||||||
| OS: | Linux | ||||||||||||||||||||||||
| Whiteboard: | |||||||||||||||||||||||||
| Attachments: |
|
||||||||||||||||||||||||
|
Description
Ferry Huberts
Created attachment 205272 [details]
the java code generating the changes
Created attachment 205273 [details]
package rename, step 1
Created attachment 205274 [details]
package rename, step 2
Created attachment 205275 [details]
package rename, step 3
Created attachment 205276 [details]
package rename, step 4
Created attachment 205277 [details]
package rename, step 5
Created attachment 205278 [details]
package rename, step 6
Created attachment 205279 [details]
bnd.bnd file before rename
Created attachment 205280 [details]
bnd.bnd file after rename (corrupted)
> Since my code is not involved after the preview I've concluded that this must
> be an eclipse bug.
Not sure, as it obviously only happens with your participant.
Markus, please take a look.
My system: Fedora 15 x86_64 openjdk 1.6.0.0-59.1.10.3.fc15 Neil Bartlett just indicated that he could not reproduce this bug on Mac OS X Lion. we're currently testing some other platform combinations Neil probably has the "[x] Rename subpackages" option disabled. I didn't debug it, but I guess the problem is that your RenameParticipant is called multiple times (for each subpackage). Each time, you create a new TextFileChange that targets the same .bnd files. You create your ReplaceEdits based on the original version, which is why it looks correct in the preview. But after the first change has been executed, the content of the file has changed and the other changes are not valid any more. One possible fix is to use RefactoringParticipant#getTextChange(Object) to get an existing TextChange. Then, you can add your edits to that Change. (In reply to comment #12) > Neil probably has the "[x] Rename subpackages" option disabled. > > I didn't debug it, but I guess the problem is that your RenameParticipant is > called multiple times (for each subpackage). Each time, you create a new > TextFileChange that targets the same .bnd files. You create your ReplaceEdits > based on the original version, which is why it looks correct in the preview. > But after the first change has been executed, the content of the file has > changed and the other changes are not valid any more. > > One possible fix is to use RefactoringParticipant#getTextChange(Object) to get > an existing TextChange. Then, you can add your edits to that Change. Win XP with latest jdk6 (b27) shows the same problem. Will try your hint, but how to go about that? My participant is not reused but a new instance is used every time and I _really_ hate statics > Will try your hint, but how to go about that? My participant is not reused but
> a new instance is used every time and I _really_ hate statics
That's the beauty of RefactoringParticipant#getTextChange(Object). The implementation talks to the refactoring processor, and that one knows all changes. See also the Javadoc of RefactoringParticipant#createChange(..).
If you wanted to have a shared participant, you can also implement ISharableParticipant.
So, you can keep your statics aversion for something else ;-)
Created attachment 205644 [details] the new (working) rename code (In reply to comment #14) > > Will try your hint, but how to go about that? My participant is not reused but > > a new instance is used every time and I _really_ hate statics > > That's the beauty of RefactoringParticipant#getTextChange(Object). The > implementation talks to the refactoring processor, and that one knows all > changes. See also the Javadoc of RefactoringParticipant#createChange(..). Thanks for your help, it works! I have one issue left though: The rename only runs in the project in which the package rename is done, while the package is referenced in bnd files in other projects. How should we make Eclipse run the rename on these projects too? (attached the new source file) (In reply to comment #15) > The rename only runs in the project in which the package rename is done, while > the package is referenced in bnd files in other projects. > How should we make Eclipse run the rename on these projects too? The Java rename processor finds references in dependent projects as well. Maybe your code should do the same? You are choosing your scope here: pkgFragment.getResource().getProject().accept(visitor, IContainer.NONE); (In reply to comment #16) > (In reply to comment #15) > > The rename only runs in the project in which the package rename is done, while > > the package is referenced in bnd files in other projects. > > How should we make Eclipse run the rename on these projects too? > > The Java rename processor finds references in dependent projects as well. Maybe > your code should do the same? You are choosing your scope here: > > pkgFragment.getResource().getProject().accept(visitor, IContainer.NONE); cool. many many thanks for the tips! I did: - pkgFragment.getResource().getProject().accept(visitor, IContainer.NONE); + + Set<IProject> visitedProjects = new HashSet<IProject>(); + + IProject containingProject = pkgFragment.getResource().getProject(); + containingProject.accept(visitor, IContainer.NONE); + visitedProjects.add(containingProject); + + for (IProject project : pkgFragment.getResource().getProject().getReferencingProjects()) { + project.accept(visitor, IContainer.NONE); + visitedProjects.add(project); + } + + for (IProject project : pkgFragment.getResource().getProject().getReferencedProjects()) { + if (!visitedProjects.contains(project)) { + project.accept(visitor, IContainer.NONE); + visitedProjects.add(project); + } + } |