mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
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:
+49
-25
@@ -55,12 +55,13 @@ import java.awt.*;
|
|||||||
import java.awt.datatransfer.Clipboard;
|
import java.awt.datatransfer.Clipboard;
|
||||||
import java.awt.datatransfer.StringSelection;
|
import java.awt.datatransfer.StringSelection;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentListener {
|
public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentListener {
|
||||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.SelectionModelImpl");
|
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.SelectionModelImpl");
|
||||||
|
|
||||||
private final CopyOnWriteArrayList<SelectionListener> mySelectionListeners = ContainerUtil.createEmptyCOWList();
|
private final CopyOnWriteArrayList<SelectionListener> mySelectionListeners = ContainerUtil.createEmptyCOWList();
|
||||||
private MyRangeMarker mySelectionMarker = null;
|
private final AtomicReference<MyRangeMarker> mySelectionMarker = new AtomicReference<MyRangeMarker>();
|
||||||
private final EditorImpl myEditor;
|
private final EditorImpl myEditor;
|
||||||
private int myLastSelectionStart;
|
private int myLastSelectionStart;
|
||||||
private LogicalPosition myBlockStart;
|
private LogicalPosition myBlockStart;
|
||||||
@@ -90,7 +91,7 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
|
|||||||
if (!isValid()) {
|
if (!isValid()) {
|
||||||
myLastSelectionStart = myEditor.getCaretModel().getOffset();
|
myLastSelectionStart = myEditor.getCaretModel().getOffset();
|
||||||
release();
|
release();
|
||||||
mySelectionMarker = null;
|
mySelectionMarker.set(null);
|
||||||
fireSelectionChanged(startBefore, endBefore, myLastSelectionStart, myLastSelectionStart);
|
fireSelectionChanged(startBefore, endBefore, myLastSelectionStart, myLastSelectionStart);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -111,8 +112,9 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
|
|||||||
public void documentChanged(DocumentEvent event) {
|
public void documentChanged(DocumentEvent event) {
|
||||||
if (myIsInUpdate == event) {
|
if (myIsInUpdate == event) {
|
||||||
myIsInUpdate = null;
|
myIsInUpdate = null;
|
||||||
if (mySelectionMarker != null && mySelectionMarker.isValid()) {
|
MyRangeMarker marker = mySelectionMarker.get();
|
||||||
mySelectionMarker.documentChanged(event);
|
if (marker != null && marker.isValid()) {
|
||||||
|
marker.documentChanged(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,8 +129,13 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
|
|||||||
|
|
||||||
public int getSelectionStart() {
|
public int getSelectionStart() {
|
||||||
validateContext(false);
|
validateContext(false);
|
||||||
if (!hasSelection()) return myEditor.getCaretModel().getOffset();
|
if (hasSelection()) {
|
||||||
return mySelectionMarker.getStartOffset();
|
MyRangeMarker marker = mySelectionMarker.get();
|
||||||
|
if (marker != null) {
|
||||||
|
return marker.getStartOffset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return myEditor.getCaretModel().getOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateContext(boolean isWrite) {
|
private void validateContext(boolean isWrite) {
|
||||||
@@ -146,17 +153,23 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
|
|||||||
|
|
||||||
public int getSelectionEnd() {
|
public int getSelectionEnd() {
|
||||||
validateContext(false);
|
validateContext(false);
|
||||||
if (!hasSelection()) return myEditor.getCaretModel().getOffset();
|
if (hasSelection()) {
|
||||||
return mySelectionMarker.getEndOffset();
|
MyRangeMarker marker = mySelectionMarker.get();
|
||||||
|
if (marker != null) {
|
||||||
|
return marker.getEndOffset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return myEditor.getCaretModel().getOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSelection() {
|
public boolean hasSelection() {
|
||||||
validateContext(false);
|
validateContext(false);
|
||||||
if (mySelectionMarker != null && !mySelectionMarker.isValid()) {
|
MyRangeMarker marker = mySelectionMarker.get();
|
||||||
|
if (marker != null && !marker.isValid()) {
|
||||||
removeSelection();
|
removeSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
return mySelectionMarker != null;
|
return marker != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSelection(int startOffset, int endOffset) {
|
public void setSelection(int startOffset, int endOffset) {
|
||||||
@@ -189,19 +202,20 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
|
|||||||
int oldSelectionEnd;
|
int oldSelectionEnd;
|
||||||
|
|
||||||
if (hasSelection()) {
|
if (hasSelection()) {
|
||||||
oldSelectionStart = mySelectionMarker.getStartOffset();
|
oldSelectionStart = getSelectionStart();
|
||||||
oldSelectionEnd = mySelectionMarker.getEndOffset();
|
oldSelectionEnd = getSelectionEnd();
|
||||||
if (oldSelectionStart == startOffset && oldSelectionEnd == endOffset) return;
|
if (oldSelectionStart == startOffset && oldSelectionEnd == endOffset) return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
oldSelectionStart = oldSelectionEnd = myEditor.getCaretModel().getOffset();
|
oldSelectionStart = oldSelectionEnd = myEditor.getCaretModel().getOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mySelectionMarker != null) {
|
MyRangeMarker marker = mySelectionMarker.get();
|
||||||
mySelectionMarker.release();
|
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);
|
fireSelectionChanged(oldSelectionStart, oldSelectionEnd, startOffset, endOffset);
|
||||||
|
|
||||||
@@ -273,11 +287,12 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
|
|||||||
validateContext(true);
|
validateContext(true);
|
||||||
removeBlockSelection();
|
removeBlockSelection();
|
||||||
myLastSelectionStart = myEditor.getCaretModel().getOffset();
|
myLastSelectionStart = myEditor.getCaretModel().getOffset();
|
||||||
if (mySelectionMarker != null) {
|
MyRangeMarker marker = mySelectionMarker.get();
|
||||||
int startOffset = mySelectionMarker.getStartOffset();
|
if (marker != null) {
|
||||||
int endOffset = mySelectionMarker.getEndOffset();
|
int startOffset = marker.getStartOffset();
|
||||||
mySelectionMarker.release();
|
int endOffset = marker.getEndOffset();
|
||||||
mySelectionMarker = null;
|
marker.release();
|
||||||
|
mySelectionMarker.set(null);
|
||||||
fireSelectionChanged(startOffset, endOffset, myLastSelectionStart, myLastSelectionStart);
|
fireSelectionChanged(startOffset, endOffset, myLastSelectionStart, myLastSelectionStart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -435,11 +450,20 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
|
|||||||
public int getLeadSelectionOffset() {
|
public int getLeadSelectionOffset() {
|
||||||
validateContext(false);
|
validateContext(false);
|
||||||
int caretOffset = myEditor.getCaretModel().getOffset();
|
int caretOffset = myEditor.getCaretModel().getOffset();
|
||||||
if (!hasSelection()) return caretOffset;
|
if (hasSelection()) {
|
||||||
int startOffset = mySelectionMarker.getStartOffset();
|
MyRangeMarker marker = mySelectionMarker.get();
|
||||||
int endOffset = mySelectionMarker.getEndOffset();
|
if (marker != null) {
|
||||||
if (caretOffset == endOffset) return startOffset;
|
int startOffset = marker.getStartOffset();
|
||||||
return endOffset;
|
int endOffset = marker.getEndOffset();
|
||||||
|
if (caretOffset == endOffset) {
|
||||||
|
return startOffset;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return endOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return caretOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void selectLineAtCaret() {
|
public void selectLineAtCaret() {
|
||||||
|
|||||||
Reference in New Issue
Block a user