diff options
author | Paul Pazderski | 2019-03-14 21:06:46 +0000 |
---|---|---|
committer | Paul Pazderski | 2019-09-15 14:12:16 +0000 |
commit | f15d5f441d9ae8cc24de9ec34fd39b04520917b5 (patch) | |
tree | aa3bd91a0d72b320b6e42fe27a4618048dc42560 | |
parent | 881615b60a5da2db70cb86a969e26d791c64d473 (diff) | |
download | eclipse.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.java | 91 | ||||
-rw-r--r-- | org.eclipse.ui.console/src/org/eclipse/ui/internal/console/IOConsolePartitioner.java | 19 |
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; |