Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Pazderski2019-03-14 21:06:46 +0000
committerPaul Pazderski2019-09-15 14:12:16 +0000
commitf15d5f441d9ae8cc24de9ec34fd39b04520917b5 (patch)
treeaa3bd91a0d72b320b6e42fe27a4618048dc42560
parent881615b60a5da2db70cb86a969e26d791c64d473 (diff)
downloadeclipse.platform.debug-f15d5f441d9ae8cc24de9ec34fd39b04520917b5.tar.gz
eclipse.platform.debug-f15d5f441d9ae8cc24de9ec34fd39b04520917b5.tar.xz
eclipse.platform.debug-f15d5f441d9ae8cc24de9ec34fd39b04520917b5.zip
Bug 550618 - [console] IOConsolePartitioner produces overlapping styleI20190915-1800
ranges Old implementation adjusted range start but did not touch the ranges length resulting in invalid overlapping ranges. Change-Id: Ie6cf1289a62a4d63f46b682b67bc72cd2d223bd2 Signed-off-by: Paul Pazderski <paul-eclipse@ppazderski.de>
-rw-r--r--org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/IOConsoleTests.java91
-rw-r--r--org.eclipse.ui.console/src/org/eclipse/ui/internal/console/IOConsolePartitioner.java19
2 files changed, 107 insertions, 3 deletions
diff --git a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/IOConsoleTests.java b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/IOConsoleTests.java
index 031f3c473..213f1aefa 100644
--- a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/IOConsoleTests.java
+++ b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/IOConsoleTests.java
@@ -18,6 +18,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
@@ -31,6 +32,7 @@ import org.eclipse.debug.tests.AbstractDebugTest;
import org.eclipse.debug.tests.TestUtil;
import org.eclipse.debug.tests.TestsPlugin;
import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
@@ -39,6 +41,7 @@ import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleConstants;
+import org.eclipse.ui.console.IConsoleDocumentPartitioner;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.IOConsole;
import org.eclipse.ui.console.IOConsoleOutputStream;
@@ -415,4 +418,92 @@ public class IOConsoleTests extends AbstractDebugTest {
closeConsole(c);
assertEquals("Test triggered errors in IOConsole.", 0, loggedErrors.get());
}
+
+ /**
+ * Tests for the {@link IConsoleDocumentPartitioner} interface.
+ */
+ public void testIConsoleDocumentPartitioner() throws Exception {
+ final IOConsoleTestUtil c = getTestUtil("Test IConsoleDocumentPartitioner");
+ try (IOConsoleOutputStream otherOut = c.getConsole().newOutputStream()) {
+ StyleRange[] styles = c.getPartitioner().getStyleRanges(0, 1);
+ assertEquals("Got fake styles.", 0, (styles == null ? 0 : styles.length));
+
+ c.insertAndVerify("#\n");
+ c.insertTyping("L");
+ c.writeFast("orem ipsum dolor sit amet, consetetur sadipscing elitr,\n");
+ c.writeFast("sed diam nonumy eirmod tempor invidunt ut labore et dolore\n", otherOut);
+ c.writeFast("magna aliquyam erat, sed diam voluptua. At vero eos et accusam\n");
+ c.writeFast("et justo duo dolores et ea rebum. Stet clita kasd gubergren,\n", otherOut);
+ c.write("no sea takimata sanctus est Lorem ipsum dolor sit amet.\n");
+ final int loremEnd = c.getContentLength();
+ c.moveCaretToEnd().insertTypingAndVerify("--").writeAndVerify("ooo");
+ c.setCaretLineRelative(1).insertTypingAndVerify("-");
+ c.verifyContentByLine("---ooo", -1);
+
+
+ styles = c.getPartitioner().getStyleRanges(0, c.getContentLength());
+ checkOverlapping(styles);
+ assertNotNull("Partitioner provided no styles.", styles);
+ assertTrue("Expected more styles.", styles.length >= 3);
+
+ styles = c.getPartitioner().getStyleRanges(5, 20);
+ checkOverlapping(styles);
+ assertNotNull("Partitioner provided no styles.", styles);
+ assertEquals("Number of styles:", 1, styles.length);
+
+ styles = c.getPartitioner().getStyleRanges(loremEnd + 1, 1);
+ checkOverlapping(styles);
+ assertNotNull("Partitioner provided no styles.", styles);
+ assertEquals("Number of styles:", 1, styles.length);
+
+ styles = c.getPartitioner().getStyleRanges(loremEnd, c.getContentLength() - loremEnd);
+ checkOverlapping(styles);
+ assertNotNull("Partitioner provided no styles.", styles);
+ assertEquals("Number of styles:", 2, styles.length);
+
+ styles = c.getPartitioner().getStyleRanges(loremEnd - 3, 5);
+ checkOverlapping(styles);
+ assertNotNull("Partitioner provided no styles.", styles);
+ assertEquals("Number of styles:", 2, styles.length);
+
+ styles = c.getPartitioner().getStyleRanges(loremEnd - 3, 8);
+ checkOverlapping(styles);
+ assertNotNull("Partitioner provided no styles.", styles);
+ assertEquals("Number of styles:", 3, styles.length);
+
+
+ assertTrue("Offset should be read-only.", c.getPartitioner().isReadOnly(0));
+ assertTrue("Offset should be read-only.", c.getPartitioner().isReadOnly(1));
+ assertFalse("Offset should be writable.", c.getPartitioner().isReadOnly(2));
+ for (int i = 3; i < loremEnd; i++) {
+ assertTrue("Offset should be read-only.", c.getPartitioner().isReadOnly(i));
+ }
+ assertFalse("Offset should be writable.", c.getPartitioner().isReadOnly(loremEnd + 0));
+ assertFalse("Offset should be writable.", c.getPartitioner().isReadOnly(loremEnd + 1));
+ assertFalse("Offset should be writable.", c.getPartitioner().isReadOnly(loremEnd + 2));
+ assertTrue("Offset should be read-only.", c.getPartitioner().isReadOnly(loremEnd + 3));
+ assertTrue("Offset should be read-only.", c.getPartitioner().isReadOnly(loremEnd + 4));
+ assertTrue("Offset should be read-only.", c.getPartitioner().isReadOnly(loremEnd + 5));
+ }
+ c.verifyPartitions();
+ closeConsole(c, "#");
+ assertEquals("Test triggered errors in IOConsole.", 0, loggedErrors.get());
+ }
+
+ /**
+ * Check if there is any offset which received two styles.
+ *
+ * @param styles the styles to check
+ */
+ private void checkOverlapping(StyleRange[] styles) {
+ if (styles == null || styles.length <= 1) {
+ return;
+ }
+ Arrays.sort(styles, (a, b) -> Integer.compare(a.start, b.start));
+ int lastEnd = Integer.MIN_VALUE;
+ for (StyleRange s : styles) {
+ assertTrue("Styles overlap.", lastEnd <= s.start);
+ lastEnd = s.start + s.length;
+ }
+ }
}
diff --git a/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/IOConsolePartitioner.java b/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/IOConsolePartitioner.java
index 81aac3846..67e7b8e1c 100644
--- a/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/IOConsolePartitioner.java
+++ b/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/IOConsolePartitioner.java
@@ -13,6 +13,7 @@
* Paul Pazderski - Contributions for:
* Bug 547064: use binary search for getPartition
* Bug 548356: fixed user input handling
+ * Bug 550618: getStyleRanges produced invalid overlapping styles
*******************************************************************************/
package org.eclipse.ui.internal.console;
@@ -772,11 +773,23 @@ public class IOConsolePartitioner implements IConsoleDocumentPartitioner, IDocum
if (!connected) {
return new StyleRange[0];
}
- IOConsolePartition[] computedPartitions = computeIOPartitioning(offset, length);
- StyleRange[] styles = new StyleRange[computedPartitions.length];
+ final IOConsolePartition[] computedPartitions = computeIOPartitioning(offset, length);
+ final StyleRange[] styles = new StyleRange[computedPartitions.length];
for (int i = 0; i < computedPartitions.length; i++) {
- int rangeStart = Math.max(computedPartitions[i].getOffset(), offset);
+ int rangeStart = computedPartitions[i].getOffset();
int rangeLength = computedPartitions[i].getLength();
+
+ // snap partitions to requested range
+ final int underflow = offset - rangeStart;
+ if (underflow > 0) {
+ rangeStart += underflow;
+ rangeLength -= underflow;
+ }
+ final int overflow = (rangeStart + rangeLength) - (offset + length);
+ if (overflow > 0) {
+ rangeLength -= overflow;
+ }
+
styles[i] = computedPartitions[i].getStyleRange(rangeStart, rangeLength);
}
return styles;

Back to the top