EA-21694 - NPE: SelectionModelImpl.getSelectionStart

Refactored the code in order to exclude variables visibilities problems in case of access from concurrent threads
This commit is contained in:
Denis Zhdanov
2010-08-30 16:10:27 +04:00
parent a7f14e657d
commit bfe13eaebb
@@ -55,12 +55,13 @@ import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicReference;
public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentListener {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.SelectionModelImpl");
private final CopyOnWriteArrayList<SelectionListener> mySelectionListeners = ContainerUtil.createEmptyCOWList();
private MyRangeMarker mySelectionMarker = null;
private final AtomicReference<MyRangeMarker> mySelectionMarker = new AtomicReference<MyRangeMarker>();
private final EditorImpl myEditor;
private int myLastSelectionStart;
private LogicalPosition myBlockStart;
@@ -90,7 +91,7 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
if (!isValid()) {
myLastSelectionStart = myEditor.getCaretModel().getOffset();
release();
mySelectionMarker = null;
mySelectionMarker.set(null);
fireSelectionChanged(startBefore, endBefore, myLastSelectionStart, myLastSelectionStart);
return;
}
@@ -111,8 +112,9 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
public void documentChanged(DocumentEvent event) {
if (myIsInUpdate == event) {
myIsInUpdate = null;
if (mySelectionMarker != null && mySelectionMarker.isValid()) {
mySelectionMarker.documentChanged(event);
MyRangeMarker marker = mySelectionMarker.get();
if (marker != null && marker.isValid()) {
marker.documentChanged(event);
}
}
}
@@ -127,8 +129,13 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
public int getSelectionStart() {
validateContext(false);
if (!hasSelection()) return myEditor.getCaretModel().getOffset();
return mySelectionMarker.getStartOffset();
if (hasSelection()) {
MyRangeMarker marker = mySelectionMarker.get();
if (marker != null) {
return marker.getStartOffset();
}
}
return myEditor.getCaretModel().getOffset();
}
private void validateContext(boolean isWrite) {
@@ -146,17 +153,23 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
public int getSelectionEnd() {
validateContext(false);
if (!hasSelection()) return myEditor.getCaretModel().getOffset();
return mySelectionMarker.getEndOffset();
if (hasSelection()) {
MyRangeMarker marker = mySelectionMarker.get();
if (marker != null) {
return marker.getEndOffset();
}
}
return myEditor.getCaretModel().getOffset();
}
public boolean hasSelection() {
validateContext(false);
if (mySelectionMarker != null && !mySelectionMarker.isValid()) {
MyRangeMarker marker = mySelectionMarker.get();
if (marker != null && !marker.isValid()) {
removeSelection();
}
return mySelectionMarker != null;
return marker != null;
}
public void setSelection(int startOffset, int endOffset) {
@@ -189,19 +202,20 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
int oldSelectionEnd;
if (hasSelection()) {
oldSelectionStart = mySelectionMarker.getStartOffset();
oldSelectionEnd = mySelectionMarker.getEndOffset();
oldSelectionStart = getSelectionStart();
oldSelectionEnd = getSelectionEnd();
if (oldSelectionStart == startOffset && oldSelectionEnd == endOffset) return;
}
else {
oldSelectionStart = oldSelectionEnd = myEditor.getCaretModel().getOffset();
}
if (mySelectionMarker != null) {
mySelectionMarker.release();
MyRangeMarker marker = mySelectionMarker.get();
if (marker != null) {
marker.release();
}
mySelectionMarker = new MyRangeMarker((DocumentEx)doc, startOffset, endOffset);
mySelectionMarker.set(new MyRangeMarker((DocumentEx)doc, startOffset, endOffset));
fireSelectionChanged(oldSelectionStart, oldSelectionEnd, startOffset, endOffset);
@@ -273,11 +287,12 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
validateContext(true);
removeBlockSelection();
myLastSelectionStart = myEditor.getCaretModel().getOffset();
if (mySelectionMarker != null) {
int startOffset = mySelectionMarker.getStartOffset();
int endOffset = mySelectionMarker.getEndOffset();
mySelectionMarker.release();
mySelectionMarker = null;
MyRangeMarker marker = mySelectionMarker.get();
if (marker != null) {
int startOffset = marker.getStartOffset();
int endOffset = marker.getEndOffset();
marker.release();
mySelectionMarker.set(null);
fireSelectionChanged(startOffset, endOffset, myLastSelectionStart, myLastSelectionStart);
}
}
@@ -435,11 +450,20 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
public int getLeadSelectionOffset() {
validateContext(false);
int caretOffset = myEditor.getCaretModel().getOffset();
if (!hasSelection()) return caretOffset;
int startOffset = mySelectionMarker.getStartOffset();
int endOffset = mySelectionMarker.getEndOffset();
if (caretOffset == endOffset) return startOffset;
return endOffset;
if (hasSelection()) {
MyRangeMarker marker = mySelectionMarker.get();
if (marker != null) {
int startOffset = marker.getStartOffset();
int endOffset = marker.getEndOffset();
if (caretOffset == endOffset) {
return startOffset;
}
else {
return endOffset;
}
}
}
return caretOffset;
}
public void selectLineAtCaret() {