diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/AbstractPairMatcherTest.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/AbstractPairMatcherTest.java index 1d6e394..1a4690a 100644 --- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/AbstractPairMatcherTest.java +++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/AbstractPairMatcherTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2008 IBM Corporation and others. + * Copyright (c) 2006, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -15,7 +15,6 @@ import junit.framework.TestCase; -import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentPartitioner; @@ -43,6 +42,8 @@ */ protected abstract ICharacterPairMatcher createMatcher(final String chars); + protected abstract void checkResult(PairMatcherTestCase test, IRegion region, boolean isForward); + /** * Returns the partitioning treated by the matcher. * @@ -58,158 +59,6 @@ super(); } - /* --- T e s t s --- */ - - /** Tests that the test case reader works */ - public void testTestCaseReader() { - performReaderTest("#( )%", 3, 0, "( )"); - performReaderTest("%( )#", 0, 3, "( )"); - performReaderTest("( )%", 3, -1, "( )"); - performReaderTest("#%", 0, 0, ""); - } - - /** - * Very simple checks. - * - * @throws BadLocationException - */ - public void testSimpleMatchSameMatcher() throws BadLocationException { - final ICharacterPairMatcher matcher= createMatcher("()[]{}"); - performMatch(matcher, "#( )%"); - performMatch(matcher, "#[ ]%"); - performMatch(matcher, "#{ }%"); - performMatch(matcher, "(% )#"); - performMatch(matcher, "[% ]#"); - performMatch(matcher, "{% }#"); - matcher.dispose(); - } - - /** - * Very simple checks. - * - * @throws BadLocationException - */ - public void testSimpleMatchDifferentMatchers() throws BadLocationException { - performMatch("()[]{}", "#( )%"); - performMatch("()[]{}", "#[ ]%"); - performMatch("()[]{}", "#{ }%"); - performMatch("()[]{}", "(% )#"); - performMatch("()[]{}", "[% ]#"); - performMatch("()[]{}", "{% }#"); - } - - /** - * Close matches. - * - * @throws BadLocationException - */ - public void testCloseMatches() throws BadLocationException { - final ICharacterPairMatcher matcher= createMatcher("()[]{}"); - performMatch(matcher, "#()%"); - performMatch(matcher, "(%)#"); - performMatch(matcher, "#(())%"); - performMatch(matcher, "(%())#"); - performMatch(matcher, "((%)#)"); - performMatch(matcher, "(#()%)"); - matcher.dispose(); - } - - - /** - * Checks of simple situations where no matches should be found. - * - * @throws BadLocationException - */ - public void testIncompleteMatch() throws BadLocationException { - final ICharacterPairMatcher matcher= createMatcher("()[]{}"); - performMatch(matcher, "(% "); - performMatch(matcher, "%( )"); - performMatch(matcher, "( % )"); - performMatch(matcher, "( %)"); - performMatch(matcher, "%"); - matcher.dispose(); - } - - /** - * Test that it doesn't match across different partitions. - * - * @throws BadLocationException - */ - public void testPartitioned() throws BadLocationException { - final ICharacterPairMatcher matcher= createMatcher("()[]{}"); - performMatch(matcher, "(% |a a| )#"); - performMatch(matcher, "#( |a a| )%"); - performMatch(matcher, "|b #( )% b|"); - performMatch(matcher, "( |b )% b|"); - performMatch(matcher, "(% |b ) b|"); - performMatch(matcher, "|a ( a| )%"); - performMatch(matcher, "|a (% a| )"); - performMatch(matcher, "|c #( c| ) ( |c )% c|"); - performMatch(matcher, "|c (% c| ) ( |c )# c|"); - performMatch(matcher, "(% |a ) a| |b ) b| |c ) c| )#"); - matcher.dispose(); - } - - /** - * Test that it works properly next to partition boundaries. - * - * @throws BadLocationException - */ - public void testTightPartitioned() throws BadLocationException { - final ICharacterPairMatcher matcher= createMatcher("()[]{}"); - performMatch(matcher, "(|b)%b|"); - performMatch(matcher, "(%|b)b|"); - performMatch(matcher, "|a(a|)%"); - performMatch(matcher, "|a(%a|)"); - performMatch(matcher, "|c#(c|)(|c)%c|"); - performMatch(matcher, "|c(%c|)(|c)#c|"); - performMatch(matcher, "(%|a)a||b)b||c)c|)#"); - matcher.dispose(); - } - - /** Test that nesting works properly */ - public void testNesting() { - final ICharacterPairMatcher matcher= createMatcher("()[]{}"); - performMatch(matcher, " ( #( ( ( ) ) ( ) )% ) "); - performMatch(matcher, " ( (% ( ( ) ) ( ) )# ) "); - performMatch(matcher, " ( #( { ( ) } [ ] )% ) "); - performMatch(matcher, " ( (% { ( ) } [ ] )# ) "); - performMatch(matcher, " ( ( #{ ( ) }% [ ] ) ) "); - performMatch(matcher, " ( ( {% ( ) }# [ ] ) ) "); - performMatch(matcher, "a(b#(c(d(e)f)g(h)i)%j)k"); - performMatch(matcher, "a(b(%c(d(e)f)g(h)i)#j)k"); - performMatch(matcher, "a(b#(c{d(e)f}g[h]i)%j)k"); - performMatch(matcher, "a(b(%c{d(e)f}g[h]i)#j)k"); - performMatch(matcher, "a(b(c#{d(e)f}%g[h]i)j)k"); - performMatch(matcher, "a(b(c{%d(e)f}#g[h]i)j)k"); - matcher.dispose(); - } - - /** - * Test a few boundary conditions. - * - * * @throws BadLocationException - */ - public void testBoundaries() throws BadLocationException { - final ICharacterPairMatcher matcher= createMatcher("()[]{}"); - final StringDocument doc= new StringDocument("abcdefghijkl"); - assertNull(matcher.match(null, 0)); - assertNull(matcher.match(doc, -1)); - assertNull(matcher.match(doc, doc.getLength() + 1)); - matcher.dispose(); - } - - public void testBug156426() { - final ICharacterPairMatcher matcher= createMatcher("()[]{}<>"); - performMatch(matcher, " #( a < b )% "); - performMatch(matcher, " (% a < b )# "); - performMatch(matcher, " #( a > b )% "); - performMatch(matcher, " (% a > b )# "); - matcher.dispose(); - } - - /* --- U t i l i t i e s --- */ - /** * Checks that the test case reader reads the test case as specified. * @@ -218,8 +67,8 @@ * @param expectedMatch the expected match * @param expectedString the expected string */ - private void performReaderTest(String testString, int expectedPos, int expectedMatch, String expectedString) { - TestCase t0= createTestCase(testString); + protected void performReaderTest(String testString, int expectedPos, int expectedMatch, String expectedString) { + PairMatcherTestCase t0= createTestCase(testString); assertEquals(expectedPos, t0.fPos); assertEquals(expectedMatch, t0.fMatch); assertEquals(expectedString, t0.fString); @@ -232,7 +81,7 @@ * @param testCase the test string */ protected void performMatch(final ICharacterPairMatcher matcher, final String testCase) { - final TestCase test= createTestCase(testCase); + final PairMatcherTestCase test= createTestCase(testCase); matcher.clear(); final IRegion region= matcher.match(test.getDocument(), test.fPos); if (test.fMatch == -1) { @@ -244,17 +93,11 @@ assertNotNull(region); final boolean isForward= test.fPos > test.fMatch; assertEquals(isForward, matcher.getAnchor() == ICharacterPairMatcher.RIGHT); - // If the match is forward, the curser is one character - // after the start of the match, so we need to count one - // step backwards - final int offset= isForward ? test.getOffset() : test.getOffset() - 1; - final int length= isForward ? test.getLength() : test.getLength() + 1; - assertEquals(length, region.getLength()); - assertEquals(offset, region.getOffset()); + checkResult(test, region, isForward); } } - private void performMatch(final String delims, final String testCase) { + protected void performMatch(final String delims, final String testCase) { final ICharacterPairMatcher matcher= createMatcher(delims); performMatch(matcher, testCase); matcher.dispose(); @@ -267,7 +110,7 @@ * @param str the string for which to create the test case * @return the created test case */ - public TestCase createTestCase(String str) { + public PairMatcherTestCase createTestCase(String str) { int pos= str.indexOf("%"); assertFalse(pos == -1); int match= str.indexOf("#"); @@ -276,15 +119,15 @@ if (match != -1 && match < pos) pos -= 1; if (pos < match) match -= 1; final String stripped= str.replaceAll("%", "").replaceAll("#", ""); - return new TestCase(stripped, pos, match); + return new PairMatcherTestCase(stripped, pos, match); } - private class TestCase { + public class PairMatcherTestCase { public final String fString; public final int fPos, fMatch; - public TestCase(String string, int pos, int match) { + public PairMatcherTestCase(String string, int pos, int match) { fString= string; fPos= pos; fMatch= match; @@ -305,7 +148,7 @@ } - private class StringDocument extends Document { + class StringDocument extends Document { public StringDocument(String str) { this.setTextStore(new StringTextStore(str)); diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DefaultPairMatcherTest.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DefaultPairMatcherTest.java index a59d0ec..0dfc191 100644 --- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DefaultPairMatcherTest.java +++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DefaultPairMatcherTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2008 IBM Corporation and others. + * Copyright (c) 2006, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -13,7 +13,9 @@ import junit.framework.Test; import junit.framework.TestSuite; +import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocumentExtension3; +import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.source.DefaultCharacterPairMatcher; import org.eclipse.jface.text.source.ICharacterPairMatcher; @@ -29,8 +31,7 @@ } protected ICharacterPairMatcher createMatcher(String chars) { - return new DefaultCharacterPairMatcher(chars.toCharArray(), - getDocumentPartitioning()); + return new DefaultCharacterPairMatcher(chars.toCharArray(), getDocumentPartitioning(), false); } /* @@ -41,4 +42,157 @@ return IDocumentExtension3.DEFAULT_PARTITIONING; } + /** Tests that the test case reader works */ + public void testTestCaseReader() { + performReaderTest("#( )%", 3, 0, "( )"); + performReaderTest("%( )#", 0, 3, "( )"); + performReaderTest("( )%", 3, -1, "( )"); + performReaderTest("#%", 0, 0, ""); + } + + /** + * Very simple checks. + * + * @throws BadLocationException + */ + public void testSimpleMatchSameMatcher() throws BadLocationException { + final ICharacterPairMatcher matcher= createMatcher("()[]{}"); + performMatch(matcher, "#( )%"); + performMatch(matcher, "#[ ]%"); + performMatch(matcher, "#{ }%"); + performMatch(matcher, "(% )#"); + performMatch(matcher, "[% ]#"); + performMatch(matcher, "{% }#"); + matcher.dispose(); + } + + /** + * Very simple checks. + * + * @throws BadLocationException + */ + public void testSimpleMatchDifferentMatchers() throws BadLocationException { + performMatch("()[]{}", "#( )%"); + performMatch("()[]{}", "#[ ]%"); + performMatch("()[]{}", "#{ }%"); + performMatch("()[]{}", "(% )#"); + performMatch("()[]{}", "[% ]#"); + performMatch("()[]{}", "{% }#"); + } + + /** + * Close matches. + * + * @throws BadLocationException + */ + public void testCloseMatches() throws BadLocationException { + final ICharacterPairMatcher matcher= createMatcher("()[]{}"); + performMatch(matcher, "#()%"); + performMatch(matcher, "(%)#"); + performMatch(matcher, "#(())%"); + performMatch(matcher, "(%())#"); + performMatch(matcher, "((%)#)"); + performMatch(matcher, "(#()%)"); + matcher.dispose(); + } + + /** + * Checks of simple situations where no matches should be found. + * + * @throws BadLocationException + */ + public void testIncompleteMatch() throws BadLocationException { + final ICharacterPairMatcher matcher= createMatcher("()[]{}"); + performMatch(matcher, "(% "); + performMatch(matcher, "%( )"); + performMatch(matcher, "( % )"); + performMatch(matcher, "( %)"); + performMatch(matcher, "%"); + matcher.dispose(); + } + + /** + * Test that it doesn't match across different partitions. + * + * @throws BadLocationException + */ + public void testPartitioned() throws BadLocationException { + final ICharacterPairMatcher matcher= createMatcher("()[]{}"); + performMatch(matcher, "(% |a a| )#"); + performMatch(matcher, "#( |a a| )%"); + performMatch(matcher, "|b #( )% b|"); + performMatch(matcher, "( |b )% b|"); + performMatch(matcher, "(% |b ) b|"); + performMatch(matcher, "|a ( a| )%"); + performMatch(matcher, "|a (% a| )"); + performMatch(matcher, "|c #( c| ) ( |c )% c|"); + performMatch(matcher, "|c (% c| ) ( |c )# c|"); + performMatch(matcher, "(% |a ) a| |b ) b| |c ) c| )#"); + matcher.dispose(); + } + + /** + * Test that it works properly next to partition boundaries. + * + * @throws BadLocationException + */ + public void testTightPartitioned() throws BadLocationException { + final ICharacterPairMatcher matcher= createMatcher("()[]{}"); + performMatch(matcher, "(|b)%b|"); + performMatch(matcher, "(%|b)b|"); + performMatch(matcher, "|a(a|)%"); + performMatch(matcher, "|a(%a|)"); + performMatch(matcher, "|c#(c|)(|c)%c|"); + performMatch(matcher, "|c(%c|)(|c)#c|"); + performMatch(matcher, "(%|a)a||b)b||c)c|)#"); + matcher.dispose(); + } + + /** Test that nesting works properly */ + public void testNesting() { + final ICharacterPairMatcher matcher= createMatcher("()[]{}"); + performMatch(matcher, " ( #( ( ( ) ) ( ) )% ) "); + performMatch(matcher, " ( (% ( ( ) ) ( ) )# ) "); + performMatch(matcher, " ( #( { ( ) } [ ] )% ) "); + performMatch(matcher, " ( (% { ( ) } [ ] )# ) "); + performMatch(matcher, " ( ( #{ ( ) }% [ ] ) ) "); + performMatch(matcher, " ( ( {% ( ) }# [ ] ) ) "); + performMatch(matcher, "a(b#(c(d(e)f)g(h)i)%j)k"); + performMatch(matcher, "a(b(%c(d(e)f)g(h)i)#j)k"); + performMatch(matcher, "a(b#(c{d(e)f}g[h]i)%j)k"); + performMatch(matcher, "a(b(%c{d(e)f}g[h]i)#j)k"); + performMatch(matcher, "a(b(c#{d(e)f}%g[h]i)j)k"); + performMatch(matcher, "a(b(c{%d(e)f}#g[h]i)j)k"); + matcher.dispose(); + } + + /** + * Test a few boundary conditions. + * + * * @throws BadLocationException + */ + public void testBoundaries() throws BadLocationException { + final ICharacterPairMatcher matcher= createMatcher("()[]{}"); + final StringDocument doc= new StringDocument("abcdefghijkl"); + assertNull(matcher.match(null, 0)); + assertNull(matcher.match(doc, -1)); + assertNull(matcher.match(doc, doc.getLength() + 1)); + matcher.dispose(); + } + + public void testBug156426() { + final ICharacterPairMatcher matcher= createMatcher("()[]{}<>"); + performMatch(matcher, " #( a < b )% "); + performMatch(matcher, " (% a < b )# "); + performMatch(matcher, " #( a > b )% "); + performMatch(matcher, " (% a > b )# "); + matcher.dispose(); + } + + protected void checkResult(final PairMatcherTestCase test, final IRegion region, final boolean isForward) { + final int offset= isForward ? test.getOffset() : test.getOffset() - 1; + final int length= isForward ? test.getLength() : test.getLength() + 1; + assertEquals(length, region.getLength()); + assertEquals(offset, region.getOffset()); + } } diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DefaultPairMatcherTest2.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DefaultPairMatcherTest2.java new file mode 100644 index 0000000..cf44b41 --- /dev/null +++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DefaultPairMatcherTest2.java @@ -0,0 +1,196 @@ +/******************************************************************************* + * Copyright (c) 2012 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.text.tests; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocumentExtension3; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.source.DefaultCharacterPairMatcher; +import org.eclipse.jface.text.source.ICharacterPairMatcher; + +/** + * Tests for the default pair matcher. + * + * @since 3.8 + */ +public class DefaultPairMatcherTest2 extends AbstractPairMatcherTest { + + public static Test suite() { + return new TestSuite(DefaultPairMatcherTest2.class); + } + + protected ICharacterPairMatcher createMatcher(String chars) { + return new DefaultCharacterPairMatcher(chars.toCharArray(), getDocumentPartitioning(), true); + } + + /* + * @see org.eclipse.jface.text.tests.AbstractPairMatcherTest#getDocumentPartitioning() + * @since 3.3 + */ + protected String getDocumentPartitioning() { + return IDocumentExtension3.DEFAULT_PARTITIONING; + } + + /** Tests that the test case reader works */ + public void testTestCaseReader() { + performReaderTest("#( %)", 2, 0, "( )"); + performReaderTest("%( )#", 0, 3, "( )"); + performReaderTest("( %)", 2, -1, "( )"); + performReaderTest("#%", 0, 0, ""); + } + + /** + * Very simple checks. + * + * @throws BadLocationException + */ + public void testSimpleMatchSameMatcher() throws BadLocationException { + final ICharacterPairMatcher matcher= createMatcher("()[]{}"); + performMatch(matcher, "#( %)"); + performMatch(matcher, "#[ %]"); + performMatch(matcher, "#{ %}"); + performMatch(matcher, "(% )#"); + performMatch(matcher, "[% ]#"); + performMatch(matcher, "{% }#"); + matcher.dispose(); + } + + /** + * Very simple checks. + * + * @throws BadLocationException + */ + public void testSimpleMatchDifferentMatchers() throws BadLocationException { + performMatch("()[]{}", "#( %)"); + performMatch("()[]{}", "#[ %]"); + performMatch("()[]{}", "#{ %}"); + performMatch("()[]{}", "(% )#"); + performMatch("()[]{}", "[% ]#"); + performMatch("()[]{}", "{% }#"); + } + + /** + * Close matches. + * + * @throws BadLocationException + */ + public void testCloseMatches() throws BadLocationException { + final ICharacterPairMatcher matcher= createMatcher("()[]{}"); + performMatch(matcher, "(%)#"); + performMatch(matcher, "#(()%)"); + performMatch(matcher, "(%())#"); + performMatch(matcher, "((%)#)"); + matcher.dispose(); + } + + /** + * Checks of simple situations where no matches should be found. + * + * @throws BadLocationException + */ + public void testIncompleteMatch() throws BadLocationException { + final ICharacterPairMatcher matcher= createMatcher("()[]{}"); + performMatch(matcher, "(% "); + performMatch(matcher, "%( )"); + performMatch(matcher, "( % )"); + performMatch(matcher, "( )%"); + performMatch(matcher, "%"); + matcher.dispose(); + } + + /** + * Test that it doesn't match across different partitions. + * + * @throws BadLocationException + */ + public void testPartitioned() throws BadLocationException { + final ICharacterPairMatcher matcher= createMatcher("()[]{}"); + performMatch(matcher, "(% |a a| )#"); + performMatch(matcher, "#( |a a| %)"); + performMatch(matcher, "|b #( %) b|"); + performMatch(matcher, "( |b %) b|"); + performMatch(matcher, "(% |b ) b|"); + performMatch(matcher, "|a ( a| %)"); + performMatch(matcher, "|a (% a| )"); + performMatch(matcher, "|c #( c| ) ( |c %) c|"); + performMatch(matcher, "|c (% c| ) ( |c )# c|"); + performMatch(matcher, "(% |a ) a| |b ) b| |c ) c| )#"); + matcher.dispose(); + } + + /** + * Test that it works properly next to partition boundaries. + * + * @throws BadLocationException + */ + public void testTightPartitioned() throws BadLocationException { + final ICharacterPairMatcher matcher= createMatcher("()[]{}"); + performMatch(matcher, "(|b%)b|"); + performMatch(matcher, "(%|b)b|"); + performMatch(matcher, "|a(a|%)"); + performMatch(matcher, "|a(%a|)"); + performMatch(matcher, "|c#(c|)(|c%)c|"); + performMatch(matcher, "|c(%c|)(|c)#c|"); + performMatch(matcher, "(%|a)a||b)b||c)c|)#"); + matcher.dispose(); + } + + /** Test that nesting works properly */ + public void testNesting() { + final ICharacterPairMatcher matcher= createMatcher("()[]{}"); + performMatch(matcher, " ( #( ( ( ) ) ( ) %) ) "); + performMatch(matcher, " ( (% ( ( ) ) ( ) )# ) "); + performMatch(matcher, " ( #( { ( ) } [ ] %) ) "); + performMatch(matcher, " ( (% { ( ) } [ ] )# ) "); + performMatch(matcher, " ( ( #{ ( ) %} [ ] ) ) "); + performMatch(matcher, " ( ( {% ( ) }# [ ] ) ) "); + performMatch(matcher, "a(b#(c(d(e)f)g(h)i%)j)k"); + performMatch(matcher, "a(b(%c(d(e)f)g(h)i)#j)k"); + performMatch(matcher, "a(b#(c{d(e)f}g[h]i%)j)k"); + performMatch(matcher, "a(b(%c{d(e)f}g[h]i)#j)k"); + performMatch(matcher, "a(b(c#{d(e)f%}g[h]i)j)k"); + performMatch(matcher, "a(b(c{%d(e)f}#g[h]i)j)k"); + matcher.dispose(); + } + + /** + * Test a few boundary conditions. + * + * * @throws BadLocationException + */ + public void testBoundaries() throws BadLocationException { + final ICharacterPairMatcher matcher= createMatcher("()[]{}"); + final StringDocument doc= new StringDocument("abcdefghijkl"); + assertNull(matcher.match(null, 0)); + assertNull(matcher.match(doc, -1)); + assertNull(matcher.match(doc, doc.getLength() + 1)); + matcher.dispose(); + } + + public void testBug156426() { + final ICharacterPairMatcher matcher= createMatcher("()[]{}<>"); + performMatch(matcher, " #( a < b %) "); + performMatch(matcher, " (% a < b )# "); + performMatch(matcher, " #( a > b %) "); + performMatch(matcher, " (% a > b )# "); + matcher.dispose(); + } + + protected void checkResult(final PairMatcherTestCase test, final IRegion region, final boolean isForward) { + final int offset= isForward ? test.getOffset() : test.getOffset() - 1; + final int length= test.getLength() + 1; + assertEquals(length, region.getLength()); + assertEquals(offset, region.getOffset()); + } +} diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/DefaultCharacterPairMatcher.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/DefaultCharacterPairMatcher.java index 6c8e26c..7b4b9e6 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/DefaultCharacterPairMatcher.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/DefaultCharacterPairMatcher.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 IBM Corporation and others. + * Copyright (c) 2006, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -34,6 +34,7 @@ private int fAnchor= -1; private final CharPairs fPairs; private final String fPartitioning; + private final boolean fCaretInsideMatchedPair; /** * Creates a new character pair matcher that matches the specified characters within the @@ -50,10 +51,34 @@ * @param partitioning the partitioning to match within */ public DefaultCharacterPairMatcher(char[] chars, String partitioning) { + this(chars, partitioning, false); + } + + /** + * Creates a new character pair matcher that matches the specified characters within the + * specified partitioning. The specified list of characters must have the form
{ + * start, end, start, end, ..., start, end + * }
For instance: + * + *
+	 * char[] chars = new char[] {'(', ')', '{', '}', '[', ']'};
+	 * new DefaultCharacterPairMatcher(chars, ...);
+	 * 
+ * + * @param chars a list of characters + * @param partitioning the partitioning to match within + * @param caretInsideMatchedPair controls the matching behavior. When true, the + * matching start peer will be found when the caret is placed before the end + * character. When false, the matching start peer will be found when the + * caret is placed after the end character. + * @since 3.8 + */ + public DefaultCharacterPairMatcher(char[] chars, String partitioning, boolean caretInsideMatchedPair) { Assert.isLegal(chars.length % 2 == 0); Assert.isNotNull(partitioning); fPairs= new CharPairs(chars); fPartitioning= partitioning; + fCaretInsideMatchedPair= caretInsideMatchedPair; } /** @@ -86,21 +111,36 @@ * Performs the actual work of matching for #match(IDocument, int). */ private IRegion performMatch(IDocument doc, int caretOffset) throws BadLocationException { - final int charOffset= caretOffset - 1; - final char prevChar= doc.getChar(Math.max(charOffset, 0)); - if (!fPairs.contains(prevChar)) return null; - final boolean isForward= fPairs.isStartCharacter(prevChar); + final char prevChar= doc.getChar(Math.max(caretOffset - 1, 0)); + boolean isForward; + final char ch; + if (fCaretInsideMatchedPair) { + final char currChar= doc.getChar(caretOffset); + isForward= fPairs.contains(prevChar) && fPairs.isStartCharacter(prevChar); + boolean isBackward= fPairs.contains(currChar) && !fPairs.isStartCharacter(currChar); + if (!isForward && !isBackward) { + return null; + } + ch= isForward ? prevChar : currChar; + } else { + if (!fPairs.contains(prevChar)) + return null; + isForward= fPairs.isStartCharacter(prevChar); + ch= prevChar; + } + fAnchor= isForward ? ICharacterPairMatcher.LEFT : ICharacterPairMatcher.RIGHT; - final int searchStartPosition= isForward ? caretOffset : caretOffset - 2; - final int adjustedOffset= isForward ? charOffset : caretOffset; - final String partition= TextUtilities.getContentType(doc, fPartitioning, charOffset, false); + final int searchStartPosition= isForward ? caretOffset : (fCaretInsideMatchedPair ? caretOffset - 1 : caretOffset - 2); + final int adjustedOffset= isForward ? caretOffset - 1 : (fCaretInsideMatchedPair ? caretOffset + 1 : caretOffset); + final String partition= TextUtilities.getContentType(doc, fPartitioning, ((!isForward && fCaretInsideMatchedPair) ? caretOffset : caretOffset - 1), false); final DocumentPartitionAccessor partDoc= new DocumentPartitionAccessor(doc, fPartitioning, partition); - int endOffset= findMatchingPeer(partDoc, prevChar, fPairs.getMatching(prevChar), - isForward, isForward ? doc.getLength() : -1, - searchStartPosition); - if (endOffset == -1) return null; - final int adjustedEndOffset= isForward ? endOffset + 1: endOffset; - if (adjustedEndOffset == adjustedOffset) return null; + int endOffset= findMatchingPeer(partDoc, ch, fPairs.getMatching(ch), + isForward, isForward ? doc.getLength() : -1, searchStartPosition); + if (endOffset == -1) + return null; + final int adjustedEndOffset= isForward ? endOffset + 1 : endOffset; + if (adjustedEndOffset == adjustedOffset) + return null; return new Region(Math.min(adjustedOffset, adjustedEndOffset), Math.abs(adjustedEndOffset - adjustedOffset)); }