IDEA-62161 Multi-line TODOs

use utility method to merge sorted lists (fixing a bug there) (following IDEA-CR-34406)
This commit is contained in:
Dmitry Batrak
2018-07-05 19:48:06 +03:00
parent 1f3a2c6fe9
commit 77e915ac7f
4 changed files with 81 additions and 124 deletions
@@ -25,6 +25,7 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.Processor;
import com.intellij.util.QueryExecutor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.text.CharArrayUtil;
import com.intellij.util.text.CharSequenceSubSequence;
import gnu.trove.TIntArrayList;
@@ -135,55 +136,11 @@ public class IndexPatternSearcher implements QueryExecutor<IndexPatternOccurrenc
}
private static void mergeCommentLists(List<CommentRange> target, List<CommentRange> source) {
if (target.isEmpty()) {
target.addAll(source);
return;
}
mergeSortedArrays(target, source);
}
/**
* Merge sorted points, which are sorted by x and with equal x by y.
* Result is put to x1 y1.
*/
static void mergeSortedArrays(@NotNull List<CommentRange> target, @NotNull List<CommentRange> source) {
List<CommentRange> result = new ArrayList<>();
int i = 0;
int j = 0;
while (i < target.size() && j < source.size()) {
CommentRange targetRange = target.get(i);
CommentRange sourceRange = source.get(j);
if (targetRange.startOffset < sourceRange.startOffset ||
targetRange.startOffset == sourceRange.startOffset && targetRange.endOffset < sourceRange.endOffset) {
result.add(targetRange);
i++;
}
else if (targetRange.startOffset > sourceRange.startOffset || targetRange.endOffset > sourceRange.endOffset) {
result.add(sourceRange);
j++;
}
else { //equals
result.add(targetRange);
i++;
j++;
}
}
while (i < target.size()) {
result.add(target.get(i));
i++;
}
while (j < source.size()) {
result.add(source.get(j));
j++;
}
List<CommentRange> merged = target.isEmpty()
? source
: ContainerUtil.mergeSortedLists(target, source, CommentRange.BY_START_OFFSET_THEN_BY_END_OFFSET, true);
target.clear();
target.addAll(result);
target.addAll(merged);
}
private static List<CommentRange> findComments(final Lexer lexer,
@@ -345,12 +302,15 @@ public class IndexPatternSearcher implements QueryExecutor<IndexPatternOccurrenc
return result.isEmpty() ? Collections.emptyList() : result;
}
static class CommentRange {
private static class CommentRange {
private static final Comparator<CommentRange> BY_START_OFFSET_THEN_BY_END_OFFSET =
Comparator.comparingInt((CommentRange o) -> o.startOffset).thenComparingInt((CommentRange o) -> o.endOffset);
private final int startOffset;
private final int endOffset;
private final String allowedContinuationPrefixChars;
CommentRange(int startOffset, int endOffset) {
private CommentRange(int startOffset, int endOffset) {
this(startOffset, endOffset, "");
}
@@ -359,20 +319,5 @@ public class IndexPatternSearcher implements QueryExecutor<IndexPatternOccurrenc
this.endOffset = endOffset;
allowedContinuationPrefixChars = chars;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CommentRange that = (CommentRange)o;
return startOffset == that.startOffset &&
endOffset == that.endOffset &&
Objects.equals(allowedContinuationPrefixChars, that.allowedContinuationPrefixChars);
}
@Override
public int hashCode() {
return Objects.hash(startOffset, endOffset, allowedContinuationPrefixChars);
}
}
}
@@ -2,16 +2,11 @@
package com.intellij.psi.impl.search;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.impl.search.IndexPatternSearcher.CommentRange;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.util.text.StringSearcher;
import gnu.trove.TIntArrayList;
import junit.framework.TestCase;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author yole
*/
@@ -65,52 +60,4 @@ public class LowLevelSearchUtilTest extends TestCase {
}
}).assertTiming();
}
public void testMergeSortedArrays() {
List<CommentRange> target = new ArrayList<>(Arrays.asList(
new CommentRange(0, 0),
new CommentRange(2, 2),
new CommentRange(4, 4),
new CommentRange(6, 6)
));
List<CommentRange> source = Arrays.asList(
new CommentRange(1, 1),
new CommentRange(2, 2),
new CommentRange(2, 3)
);
IndexPatternSearcher.mergeSortedArrays(target, source);
assertEquals(Arrays.asList(
new CommentRange(0, 0),
new CommentRange(1, 1),
new CommentRange(2, 2),
new CommentRange(2, 3),
new CommentRange(4, 4),
new CommentRange(6, 6)
), target);
IndexPatternSearcher.mergeSortedArrays(target, source);
assertEquals(Arrays.asList(
new CommentRange(0, 0),
new CommentRange(1, 1),
new CommentRange(2, 2),
new CommentRange(2, 3),
new CommentRange(4, 4),
new CommentRange(6, 6)
), target);
IndexPatternSearcher.mergeSortedArrays(target, Arrays.asList(
new CommentRange(-1, -1),
new CommentRange(-1, -2),
new CommentRange(-2, -3)
));
assertEquals(Arrays.asList(
new CommentRange(-1, -1),
new CommentRange(-1, -2),
new CommentRange(-2, -3),
new CommentRange(0, 0),
new CommentRange(1, 1),
new CommentRange(2, 2),
new CommentRange(2, 3),
new CommentRange(4, 4),
new CommentRange(6, 6)
), target);
}
}
@@ -16,6 +16,8 @@
package com.intellij.util.containers;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Segment;
import com.intellij.openapi.util.UnfairTextRange;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.util.ArrayUtil;
import one.util.streamex.IntStreamEx;
@@ -241,4 +243,61 @@ public class ContainerUtilTest {
List<String> actual = ContainerUtil.newArrayList(value);
assertEquals(expected, actual);
}
@Test
public void testMergeSortedLists() {
List<Segment> target = new ArrayList<>(Arrays.asList(
range(0, 0),
range(2, 2),
range(4, 4),
range(6, 6)
));
List<Segment> source = Arrays.asList(
range(1, 1),
range(2, 2),
range(2, 3)
);
target = mergeSegmentLists(target, source);
assertEquals(Arrays.asList(
range(0, 0),
range(1, 1),
range(2, 2),
range(2, 3),
range(4, 4),
range(6, 6)
), target);
target = mergeSegmentLists(target, source);
assertEquals(Arrays.asList(
range(0, 0),
range(1, 1),
range(2, 2),
range(2, 3),
range(4, 4),
range(6, 6)
), target);
target = mergeSegmentLists(target, Arrays.asList(
range(-1, -1),
range(-1, -2),
range(-2, -3)
));
assertEquals(Arrays.asList(
range(-1, -1),
range(-1, -2),
range(-2, -3),
range(0, 0),
range(1, 1),
range(2, 2),
range(2, 3),
range(4, 4),
range(6, 6)
), target);
}
private static Segment range(int start, int end) {
return new UnfairTextRange(start, end);
}
private static List<Segment> mergeSegmentLists(List<Segment> list1, List<Segment> list2) {
return ContainerUtil.mergeSortedLists(list1, list2, Segment.BY_START_OFFSET_THEN_END_OFFSET, true);
}
}
@@ -637,7 +637,18 @@ public class ContainerUtil extends ContainerUtilRt {
T element1 = list1.get(index1);
T element2 = list2.get(index2);
int c = comparator.compare(element1, element2);
if (c <= 0) {
if (c == 0) {
index1++;
index2++;
if (mergeEqualItems) {
e = element1;
}
else {
processor.consume(element1);
e = element2;
}
}
else if (c < 0) {
e = element1;
index1++;
}
@@ -645,11 +656,6 @@ public class ContainerUtil extends ContainerUtilRt {
e = element2;
index2++;
}
if (c == 0 && !mergeEqualItems) {
processor.consume(e);
index2++;
e = element2;
}
}
processor.consume(e);
}