mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
EA-45865 - assert: DocumentImpl.a
This commit is contained in:
+19
-8
@@ -15,26 +15,29 @@
|
||||
*/
|
||||
package com.intellij.openapi.diff;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.event.DocumentAdapter;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
abstract class DocumentsSynchonizer {
|
||||
abstract class DocumentsSynchronizer {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.DocumentsSynchonizer");
|
||||
private Document myOriginal = null;
|
||||
private Document myCopy = null;
|
||||
private final Project myProject;
|
||||
|
||||
private boolean myDuringModification = false;
|
||||
private volatile boolean myDuringModification = false;
|
||||
private int myAssignedCount = 0;
|
||||
|
||||
private final DocumentAdapter myOriginalListener = new DocumentAdapter() {
|
||||
@Override
|
||||
public void documentChanged(DocumentEvent e) {
|
||||
if (myDuringModification) return;
|
||||
onOriginalChanged(e, getCopy());
|
||||
@@ -42,39 +45,47 @@ abstract class DocumentsSynchonizer {
|
||||
};
|
||||
|
||||
private final DocumentAdapter myCopyListener = new DocumentAdapter() {
|
||||
@Override
|
||||
public void documentChanged(DocumentEvent e) {
|
||||
if (myDuringModification) return;
|
||||
onCopyChanged(e, getOriginal());
|
||||
}
|
||||
};
|
||||
private final PropertyChangeListener myROListener = new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (Document.PROP_WRITABLE.equals(evt.getPropertyName())) getCopy().setReadOnly(!getOriginal().isWritable());
|
||||
}
|
||||
};
|
||||
|
||||
protected DocumentsSynchonizer(Project project) {
|
||||
protected DocumentsSynchronizer(Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
protected abstract void onCopyChanged(DocumentEvent event, Document original);
|
||||
protected abstract void onCopyChanged(@NotNull DocumentEvent event, @NotNull Document original);
|
||||
|
||||
protected abstract void onOriginalChanged(DocumentEvent event, Document copy);
|
||||
protected abstract void onOriginalChanged(@NotNull DocumentEvent event, @NotNull Document copy);
|
||||
|
||||
protected abstract void beforeListenersAttached(Document original, Document copy);
|
||||
protected abstract void beforeListenersAttached(@NotNull Document original, @NotNull Document copy);
|
||||
|
||||
protected abstract Document createOriginal();
|
||||
|
||||
protected abstract Document createCopy();
|
||||
|
||||
protected void replaceString(final Document document, final int startOffset, final int endOffset, final String newText) {
|
||||
protected void replaceString(@NotNull final Document document, final int startOffset, final int endOffset, @NotNull final String newText) {
|
||||
LOG.assertTrue(!myDuringModification);
|
||||
try {
|
||||
myDuringModification = true;
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
LOG.assertTrue(endOffset <= document.getTextLength());
|
||||
document.replaceString(startOffset, endOffset, newText);
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
document.replaceString(startOffset, endOffset, newText);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, DiffBundle.message("save.merge.result.command.name"), document);
|
||||
}
|
||||
@@ -23,11 +23,11 @@ import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -39,19 +39,16 @@ public class FragmentContent extends DiffContent {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.FragmentContent");
|
||||
private final DiffContent myOriginal;
|
||||
private final FileType myType;
|
||||
private final MyDocumentsSynchonizer mySynchonizer;
|
||||
private final MyDocumentsSynchronizer mySynchonizer;
|
||||
public static final Key<Document> ORIGINAL_DOCUMENT = new Key<Document>("ORIGINAL_DOCUMENT");
|
||||
|
||||
public FragmentContent(DiffContent original, TextRange range, Project project, VirtualFile file) {
|
||||
public FragmentContent(@NotNull DiffContent original, @NotNull TextRange range, Project project, VirtualFile file) {
|
||||
this(original, range, project, file != null ? DiffContentUtil.getContentType(file) : null);
|
||||
}
|
||||
|
||||
public FragmentContent(DiffContent original, TextRange range, Project project, FileType type) {
|
||||
this(original.getDocument().createRangeMarker(range.getStartOffset(), range.getEndOffset(), true), original, type, project);
|
||||
}
|
||||
|
||||
private FragmentContent(RangeMarker rangeMarker, DiffContent original, FileType fileType, Project project) {
|
||||
mySynchonizer = new MyDocumentsSynchonizer(project, rangeMarker);
|
||||
public FragmentContent(@NotNull DiffContent original, @NotNull TextRange range, Project project, FileType fileType) {
|
||||
RangeMarker rangeMarker = original.getDocument().createRangeMarker(range.getStartOffset(), range.getEndOffset(), true);
|
||||
mySynchonizer = new MyDocumentsSynchronizer(project, rangeMarker);
|
||||
myOriginal = original;
|
||||
myType = fileType;
|
||||
}
|
||||
@@ -65,27 +62,35 @@ public class FragmentContent extends DiffContent {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onAssigned(boolean isAssigned) {
|
||||
myOriginal.onAssigned(isAssigned);
|
||||
mySynchonizer.listenDocuments(isAssigned);
|
||||
super.onAssigned(isAssigned);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document getDocument() {
|
||||
return mySynchonizer.getCopy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OpenFileDescriptor getOpenFileDescriptor(int offset) {
|
||||
return myOriginal.getOpenFileDescriptor(offset + mySynchonizer.getStartOffset());
|
||||
}
|
||||
|
||||
public VirtualFile getFile() { return null; }
|
||||
@Override
|
||||
public VirtualFile getFile() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public FileType getContentType() {
|
||||
return myType != null ? myType : myOriginal.getContentType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes() throws IOException {
|
||||
return getDocument().getText().getBytes();
|
||||
}
|
||||
@@ -97,52 +102,59 @@ public class FragmentContent extends DiffContent {
|
||||
return new FragmentContent(new DocumentContent(project, document), TextRange.create(rangeMarker), project, type);
|
||||
}
|
||||
|
||||
private class MyDocumentsSynchonizer extends DocumentsSynchonizer {
|
||||
private class MyDocumentsSynchronizer extends DocumentsSynchronizer {
|
||||
private final RangeMarker myRangeMarker;
|
||||
|
||||
public MyDocumentsSynchonizer(Project project, RangeMarker originalRange) {
|
||||
public MyDocumentsSynchronizer(Project project, @NotNull RangeMarker originalRange) {
|
||||
super(project);
|
||||
myRangeMarker = originalRange;
|
||||
}
|
||||
|
||||
public int getStartOffset() { return myRangeMarker.getStartOffset(); }
|
||||
public int getStartOffset() {
|
||||
return myRangeMarker.getStartOffset();
|
||||
}
|
||||
|
||||
protected void onOriginalChanged(DocumentEvent event, Document copy) {
|
||||
@Override
|
||||
protected void onOriginalChanged(@NotNull DocumentEvent event, @NotNull Document copy) {
|
||||
if (!myRangeMarker.isValid()) {
|
||||
fireContentInvalid();
|
||||
return;
|
||||
}
|
||||
replaceString(copy, 0, copy.getTextLength(),
|
||||
subText(event.getDocument(), myRangeMarker.getStartOffset(), getLength()));
|
||||
replaceString(copy, 0, copy.getTextLength(), subText(event.getDocument(), myRangeMarker.getStartOffset(), getLength()));
|
||||
}
|
||||
|
||||
protected void beforeListenersAttached(Document original, Document copy) {
|
||||
@Override
|
||||
protected void beforeListenersAttached(@NotNull Document original, @NotNull Document copy) {
|
||||
boolean writable = copy.isWritable();
|
||||
Document copyEx = copy;
|
||||
if (!writable) copyEx.setReadOnly(false);
|
||||
replaceString(copy, 0, copy.getTextLength(),
|
||||
subText(original, myRangeMarker.getStartOffset(), getLength()));
|
||||
copyEx.setReadOnly(!writable);
|
||||
if (!writable) {
|
||||
copy.setReadOnly(false);
|
||||
}
|
||||
replaceString(copy, 0, copy.getTextLength(), subText(original, myRangeMarker.getStartOffset(), getLength()));
|
||||
copy.setReadOnly(!writable);
|
||||
}
|
||||
|
||||
private int getLength() {
|
||||
return myRangeMarker.getEndOffset() - myRangeMarker.getStartOffset();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Document createOriginal() {
|
||||
return myRangeMarker.getDocument();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Document createCopy() {
|
||||
final Document originalDocument = myRangeMarker.getDocument();
|
||||
String textInRange = originalDocument.getCharsSequence().subSequence(myRangeMarker.getStartOffset(), myRangeMarker.getEndOffset()).toString();
|
||||
String textInRange =
|
||||
originalDocument.getCharsSequence().subSequence(myRangeMarker.getStartOffset(), myRangeMarker.getEndOffset()).toString();
|
||||
final Document result = EditorFactory.getInstance().createDocument(textInRange);
|
||||
result.setReadOnly(!originalDocument.isWritable());
|
||||
result.putUserData(ORIGINAL_DOCUMENT, originalDocument);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void onCopyChanged(DocumentEvent event, Document original) {
|
||||
@Override
|
||||
protected void onCopyChanged(@NotNull DocumentEvent event, @NotNull Document original) {
|
||||
final int originalOffset = event.getOffset() + myRangeMarker.getStartOffset();
|
||||
LOG.assertTrue(originalOffset >= 0);
|
||||
if (!original.isWritable()) return;
|
||||
|
||||
Reference in New Issue
Block a user