Bug 65211

Summary: AbstractTextEditor.doSetInput temporarily references an unconnected document
Product: [Eclipse Project] Platform Reporter: Michael Scharf <eclipse>
Component: TextAssignee: Platform-Text-Inbox <platform-text-inbox>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3    
Version: 3.0   
Target Milestone: 3.0 RC2   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description Michael Scharf CLA 2004-06-01 22:03:37 EDT
We ran into a problem with AbstractTextEditor.doSetInput
which temporarily references an unconnected document when
reusing an editor. With standard GapTextStore based document
implementations this does not make a big difference, but we
use a temporary scratchfile as text storage, which is
disposed when the documents refcount reaches 0. Thus the
document is no longer usable, then.

The problem did not exist in eclipse 2.1.2. In eclispe 3.0M9,
4 lines of code (2727-2730) have been added:

    protected void doSetInput(IEditorInput input) throws CoreException { [...]
        provider.connect(input);
        
        initializeTitle(input);

+       if (fIsOverwriting)
+           toggleOverwriteMode();
+       setInsertMode((InsertMode) getLegalInsertModes().get(0));
+       updateCaret();
        
        if (fSourceViewer != null)
            initializeSourceViewer(input);
            
        updateStatusField
(ITextEditorActionConstants.STATUS_CATEGORY_ELEMENT_STATE);


When updating the caret (triggered by setInsertMode),
StyledText still references the disconnected document, only
after initializeSourceViewer(input) it is updated to the new
document.  Probably the problem vanishes, if the 4 lines
would be moved after initializeSourceViewer(input).

We also identified a similar bug in
AbstractTextEditor.ElementStateListener.elementMoved:

    public void elementMoved(final Object originalElement, final Object 
movedElement) { [...]
      	IDocumentProvider d= getDocumentProvider();
      	IDocument changed= null;
      	if (isDirty())
      	    changed= d.getDocument(getEditorInput());
      	    
      	setInput((IEditorInput) movedElement);
      	            
      	if (changed != null) {
!     	    d.getDocument(getEditorInput()).set(changed.get());
      	    validateState(getEditorInput());
      	    updateStatusField
(ITextEditorActionConstants.STATUS_CATEGORY_ELEMENT_STATE);
      	}                   

setInput disconnects the old document (changed), which is
referenced a few lines later.  The content of "changed"
could be saved to a local String variable before setting the
new input.
Comment 1 Kai-Uwe Maetzel CLA 2004-06-02 14:33:53 EDT
to be investigated
Comment 2 Kai-Uwe Maetzel CLA 2004-06-09 14:31:33 EDT
The mentioned accesses to unreferenced documents are eliminated in build 
I200406100800. 

Please be aware that deconstructing the document on disconnect is dangerous. 
IDocumentProvider does not specify that a document once obtained from the 
provider may become invalid without notification. The same is true for 
IDocument. IDocument does not define a live cycle or predicates that tell a 
client whether a document is deconstructed or disposed. Thus, any code that 
does not care about the life cycle of specific IDocument implementations is 
valid code. The changes I made can not be expected in general. It's just 
courtesy.
Comment 3 Dani Megert CLA 2004-06-11 08:55:40 EDT
start verifying
Comment 4 Dani Megert CLA 2004-06-11 08:57:44 EDT
verified in I200406110010 through code inspection