diff --git a/java/java-tests/testSrc/com/intellij/java/find/FindInEditorTest.java b/java/java-tests/testSrc/com/intellij/java/find/FindInEditorTest.java index 8acf6b3c9fe8..cac4ef410901 100644 --- a/java/java-tests/testSrc/com/intellij/java/find/FindInEditorTest.java +++ b/java/java-tests/testSrc/com/intellij/java/find/FindInEditorTest.java @@ -24,10 +24,12 @@ import com.intellij.ui.HintHint; import com.intellij.ui.LightweightHint; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; +import org.opentest4j.AssertionFailedError; import java.awt.*; import java.io.ByteArrayOutputStream; import java.io.PrintStream; +import java.util.Arrays; public class FindInEditorTest extends LightPlatformCodeInsightTestCase { private LivePreviewController myLivePreviewController; @@ -343,4 +345,51 @@ public class FindInEditorTest extends LightPlatformCodeInsightTestCase { EditorFactory.getInstance().releaseEditor(editor); } } + + public void testSearchAreaUnion() { + SearchResults.SearchArea emptyArea = new SearchResults.SearchArea(new int[]{}, new int[]{}); + SearchResults.SearchArea area1 = new SearchResults.SearchArea(new int[]{10, 90}, new int[]{30, 95}); + SearchResults.SearchArea area2 = new SearchResults.SearchArea(new int[]{5, 25}, new int[]{15, 45}); + SearchResults.SearchArea area3 = new SearchResults.SearchArea(new int[]{5, 10, 85}, new int[]{6, 12, 90}); + + assertSameSearchAreas(area1.union(area1), area1); + assertSameSearchAreas(area2.union(area2), area2); + assertSameSearchAreas(area3.union(area3), area3); + + assertSameSearchAreas(area1.union(area2), area2.union(area1)); + assertSameSearchAreas(area1.union(area3), area3.union(area1)); + assertSameSearchAreas(area2.union(area3), area3.union(area2)); + + assertSameSearchAreas(new SearchResults.SearchArea(new int[]{5, 90}, new int[]{45, 95}), + area1.union(area2)); + assertSameSearchAreas(new SearchResults.SearchArea(new int[]{5, 10, 85}, new int[]{6, 30, 95}), + area1.union(area3)); + assertSameSearchAreas(new SearchResults.SearchArea(new int[]{5, 25, 85}, new int[]{15, 45, 90}), + area2.union(area3)); + + assertSameSearchAreas(new SearchResults.SearchArea(new int[]{5, 85}, new int[]{45, 95}), + area1.union(area2).union(area3)); + + assertSameSearchAreas(emptyArea, emptyArea.union(emptyArea)); + assertSameSearchAreas(area1, emptyArea.union(area1)); + assertSameSearchAreas(area1, area1.union(emptyArea)); + } + + private static void assertSameSearchAreas(SearchResults.SearchArea expected, + SearchResults.SearchArea actual) { + if (Arrays.equals(expected.startOffsets(), actual.startOffsets()) && + Arrays.equals(expected.endOffsets(), actual.endOffsets())) { + return; + } + + throw new AssertionFailedError(null, + "startOffsets:\n" + + StringUtil.join(expected.startOffsets(), "\n") + + "\n\nendOffsets:\n" + + StringUtil.join(expected.endOffsets(), "\n"), + "startOffsets:\n" + + StringUtil.join(actual.startOffsets(), "\n") + + "\n\nendOffsets:\n" + + StringUtil.join(actual.endOffsets(), "\n")); + } } diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java index e9eb42fc2d44..9a212e486f89 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java +++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java @@ -7,6 +7,7 @@ import com.intellij.find.FindModel; import com.intellij.find.FindResult; import com.intellij.find.FindUtil; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Caret; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; @@ -28,6 +29,8 @@ import com.intellij.util.concurrency.annotations.RequiresEdt; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.Stack; import com.intellij.util.ui.UIUtil; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -275,58 +278,67 @@ public class SearchResults implements DocumentListener, CaretListener { /** * Merges the given {@link SearchArea} with the current one. - *
- * If the given areas intersect - union area will be returned. - * If the given areas have no intersection - area contains all the given areas will be returned. - * - * @param area the area to merge with the current - * @return a new merged area */ - public @NotNull SearchArea merge(@NotNull SearchArea area) { - int[] startOffsets1 = startOffsets; - int[] endOffsets1 = endOffsets; + public @NotNull SearchArea union(@NotNull SearchArea area) { + int[] mergedStartOffsets = ArrayUtil.mergeArrays(startOffsets, area.startOffsets); + int[] mergedEndOffsets = ArrayUtil.mergeArrays(endOffsets, area.endOffsets); + Arrays.sort(mergedStartOffsets); + Arrays.sort(mergedEndOffsets); - int[] startOffsets2 = area.startOffsets; - int[] endOffsets2 = area.endOffsets; + final IntList resultStartOffsets = new IntArrayList(mergedStartOffsets.length); + final IntList resultEndOffsets = new IntArrayList(mergedStartOffsets.length); - List