mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
encapsulate ImmutableText
This commit is contained in:
@@ -38,7 +38,7 @@ import com.intellij.util.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.IntArrayList;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import com.intellij.util.text.ImmutableText;
|
||||
import com.intellij.util.text.ImmutableCharSequence;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import gnu.trove.TObjectProcedure;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -66,7 +66,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
|
||||
@SuppressWarnings("RedundantStringConstructorCall") private final Object myLineSetLock = new String("line set lock");
|
||||
private volatile LineSet myLineSet;
|
||||
private volatile ImmutableText myText;
|
||||
private volatile ImmutableCharSequence myText;
|
||||
private volatile SoftReference<String> myTextString;
|
||||
private volatile FrozenDocument myFrozen;
|
||||
|
||||
@@ -133,7 +133,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
public DocumentImpl(@NotNull CharSequence chars, boolean acceptSlashR, boolean forUseInNonAWTThread) {
|
||||
setAcceptSlashR(acceptSlashR);
|
||||
assertValidSeparators(chars);
|
||||
myText = ImmutableText.valueOf(chars);
|
||||
myText = CharArrayUtil.createImmutableCharSequence(chars);
|
||||
setCyclicBufferSize(0);
|
||||
setModificationStamp(LocalTimeCounter.currentTime());
|
||||
myAssertThreading = !forUseInNonAWTThread;
|
||||
@@ -472,12 +472,12 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
|
||||
RangeMarker marker = getRangeGuard(offset, offset);
|
||||
if (marker != null) {
|
||||
throwGuardedFragment(marker, offset, null, s.toString());
|
||||
throwGuardedFragment(marker, offset, "", s);
|
||||
}
|
||||
|
||||
myText = myText.ensureChunked();
|
||||
ImmutableText newText = myText.insert(offset, ImmutableText.valueOf(s));
|
||||
updateText(newText, offset, null, newText.subtext(offset, offset + s.length()), false, LocalTimeCounter.currentTime(), offset, 0);
|
||||
ImmutableCharSequence newText = myText.insert(offset, s);
|
||||
ImmutableCharSequence newString = newText.subtext(offset, offset + s.length());
|
||||
updateText(newText, offset, "", newString, false, LocalTimeCounter.currentTime(), offset, 0);
|
||||
trimToSize();
|
||||
}
|
||||
|
||||
@@ -497,11 +497,12 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
|
||||
RangeMarker marker = getRangeGuard(startOffset, endOffset);
|
||||
if (marker != null) {
|
||||
throwGuardedFragment(marker, startOffset, myText.subSequence(startOffset, endOffset).toString(), null);
|
||||
throwGuardedFragment(marker, startOffset, myText.subSequence(startOffset, endOffset), "");
|
||||
}
|
||||
|
||||
myText = myText.ensureChunked();
|
||||
updateText(myText.delete(startOffset, endOffset), startOffset, myText.subtext(startOffset, endOffset), null, false, LocalTimeCounter.currentTime(), startOffset, endOffset - startOffset);
|
||||
ImmutableCharSequence newText = myText.delete(startOffset, endOffset);
|
||||
ImmutableCharSequence oldString = myText.subtext(startOffset, endOffset);
|
||||
updateText(newText, startOffset, oldString, "", false, LocalTimeCounter.currentTime(), startOffset, endOffset - startOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -575,15 +576,14 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
CharSequence sToDelete = myText.subtext(startOffset, endOffset);
|
||||
RangeMarker guard = getRangeGuard(startOffset, endOffset);
|
||||
if (guard != null) {
|
||||
throwGuardedFragment(guard, startOffset, sToDelete.toString(), changedPart.toString());
|
||||
throwGuardedFragment(guard, startOffset, sToDelete, changedPart);
|
||||
}
|
||||
|
||||
ImmutableText newText;
|
||||
if (wholeTextReplaced && s instanceof ImmutableText) {
|
||||
newText = (ImmutableText)s;
|
||||
ImmutableCharSequence newText;
|
||||
if (wholeTextReplaced && s instanceof ImmutableCharSequence) {
|
||||
newText = (ImmutableCharSequence)s;
|
||||
}
|
||||
else {
|
||||
myText = myText.ensureChunked();
|
||||
newText = myText.delete(startOffset, endOffset).insert(startOffset, changedPart);
|
||||
changedPart = newText.subtext(startOffset, startOffset + changedPart.length());
|
||||
}
|
||||
@@ -649,7 +649,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
}
|
||||
}
|
||||
|
||||
private void throwGuardedFragment(@NotNull RangeMarker guard, int offset, String oldString, String newString) {
|
||||
private void throwGuardedFragment(@NotNull RangeMarker guard, int offset, @NotNull CharSequence oldString, @NotNull CharSequence newString) {
|
||||
if (myCheckGuardedBlocks > 0 && !myGuardsSuppressed) {
|
||||
DocumentEvent event = new DocumentEventImpl(this, offset, oldString, newString, myModificationStamp, false);
|
||||
throw new ReadOnlyFragmentModificationException(event, guard);
|
||||
@@ -698,10 +698,10 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
myFrozen = null;
|
||||
}
|
||||
|
||||
private void updateText(@NotNull ImmutableText newText,
|
||||
private void updateText(@NotNull ImmutableCharSequence newText,
|
||||
int offset,
|
||||
@Nullable CharSequence oldString,
|
||||
@Nullable CharSequence newString,
|
||||
@NotNull CharSequence oldString,
|
||||
@NotNull CharSequence newString,
|
||||
boolean wholeTextReplaced,
|
||||
long newModificationStamp,
|
||||
int initialStartOffset,
|
||||
@@ -712,7 +712,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
DocumentEvent event = new DocumentEventImpl(this, offset, oldString, newString, myModificationStamp, wholeTextReplaced, initialStartOffset, initialOldLength);
|
||||
doBeforeChangedUpdate(event);
|
||||
myTextString = null;
|
||||
ImmutableText prevText = myText;
|
||||
ImmutableCharSequence prevText = myText;
|
||||
myText = newText;
|
||||
sequence.incrementAndGet(); // increment sequence before firing events so that modification sequence on commit will match this sequence now
|
||||
changedUpdate(event, newModificationStamp, prevText);
|
||||
@@ -764,7 +764,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
}
|
||||
}
|
||||
|
||||
private void changedUpdate(@NotNull DocumentEvent event, long newModificationStamp, ImmutableText prevText) {
|
||||
private void changedUpdate(@NotNull DocumentEvent event, long newModificationStamp, @NotNull CharSequence prevText) {
|
||||
try {
|
||||
if (LOG.isDebugEnabled()) LOG.debug(event.toString());
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import com.intellij.util.text.ImmutableText;
|
||||
import com.intellij.util.text.ImmutableCharSequence;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -40,12 +40,12 @@ import java.util.List;
|
||||
* @author peter
|
||||
*/
|
||||
public class FrozenDocument implements DocumentEx {
|
||||
private final ImmutableText myText;
|
||||
private final ImmutableCharSequence myText;
|
||||
private final LineSet myLineSet;
|
||||
private final long myStamp;
|
||||
private volatile SoftReference<String> myTextString;
|
||||
|
||||
public FrozenDocument(@NotNull ImmutableText text, @NotNull LineSet lineSet, long stamp, @Nullable String textString) {
|
||||
FrozenDocument(@NotNull ImmutableCharSequence text, @NotNull LineSet lineSet, long stamp, @Nullable String textString) {
|
||||
myText = text;
|
||||
myLineSet = lineSet;
|
||||
myStamp = stamp;
|
||||
@@ -55,8 +55,8 @@ public class FrozenDocument implements DocumentEx {
|
||||
public FrozenDocument applyEvent(DocumentEvent event, int newStamp) {
|
||||
final int offset = event.getOffset();
|
||||
final int oldEnd = offset + event.getOldLength();
|
||||
final ImmutableText newText = myText.delete(offset, oldEnd).insert(offset, event.getNewFragment());
|
||||
final LineSet newLineSet = myLineSet.update(myText, offset, oldEnd, event.getNewFragment(), event.isWholeTextReplaced());
|
||||
ImmutableCharSequence newText = myText.delete(offset, oldEnd).insert(offset, event.getNewFragment());
|
||||
LineSet newLineSet = myLineSet.update(myText, offset, oldEnd, event.getNewFragment(), event.isWholeTextReplaced());
|
||||
return new FrozenDocument(newText, newLineSet, newStamp, null);
|
||||
}
|
||||
|
||||
|
||||
+11
-86
@@ -17,7 +17,6 @@ package com.intellij.openapi.editor.impl.event;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.diff.Diff;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -29,38 +28,27 @@ public class DocumentEventImpl extends DocumentEvent {
|
||||
private final CharSequence myNewString;
|
||||
private final int myNewLength;
|
||||
|
||||
private boolean isOnlyOneLineChangedCalculated = false;
|
||||
private boolean isOnlyOneLineChanged;
|
||||
|
||||
private boolean isStartOldIndexCalculated = false;
|
||||
private int myStartOldIndex;
|
||||
|
||||
private final long myOldTimeStamp;
|
||||
private final boolean myIsWholeDocReplaced;
|
||||
private Diff.Change myChange;
|
||||
private static final Diff.Change TOO_BIG_FILE = new Diff.Change(0, 0, 0, 0, null) {
|
||||
};
|
||||
|
||||
private int myOptimizedLineShift = -1;
|
||||
private boolean myOptimizedLineShiftCalculated;
|
||||
|
||||
private int myOptimizedOldLineShift = -1;
|
||||
private boolean myOptimizedOldLineShiftCalculated;
|
||||
private final int myInitialStartOffset;
|
||||
private final int myInitialOldLength;
|
||||
|
||||
public DocumentEventImpl(@NotNull Document document,
|
||||
int offset,
|
||||
CharSequence oldString,
|
||||
CharSequence newString,
|
||||
@NotNull CharSequence oldString,
|
||||
@NotNull CharSequence newString,
|
||||
long oldTimeStamp,
|
||||
boolean wholeTextReplaced) {
|
||||
this(document, offset, oldString, newString, oldTimeStamp, wholeTextReplaced, offset, oldString == null ? 0 : oldString.length());
|
||||
this(document, offset, oldString, newString, oldTimeStamp, wholeTextReplaced, offset, oldString.length());
|
||||
}
|
||||
public DocumentEventImpl(@NotNull Document document,
|
||||
int offset,
|
||||
CharSequence oldString,
|
||||
CharSequence newString,
|
||||
@NotNull CharSequence oldString,
|
||||
@NotNull CharSequence newString,
|
||||
long oldTimeStamp,
|
||||
boolean wholeTextReplaced,
|
||||
int initialStartOffset,
|
||||
@@ -68,25 +56,18 @@ public class DocumentEventImpl extends DocumentEvent {
|
||||
super(document);
|
||||
myOffset = offset;
|
||||
|
||||
myOldString = oldString == null ? "" : oldString;
|
||||
myOldLength = myOldString.length();
|
||||
myOldString = oldString;
|
||||
myOldLength = oldString.length();
|
||||
|
||||
myNewString = newString == null ? "" : newString;
|
||||
myNewLength = myNewString.length();
|
||||
myNewString = newString;
|
||||
myNewLength = newString.length();
|
||||
|
||||
myInitialStartOffset = initialStartOffset;
|
||||
myInitialOldLength = initialOldLength;
|
||||
|
||||
myOldTimeStamp = oldTimeStamp;
|
||||
|
||||
if (getDocument().getTextLength() == 0) {
|
||||
isOnlyOneLineChangedCalculated = true;
|
||||
isOnlyOneLineChanged = false;
|
||||
myIsWholeDocReplaced = false;
|
||||
}
|
||||
else {
|
||||
myIsWholeDocReplaced = wholeTextReplaced;
|
||||
}
|
||||
myIsWholeDocReplaced = getDocument().getTextLength() != 0 && wholeTextReplaced;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -138,44 +119,12 @@ public class DocumentEventImpl extends DocumentEvent {
|
||||
return myInitialOldLength;
|
||||
}
|
||||
|
||||
public int getStartOldIndex() {
|
||||
if (isStartOldIndexCalculated) return myStartOldIndex;
|
||||
|
||||
isStartOldIndexCalculated = true;
|
||||
myStartOldIndex = getDocument().getLineNumber(myOffset);
|
||||
return myStartOldIndex;
|
||||
}
|
||||
|
||||
public boolean isOnlyOneLineChanged() {
|
||||
if (isOnlyOneLineChangedCalculated) return isOnlyOneLineChanged;
|
||||
|
||||
isOnlyOneLineChangedCalculated = true;
|
||||
isOnlyOneLineChanged = true;
|
||||
|
||||
for (int i = 0; i < myOldString.length(); i++) {
|
||||
if (myOldString.charAt(i) == '\n') {
|
||||
isOnlyOneLineChanged = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isOnlyOneLineChanged) {
|
||||
for (int i = 0; i < myNewString.length(); i++) {
|
||||
if (myNewString.charAt(i) == '\n') {
|
||||
isOnlyOneLineChanged = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return isOnlyOneLineChanged;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getOldTimeStamp() {
|
||||
return myOldTimeStamp;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
@SuppressWarnings("HardCodedStringLiteral")
|
||||
public String toString() {
|
||||
return "DocumentEventImpl[myOffset=" + myOffset + ", myOldLength=" + myOldLength + ", myNewLength=" + myNewLength +
|
||||
", myOldString='" + myOldString + "', myNewString='" + myNewString + "']" + (isWholeTextReplaced() ? " Whole." : ".");
|
||||
@@ -229,29 +178,5 @@ public class DocumentEventImpl extends DocumentEvent {
|
||||
return myChange;
|
||||
}
|
||||
|
||||
public int getOptimizedLineShift() {
|
||||
if (!myOptimizedLineShiftCalculated) {
|
||||
myOptimizedLineShiftCalculated = true;
|
||||
|
||||
if (myOldLength == 0) {
|
||||
int lineShift = StringUtil.countNewLines(myNewString);
|
||||
|
||||
myOptimizedLineShift = lineShift == 0 ? -1 : lineShift;
|
||||
}
|
||||
}
|
||||
return myOptimizedLineShift;
|
||||
}
|
||||
|
||||
public int getOptimizedOldLineShift() {
|
||||
if (!myOptimizedOldLineShiftCalculated) {
|
||||
myOptimizedOldLineShiftCalculated = true;
|
||||
|
||||
if (myNewLength == 0) {
|
||||
int lineShift = StringUtil.countNewLines(myOldString);
|
||||
|
||||
myOptimizedOldLineShift = lineShift == 0 ? -1 : lineShift;
|
||||
}
|
||||
}
|
||||
return myOptimizedOldLineShift;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,8 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.tree.ForeignLeafPsiElement;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import com.intellij.util.text.ImmutableText;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import com.intellij.util.text.ImmutableCharSequence;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
@@ -48,7 +49,7 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter {
|
||||
|
||||
private volatile Document mySyncDocument;
|
||||
|
||||
public PsiToDocumentSynchronizer(PsiDocumentManagerBase psiDocumentManager, MessageBus bus) {
|
||||
PsiToDocumentSynchronizer(PsiDocumentManagerBase psiDocumentManager, MessageBus bus) {
|
||||
myPsiDocumentManager = psiDocumentManager;
|
||||
myBus = bus;
|
||||
}
|
||||
@@ -317,13 +318,11 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter {
|
||||
}
|
||||
});
|
||||
private final PsiFile myChangeScope;
|
||||
private final ImmutableText myDocText;
|
||||
private ImmutableText myPsiText;
|
||||
private ImmutableCharSequence myPsiText;
|
||||
|
||||
public DocumentChangeTransaction(@NotNull Document doc, @NotNull PsiFile scope) {
|
||||
DocumentChangeTransaction(@NotNull Document doc, @NotNull PsiFile scope) {
|
||||
myChangeScope = scope;
|
||||
myDocText = ImmutableText.valueOf(doc.getImmutableCharSequence());
|
||||
myPsiText = myDocText;
|
||||
myPsiText = CharArrayUtil.createImmutableCharSequence(doc.getImmutableCharSequence());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -571,4 +571,9 @@ public class CharArrayUtil {
|
||||
//noinspection IOResourceOpenedButNotSafelyClosed
|
||||
return chars == null ? new CharSequenceReader(text.toString()) : new UnsyncCharArrayReader(chars, 0, text.length());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ImmutableCharSequence createImmutableCharSequence(@NotNull CharSequence sequence) {
|
||||
return ImmutableText.valueOf(sequence);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,14 @@ public abstract class ImmutableCharSequence implements CharSequence {
|
||||
|
||||
public static boolean isImmutable(@NotNull final CharSequence cs) {
|
||||
if (cs instanceof ImmutableCharSequence) return true;
|
||||
if (cs instanceof CharSequenceSubSequence) return isImmutable(((CharSequenceSubSequence)cs).getBaseSequence());
|
||||
return false;
|
||||
return cs instanceof CharSequenceSubSequence && isImmutable(((CharSequenceSubSequence)cs).getBaseSequence());
|
||||
}
|
||||
|
||||
|
||||
public abstract ImmutableCharSequence concat(CharSequence sequence);
|
||||
|
||||
public abstract ImmutableCharSequence insert(int index, CharSequence seq);
|
||||
|
||||
public abstract ImmutableCharSequence delete(int start, int end);
|
||||
|
||||
public abstract ImmutableCharSequence subtext(int start, int end);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
* @version 5.3, January 10, 2007
|
||||
*/
|
||||
@SuppressWarnings({"AssignmentToForLoopParameter","UnnecessaryThis"})
|
||||
public final class ImmutableText extends ImmutableCharSequence implements CharArrayExternalizable, CharSequenceWithStringHash {
|
||||
final class ImmutableText extends ImmutableCharSequence implements CharArrayExternalizable, CharSequenceWithStringHash {
|
||||
/**
|
||||
* Holds the default size for primitive blocks of characters.
|
||||
*/
|
||||
@@ -78,7 +78,7 @@ public final class ImmutableText extends ImmutableCharSequence implements CharAr
|
||||
* @param obj the object to represent as text.
|
||||
* @return the textual representation of the specified object.
|
||||
*/
|
||||
public static ImmutableText valueOf(@NotNull Object obj) {
|
||||
static ImmutableText valueOf(@NotNull Object obj) {
|
||||
if (obj instanceof ImmutableText) return (ImmutableText)obj;
|
||||
if (obj instanceof CharSequence) return ((CharSequence)obj).length() == 0 ? EMPTY : valueOf((CharSequence)obj);
|
||||
return valueOf(String.valueOf(obj));
|
||||
@@ -129,7 +129,7 @@ public final class ImmutableText extends ImmutableCharSequence implements CharAr
|
||||
*
|
||||
* @return a copy of this text better prepared for small modifications to fully enable structure-sharing capabilities
|
||||
*/
|
||||
public ImmutableText ensureChunked() {
|
||||
private ImmutableText ensureChunked() {
|
||||
if (length() > BLOCK_SIZE && myNode instanceof LeafNode) {
|
||||
return new ImmutableText(nodeOf((LeafNode)myNode, 0, length()));
|
||||
}
|
||||
@@ -145,22 +145,6 @@ public final class ImmutableText extends ImmutableCharSequence implements CharAr
|
||||
return new CompositeNode(nodeOf(node, offset, half), nodeOf(node, offset + half, length - half));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text representation of the <code>boolean</code> argument.
|
||||
*
|
||||
* @param b a <code>boolean</code>.
|
||||
* @return if the argument is <code>true</code>, the text
|
||||
* <code>"true"</code> is returned; otherwise, the text
|
||||
* <code>"false"</code> is returned.
|
||||
*/
|
||||
public static ImmutableText valueOf(boolean b) {
|
||||
return b ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
private static final ImmutableText TRUE = valueOf("true");
|
||||
|
||||
private static final ImmutableText FALSE = valueOf("false");
|
||||
|
||||
private static final LeafNode EMPTY_NODE = new Leaf8BitNode(ArrayUtil.EMPTY_BYTE_ARRAY);
|
||||
private static final ImmutableText EMPTY = new ImmutableText(EMPTY_NODE);
|
||||
|
||||
@@ -183,10 +167,15 @@ public final class ImmutableText extends ImmutableCharSequence implements CharAr
|
||||
* @param that the text that is concatenated.
|
||||
* @return <code>this + that</code>
|
||||
*/
|
||||
public ImmutableText concat(ImmutableText that) {
|
||||
private ImmutableText concat(ImmutableText that) {
|
||||
return that.length() == 0 ? this : length() == 0 ? that : new ImmutableText(concatNodes(ensureChunked().myNode, that.ensureChunked().myNode));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableText concat(CharSequence sequence) {
|
||||
return concat(valueOf(sequence));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a portion of this text.
|
||||
*
|
||||
@@ -209,10 +198,11 @@ public final class ImmutableText extends ImmutableCharSequence implements CharAr
|
||||
* @throws IndexOutOfBoundsException if <code>(index < 0) ||
|
||||
* (index > this.length())</code>
|
||||
*/
|
||||
public ImmutableText insert(int index, ImmutableText txt) {
|
||||
private ImmutableText insert(int index, ImmutableText txt) {
|
||||
return subtext(0, index).concat(txt).concat(subtext(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableText insert(int index, CharSequence seq) {
|
||||
return insert(index, valueOf(seq));
|
||||
}
|
||||
@@ -226,6 +216,7 @@ public final class ImmutableText extends ImmutableCharSequence implements CharAr
|
||||
* @throws IndexOutOfBoundsException if <code>(start < 0) || (end < 0) ||
|
||||
* (start > end) || (end > this.length()</code>
|
||||
*/
|
||||
@Override
|
||||
public ImmutableText delete(int start, int end) {
|
||||
if (start == end) return this;
|
||||
if (start > end) {
|
||||
@@ -333,11 +324,12 @@ public final class ImmutableText extends ImmutableCharSequence implements CharAr
|
||||
* @throws IndexOutOfBoundsException if <code>(start < 0) || (end < 0) ||
|
||||
* (start > end) || (end > this.length())</code>
|
||||
*/
|
||||
@Override
|
||||
public ImmutableText subtext(int start, int end) {
|
||||
if ((start < 0) || (start > end) || (end > length())) {
|
||||
if (start < 0 || start > end || end > length()) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
if ((start == 0) && (end == length())) {
|
||||
if (start == 0 && end == length()) {
|
||||
return this;
|
||||
}
|
||||
if (start == end) {
|
||||
@@ -405,7 +397,7 @@ public final class ImmutableText extends ImmutableCharSequence implements CharAr
|
||||
Node head = node1;
|
||||
Node tail = node2;
|
||||
|
||||
if (((head.length() << 1) < tail.length()) && tail instanceof CompositeNode) {
|
||||
if ((head.length() << 1) < tail.length() && tail instanceof CompositeNode) {
|
||||
// head too small, returns (head + tail/2) + (tail/2)
|
||||
if (((CompositeNode)tail).head.length() > ((CompositeNode)tail).tail.length()) {
|
||||
// Rotates to concatenate with smaller part.
|
||||
@@ -414,7 +406,7 @@ public final class ImmutableText extends ImmutableCharSequence implements CharAr
|
||||
head = concatNodes(head, ((CompositeNode)tail).head);
|
||||
tail = ((CompositeNode)tail).tail;
|
||||
}
|
||||
else if (((tail.length() << 1) < head.length()) && head instanceof CompositeNode) {
|
||||
else if ((tail.length() << 1) < head.length() && head instanceof CompositeNode) {
|
||||
// tail too small, returns (head/2) + (head/2 concat tail)
|
||||
if (((CompositeNode)head).tail.length() > ((CompositeNode)head).head.length()) {
|
||||
// Rotates to concatenate with smaller part.
|
||||
@@ -441,7 +433,7 @@ public final class ImmutableText extends ImmutableCharSequence implements CharAr
|
||||
|
||||
@Override
|
||||
void getChars(int start, int end, @NotNull char[] dest, int destPos) {
|
||||
if ((start < 0) || (end > length()) || (start > end)) {
|
||||
if (start < 0 || end > length() || start > end) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
System.arraycopy(data, start, dest, destPos, end - start);
|
||||
@@ -480,7 +472,7 @@ public final class ImmutableText extends ImmutableCharSequence implements CharAr
|
||||
|
||||
@Override
|
||||
void getChars(int start, int end, @NotNull char[] dest, int destPos) {
|
||||
if ((start < 0) || (end > length()) || (start > end)) {
|
||||
if (start < 0 || end > length() || start > end) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
for (int i=start;i<end;i++) {
|
||||
@@ -579,7 +571,7 @@ public final class ImmutableText extends ImmutableCharSequence implements CharAr
|
||||
if (start >= cesure) {
|
||||
return tail.subNode(start - cesure, end - cesure);
|
||||
}
|
||||
if ((start == 0) && (end == count)) {
|
||||
if (start == 0 && end == count) {
|
||||
return this;
|
||||
}
|
||||
// Overlaps head and tail.
|
||||
|
||||
Reference in New Issue
Block a user