Community
Participate
Working Groups
We have a code generation framework that uses the JDT APIs to create and delete compilation unit elements. We have the framework setup such that we can generate changes while the Java editor is open on a file. In this case, we generate into the open file. What we have found is that doing multiple delete elements (e.g., fields and methods) within the CompilationUnit is extremely slow and it gets worse the larger the class and the more elements that are updated. Looking into the problem, it appears that the save(...) on the WorkingCopy performs a reconcile (). This happens on each and every element add, remove, or update. This is expensive and slow. What we would like is a capability to halt the save on the WorkingCopy by the JavaModelOperations while doing a batch set of changes. After the changes are complete, we would then save all WorkingCopies that have been modified and at this time the reconcile will take place. Basically, we would only have one reconcile() on a particular WorkingCopy during this batch codegen instead of possible hundreds.
Are you sure that the JavaCore.run(IWorkspaceRunnable action, IProgressMonitor monitor) throws CoreException doesn't do what you want?
Indeed, batching JavaModel operations was added for 2.1. If properly batched, then only one reconciliation action should occur at the end. Is it ok to close ?
We did try using JavaCore.run(IWorkspaceRunnable action, IProgressMonitor monitor) throws CoreException but it appeared that the reconcile still took place but the notifications were batched and sent at the end. Should this stop the reconcile altogether? I still see the save(...) method being called irregardless of whether this api is used or not.
I see. The philosophy of the model is that side-effects are updating the model as they are performed. This is why the element additions, even if batched, are still performed immediately. The generated delta is accumulated until the end of the batch operation, and only notified at once. Thus, one can create a method, and immediately after use it (instead of waiting until the batch operation ends). What you would need instead is to create a DOM ASTof the unit, update it all at once and commit it at the end. Unfortunately, there is currently no API for writing out some modified DOM AST back to source (this is on the 3.0 plan). JDT/UI has defined such custom mechanism for refactoring purpose though.
Besides the reconcile batching, It would be a good thing to allow one to postpone the linkage between the model changing and the consequence change onto the AnnotationModel (call to endReporting() from ReconcileWorkingCopyOperation), like the AnnotationPainter. We have a scenario were a set of instance fields, getter methods and IMethods updates are made to a compilation unit (with error/warnings) in one Compound command. Reconcile is slow, but, it may be called in between to ensure a consistent model when needed. There is no need for the model change to propagate to its listeners. In our case we would not even want the JavaEditor "fliker" while the updates are in progress.
The JDOM (you are using) is going to be deprecated as soon as the new DOM serialization support is added (on 3.0 plan). Using the DOM, you will be able to perform sets of changes and only persist them as source at the end. However this is still work in progress.
Just to further clarify, some of the JDOM APIs like move, copy are allowing to batch changes, but not all of them (create).
David - please close once rewrite support is in.
Rewrite support is now in.
Rewrite support is now in look at org.eclipse.jdt.core.dom.rewrite.ASTRewrite and org.eclipse.jdt.core.dom.CompilationUnit#recordModifications() org.eclipse.jdt.core.dom.CompilationUnit#rewrite(IDocument,Map)