Community
Participate
Working Groups
I20040519 M9 test pass 1. Have these two classes: ========== Super.java ========== public class Super { } ========== Sub.java ============ public class Sub extends Super { private int b; public int getA() { return a; } public int getB() { return b; } } ================================= 2.a) choose Refactoring->Pull Up, select the field b 3.a) observe: the correct refactoring 4.a) choose Refactor->Undo Pull Up 5.a) observe: refactoring is correctly undone 6.a) observe: Sub.java is not correctly reconciled: - outline does not show field b, only a - choosing "pull up" again ony offers field a to be pulled up, not b 2.b) choose Refactoring->Pull Up, select the field a this time 3.b) observe: the CUs are correctly refactored 4.b) observe: compile error in Sub.getA(), saying that a cannot be resolved In both cases, modifying the cu and thus triggering a reconcile fixes the problem. Not sure on what side the problem is.
The Java reconciler is triggered correctly. It produces the following delta: org.eclipse.jdt.core.ElementChangedEvent[source=[Working copy] Sub.java[*]: {CHILDREN | FINE GRAINED} Sub[*]: {CHILDREN | FINE GRAINED} b[+]: {}] Where as the working copy is: [Working copy] Sub.java [in <default> [in <project root> [in Test]]] class Sub int a int b int getA() int getB() The stack looks as follows: Thread [org.eclipse.jdt.internal.ui.text.JavaReconciler] (Suspended (breakpoint at line 75 in PackageExplorerContentProvider)) PackageExplorerContentProvider.elementChanged(ElementChangedEvent) line: 75 DeltaProcessor$2.run() line: 1469 InternalPlatform.run(ISafeRunnable) line: 607 Platform.run(ISafeRunnable) line: 668 DeltaProcessor.notifyListeners(IJavaElementDelta, int, IElementChangedListener[], int[], int) line: 1464 DeltaProcessor.fireReconcileDelta(IElementChangedListener[], int[], int) line: 1331 DeltaProcessor.fire(IJavaElementDelta, int) line: 1289 ReconcileWorkingCopyOperation(JavaModelOperation).run (IProgressMonitor) line: 720 ReconcileWorkingCopyOperation(JavaModelOperation).runOperation (IProgressMonitor) line: 739 CompilationUnit.reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor) line: 1097 JavaReconcilingStrategy.reconcile() line: 88 JavaReconcilingStrategy.reconcile(IRegion) line: 129 JavaCompositeReconcilingStrategy (CompositeReconcilingStrategy).reconcile(IRegion) line: 86 JavaCompositeReconcilingStrategy.reconcile(IRegion) line: 96 JavaReconciler(MonoReconciler).process(DirtyRegion) line: 76 AbstractReconciler$BackgroundThread.run() line: 200 Moving to JDT/Text.
Strangly this only happens the first time when you do the refactoring after you have entered the source code. Here is what I did: - started target workspace - create Super in default package of Test project - copied the code from above - create Sub in default package - copied code from above - fixed missing field a by entering a second field private int a; before field b; - selected b in outline. Performed Pull-Up - Executed Refactor Undo.
Created attachment 10852 [details] Attaching the Java model delta
The Java Model delta is missing a delta for the addition of the variable b in Sub.java. Unclear if the reconciler has not been triggered or if the Java Model didn't produce the delta.
Moving to JDT/Text to check if the reconciler gets triggered.
Further findings: - refactoring saves the file after changing it so the delta computation should not rely on the reconciler. - the undo works without any problems if no working copies exists on Super and sub. The package explorer updates correctly then. - the problem doesn't occur always. So it seems to be a timing issue. But when ever it happens the delta sent out by Java Model doesn't contain the addition of field b to type Sub. - it is best reproducable (on my maschine) when the package explorer has focus when the refactoring undo operation is executed.
*** Bug 62836 has been marked as a duplicate of this bug. ***
Our findings are as follows: 1) the delta seems to be wrong in most cases (missing addition or removal for Sub) 2) there are two paths which trigger two different deltas a) reconciler thread calls cu.reconcile when the document changes ==> fine grained delta b) main thread commits changes to ResourceTextFileBuffer which causes a resource delta to be sent which causes J Core to send a delta We assume that the two triggers from different threads confuse the Java model and as a result a wrong delta gets sent.
*** Bug 63515 has been marked as a duplicate of this bug. ***
DocumentAdapter.fireBufferChanged(BufferChangedEvent) is not called for the Sub.java working copy. As a consequence we think that the content of the buffer is the same and we don't fire a delta. Moving to JDT/Text to investigate why this is not fired.
*** Bug 63799 has been marked as a duplicate of this bug. ***
important strange detail for the test case: folding must be disabled
I just debugged a case where DocumentAdapter.fireBufferChanged(BufferChangedEvent) was called for Sub.java (twice, because of some formatting) and the outline was still not updated.
I found the following: - comment 10 is correct: the document change does not make it to the adapter - reason for that: the DocumentAdapter is closed from the reconciler thread and then reopened - if the document change hits right into that gap, the change is not propagated to jdt core. Following a stack trace into DocumentAdapter.close: Thread [org.eclipse.jdt.internal.ui.text.JavaReconciler] (Suspended (breakpoint at line 237 in DocumentAdapter)) DocumentAdapter.close() line: 237 CompilationUnit(Openable).closeBuffer() line: 93 ImportContainer(JavaElement).openWhenClosed(Object, IProgressMonitor) line: 583 ImportContainer(JavaElement).getElementInfo(IProgressMonitor) line: 310 ImportContainer(JavaElement).getElementInfo() line: 296 ImportContainer(JavaElement).exists() line: 163 CompilationUnit.getImports() line: 683 SourceTypeElementInfo.getImports() line: 126 SourceTypeConverter.convert(ISourceType[], CompilationResult) line: 109 SourceTypeConverter.buildCompilationUnit(ISourceType[], int, ProblemReporter, CompilationResult) line: 83 CompilationUnitProblemFinder.accept(ISourceType[], PackageBinding) line: 100 LookupEnvironment.askForType(PackageBinding, char[]) line: 107 PackageBinding.getTypeOrPackage(char[]) line: 170 CompilationUnitScope(Scope).getTypeOrPackage(char[], int) line: 1448 ClassScope.findSupertype(TypeReference) line: 815 ClassScope.connectSuperclass() line: 607 ClassScope.connectTypeHierarchy() line: 700 CompilationUnitScope.connectTypeHierarchy() line: 242 LookupEnvironment.completeTypeBindings() line: 171 CompilationUnitProblemFinder(Compiler).resolve(CompilationUnitDeclaration, ICompilationUnit, boolean, boolean, boolean) line: 550 CompilationUnitProblemFinder.process(CompilationUnitDeclaration, ICompilationUnit, char[], Parser, WorkingCopyOwner, IProblemRequestor, IProblemFactory, boolean, IProgressMonitor) line: 176 CompilationUnit.buildStructure(OpenableElementInfo, IProgressMonitor, Map, IResource) line: 145 CompilationUnit(Openable).generateInfos(Object, HashMap, IProgressMonitor) line: 183 CompilationUnit(JavaElement).openWhenClosed(Object, IProgressMonitor) line: 573 CompilationUnit.makeConsistent(boolean, int, IProgressMonitor) line: 970 ReconcileWorkingCopyOperation.executeOperation() line: 58 ReconcileWorkingCopyOperation(JavaModelOperation).run(IProgressMonitor) line: 700 ReconcileWorkingCopyOperation(JavaModelOperation).runOperation(IProgressMonitor) line: 739 CompilationUnit.reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor) line: 1097 JavaReconcilingStrategy.reconcile() line: 88 JavaReconcilingStrategy.reconcile(IRegion) line: 129 JavaCompositeReconcilingStrategy(CompositeReconcilingStrategy).reconcile(IRegion) line: 86 JavaCompositeReconcilingStrategy.reconcile(IRegion) line: 96 JavaReconciler(MonoReconciler).process(DirtyRegion) line: 76 AbstractReconciler$BackgroundThread.run() line: 200
moving to jdt core for comments.
*** Bug 63326 has been marked as a duplicate of this bug. ***
JavaElement.getElementInfo(IProgressMonitor) should not try to open the element if its openable parent is open.
Actually problem was in JavaElement#openWhenClosed() that would close the buffer of an openable that was not the element's openable. This happened when reconciling the Sub.java cu: in the process of computing problems, Super.java was being asks if its import container existed. This caused the buffer for Sub.java to be closed. Changed JavaElement#openWhenClosed() to close only the buffer of the element's openable. Added regression test ReconcilerTests#testBufferOpenAfterReconcile()
*** Bug 64481 has been marked as a duplicate of this bug. ***
Verified in 200405281200
*** Bug 37870 has been marked as a duplicate of this bug. ***