View | Details | Raw Unified | Return to bug 9503 | Differences between
and this patch

Collapse All | Expand All

(-)a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/AbstractPairMatcherTest.java (-170 / +13 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2008 IBM Corporation and others.
2
 * Copyright (c) 2006, 2012 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 15-21 Link Here
15
15
16
import junit.framework.TestCase;
16
import junit.framework.TestCase;
17
17
18
import org.eclipse.jface.text.BadLocationException;
19
import org.eclipse.jface.text.Document;
18
import org.eclipse.jface.text.Document;
20
import org.eclipse.jface.text.IDocument;
19
import org.eclipse.jface.text.IDocument;
21
import org.eclipse.jface.text.IDocumentPartitioner;
20
import org.eclipse.jface.text.IDocumentPartitioner;
Lines 43-48 Link Here
43
	 */
42
	 */
44
	protected abstract ICharacterPairMatcher createMatcher(final String chars);
43
	protected abstract ICharacterPairMatcher createMatcher(final String chars);
45
44
45
	protected abstract void checkResult(PairMatcherTestCase test, IRegion region, boolean isForward);
46
46
	/**
47
	/**
47
	 * Returns the partitioning treated by the matcher.
48
	 * Returns the partitioning treated by the matcher.
48
	 * 
49
	 * 
Lines 58-215 Link Here
58
		super();
59
		super();
59
	}
60
	}
60
61
61
	/* --- T e s t s --- */
62
63
	/** Tests that the test case reader works */
64
	public void testTestCaseReader() {
65
		performReaderTest("#( )%", 3,  0,  "( )");
66
		performReaderTest("%( )#", 0,  3,  "( )");
67
		performReaderTest("( )%",  3,  -1, "( )");
68
		performReaderTest("#%",    0,  0,  "");
69
	}
70
71
	/**
72
	 * Very simple checks.
73
	 * 
74
	 * @throws BadLocationException
75
	 */
76
	public void testSimpleMatchSameMatcher() throws BadLocationException {
77
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
78
		performMatch(matcher, "#(   )%");
79
		performMatch(matcher, "#[   ]%");
80
		performMatch(matcher, "#{   }%");
81
		performMatch(matcher, "(%   )#");
82
		performMatch(matcher, "[%   ]#");
83
		performMatch(matcher, "{%   }#");
84
		matcher.dispose();
85
	}
86
87
	/**
88
	 * Very simple checks.
89
	 * 
90
	 * @throws BadLocationException
91
	 */
92
	public void testSimpleMatchDifferentMatchers() throws BadLocationException {
93
		performMatch("()[]{}", "#(   )%");
94
		performMatch("()[]{}", "#[   ]%");
95
		performMatch("()[]{}", "#{   }%");
96
		performMatch("()[]{}", "(%   )#");
97
		performMatch("()[]{}", "[%   ]#");
98
		performMatch("()[]{}", "{%   }#");
99
	}
100
101
	/**
102
	 * Close matches.
103
	 * 
104
	 * @throws BadLocationException
105
	 */
106
	public void testCloseMatches() throws BadLocationException {
107
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
108
		performMatch(matcher, "#()%");
109
		performMatch(matcher, "(%)#");
110
		performMatch(matcher, "#(())%");
111
		performMatch(matcher, "(%())#");
112
		performMatch(matcher, "((%)#)");
113
		performMatch(matcher, "(#()%)");
114
		matcher.dispose();
115
	}
116
117
118
	/**
119
	 * Checks of simple situations where no matches should be found.
120
	 * 
121
	 * @throws BadLocationException
122
	 */
123
	public void testIncompleteMatch() throws BadLocationException {
124
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
125
		performMatch(matcher, "(% ");
126
		performMatch(matcher, "%(  )");
127
		performMatch(matcher, "( % )");
128
		performMatch(matcher, "(  %)");
129
		performMatch(matcher, "%");
130
		matcher.dispose();
131
	}
132
133
	/**
134
	 * Test that it doesn't match across different partitions.
135
	 * 
136
	 * @throws BadLocationException
137
	 */
138
	public void testPartitioned() throws BadLocationException {
139
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
140
		performMatch(matcher, "(% |a a| )#");
141
		performMatch(matcher, "#( |a a| )%");
142
		performMatch(matcher, "|b #( )% b|");
143
		performMatch(matcher, "( |b )% b|");
144
		performMatch(matcher, "(% |b ) b|");
145
		performMatch(matcher, "|a ( a| )%");
146
		performMatch(matcher, "|a (% a| )");
147
		performMatch(matcher, "|c #( c| ) ( |c )% c|");
148
		performMatch(matcher, "|c (% c| ) ( |c )# c|");
149
		performMatch(matcher, "(% |a ) a| |b ) b| |c ) c| )#");
150
		matcher.dispose();
151
	}
152
153
	/**
154
	 * Test that it works properly next to partition boundaries.
155
	 * 
156
	 * @throws BadLocationException
157
	 */
158
	public void testTightPartitioned() throws BadLocationException {
159
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
160
		performMatch(matcher, "(|b)%b|");
161
		performMatch(matcher, "(%|b)b|");
162
		performMatch(matcher, "|a(a|)%");
163
		performMatch(matcher, "|a(%a|)");
164
		performMatch(matcher, "|c#(c|)(|c)%c|");
165
		performMatch(matcher, "|c(%c|)(|c)#c|");
166
		performMatch(matcher, "(%|a)a||b)b||c)c|)#");
167
		matcher.dispose();
168
	}
169
170
	/** Test that nesting works properly */
171
	public void testNesting() {
172
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
173
		performMatch(matcher, " ( #( ( ( ) ) ( ) )% ) ");
174
		performMatch(matcher, " ( (% ( ( ) ) ( ) )# ) ");
175
		performMatch(matcher, " ( #( { ( ) } [ ] )% ) ");
176
		performMatch(matcher, " ( (% { ( ) } [ ] )# ) ");
177
		performMatch(matcher, " ( ( #{ ( ) }% [ ] ) ) ");
178
		performMatch(matcher, " ( ( {% ( ) }# [ ] ) ) ");
179
		performMatch(matcher, "a(b#(c(d(e)f)g(h)i)%j)k");
180
		performMatch(matcher, "a(b(%c(d(e)f)g(h)i)#j)k");
181
		performMatch(matcher, "a(b#(c{d(e)f}g[h]i)%j)k");
182
		performMatch(matcher, "a(b(%c{d(e)f}g[h]i)#j)k");
183
		performMatch(matcher, "a(b(c#{d(e)f}%g[h]i)j)k");
184
		performMatch(matcher, "a(b(c{%d(e)f}#g[h]i)j)k");
185
		matcher.dispose();
186
	}
187
188
	/**
189
	 * Test a few boundary conditions.
190
	 * 
191
	 * * @throws BadLocationException
192
	 */
193
	public void testBoundaries() throws BadLocationException {
194
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
195
		final StringDocument doc= new StringDocument("abcdefghijkl");
196
		assertNull(matcher.match(null, 0));
197
		assertNull(matcher.match(doc, -1));
198
		assertNull(matcher.match(doc, doc.getLength() + 1));
199
		matcher.dispose();
200
	}
201
202
	public void testBug156426() {
203
		final ICharacterPairMatcher matcher= createMatcher("()[]{}<>");
204
		performMatch(matcher, " #( a < b )% ");
205
		performMatch(matcher, " (% a < b )# ");
206
		performMatch(matcher, " #( a > b )% ");
207
		performMatch(matcher, " (% a > b )# ");
208
		matcher.dispose();
209
	}
210
211
	/* --- U t i l i t i e s --- */
212
213
	/**
62
	/**
214
	 * Checks that the test case reader reads the test case as specified.
63
	 * Checks that the test case reader reads the test case as specified.
215
	 * 
64
	 * 
Lines 218-225 Link Here
218
	 * @param expectedMatch the expected match
67
	 * @param expectedMatch the expected match
219
	 * @param expectedString the expected string
68
	 * @param expectedString the expected string
220
	 */
69
	 */
221
	private void performReaderTest(String testString, int expectedPos, int expectedMatch, String expectedString) {
70
	protected void performReaderTest(String testString, int expectedPos, int expectedMatch, String expectedString) {
222
		TestCase t0= createTestCase(testString);
71
		PairMatcherTestCase t0= createTestCase(testString);
223
		assertEquals(expectedPos, t0.fPos);
72
		assertEquals(expectedPos, t0.fPos);
224
		assertEquals(expectedMatch, t0.fMatch);
73
		assertEquals(expectedMatch, t0.fMatch);
225
		assertEquals(expectedString, t0.fString);
74
		assertEquals(expectedString, t0.fString);
Lines 232-238 Link Here
232
	 * @param testCase the test string
81
	 * @param testCase the test string
233
	 */
82
	 */
234
	protected void performMatch(final ICharacterPairMatcher matcher, final String testCase) {
83
	protected void performMatch(final ICharacterPairMatcher matcher, final String testCase) {
235
		final TestCase test= createTestCase(testCase);
84
		final PairMatcherTestCase test= createTestCase(testCase);
236
		matcher.clear();
85
		matcher.clear();
237
		final IRegion region= matcher.match(test.getDocument(), test.fPos);
86
		final IRegion region= matcher.match(test.getDocument(), test.fPos);
238
		if (test.fMatch == -1) {
87
		if (test.fMatch == -1) {
Lines 244-260 Link Here
244
			assertNotNull(region);
93
			assertNotNull(region);
245
			final boolean isForward= test.fPos > test.fMatch;
94
			final boolean isForward= test.fPos > test.fMatch;
246
			assertEquals(isForward, matcher.getAnchor() == ICharacterPairMatcher.RIGHT);
95
			assertEquals(isForward, matcher.getAnchor() == ICharacterPairMatcher.RIGHT);
247
			// If the match is forward, the curser is one character
96
			checkResult(test, region, isForward);
248
			// after the start of the match, so we need to count one
249
			// step backwards
250
			final int offset= isForward ? test.getOffset() : test.getOffset() - 1;
251
			final int length= isForward ? test.getLength() : test.getLength() + 1;
252
			assertEquals(length, region.getLength());
253
			assertEquals(offset, region.getOffset());
254
		}
97
		}
255
	}
98
	}
256
99
257
	private void performMatch(final String delims, final String testCase) {
100
	protected void performMatch(final String delims, final String testCase) {
258
		final ICharacterPairMatcher matcher= createMatcher(delims);
101
		final ICharacterPairMatcher matcher= createMatcher(delims);
259
		performMatch(matcher, testCase);
102
		performMatch(matcher, testCase);
260
		matcher.dispose();
103
		matcher.dispose();
Lines 267-273 Link Here
267
	 * @param str the string for which to create the test case
110
	 * @param str the string for which to create the test case
268
	 * @return the created test case
111
	 * @return the created test case
269
	 */
112
	 */
270
	public TestCase createTestCase(String str) {
113
	public PairMatcherTestCase createTestCase(String str) {
271
		int pos= str.indexOf("%");
114
		int pos= str.indexOf("%");
272
		assertFalse(pos == -1);
115
		assertFalse(pos == -1);
273
		int match= str.indexOf("#");
116
		int match= str.indexOf("#");
Lines 276-290 Link Here
276
		if (match != -1 && match < pos) pos -= 1;
119
		if (match != -1 && match < pos) pos -= 1;
277
		if (pos < match) match -= 1;
120
		if (pos < match) match -= 1;
278
		final String stripped= str.replaceAll("%", "").replaceAll("#", "");
121
		final String stripped= str.replaceAll("%", "").replaceAll("#", "");
279
		return new TestCase(stripped, pos, match);
122
		return new PairMatcherTestCase(stripped, pos, match);
280
	}
123
	}
281
124
282
	private class TestCase {
125
	public class PairMatcherTestCase {
283
126
284
		public final String fString;
127
		public final String fString;
285
		public final int fPos, fMatch;
128
		public final int fPos, fMatch;
286
129
287
		public TestCase(String string, int pos, int match) {
130
		public PairMatcherTestCase(String string, int pos, int match) {
288
			fString= string;
131
			fString= string;
289
			fPos= pos;
132
			fPos= pos;
290
			fMatch= match;
133
			fMatch= match;
Lines 305-311 Link Here
305
148
306
	}
149
	}
307
150
308
	private class StringDocument extends Document {
151
	class StringDocument extends Document {
309
152
310
		public StringDocument(String str) {
153
		public StringDocument(String str) {
311
			this.setTextStore(new StringTextStore(str));
154
			this.setTextStore(new StringTextStore(str));
(-)a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DefaultPairMatcherTest.java (-3 / +157 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2008 IBM Corporation and others.
2
 * Copyright (c) 2006, 2012 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 13-19 Link Here
13
import junit.framework.Test;
13
import junit.framework.Test;
14
import junit.framework.TestSuite;
14
import junit.framework.TestSuite;
15
15
16
import org.eclipse.jface.text.BadLocationException;
16
import org.eclipse.jface.text.IDocumentExtension3;
17
import org.eclipse.jface.text.IDocumentExtension3;
18
import org.eclipse.jface.text.IRegion;
17
import org.eclipse.jface.text.source.DefaultCharacterPairMatcher;
19
import org.eclipse.jface.text.source.DefaultCharacterPairMatcher;
18
import org.eclipse.jface.text.source.ICharacterPairMatcher;
20
import org.eclipse.jface.text.source.ICharacterPairMatcher;
19
21
Lines 29-36 Link Here
29
	}
31
	}
30
32
31
	protected ICharacterPairMatcher createMatcher(String chars) {
33
	protected ICharacterPairMatcher createMatcher(String chars) {
32
		return new DefaultCharacterPairMatcher(chars.toCharArray(),
34
		return new DefaultCharacterPairMatcher(chars.toCharArray(), getDocumentPartitioning(), false);
33
				getDocumentPartitioning());
34
	}
35
	}
35
36
36
	/*
37
	/*
Lines 41-44 Link Here
41
		return IDocumentExtension3.DEFAULT_PARTITIONING;
42
		return IDocumentExtension3.DEFAULT_PARTITIONING;
42
	}
43
	}
43
44
45
	/** Tests that the test case reader works */
46
	public void testTestCaseReader() {
47
		performReaderTest("#( )%", 3,  0,  "( )");
48
		performReaderTest("%( )#", 0,  3,  "( )");
49
		performReaderTest("( )%",  3,  -1, "( )");
50
		performReaderTest("#%",    0,  0,  "");
51
	}
52
53
	/**
54
	 * Very simple checks.
55
	 * 
56
	 * @throws BadLocationException
57
	 */
58
	public void testSimpleMatchSameMatcher() throws BadLocationException {
59
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
60
		performMatch(matcher, "#(   )%");
61
		performMatch(matcher, "#[   ]%");
62
		performMatch(matcher, "#{   }%");
63
		performMatch(matcher, "(%   )#");
64
		performMatch(matcher, "[%   ]#");
65
		performMatch(matcher, "{%   }#");
66
		matcher.dispose();
67
	}
68
69
	/**
70
	 * Very simple checks.
71
	 * 
72
	 * @throws BadLocationException
73
	 */
74
	public void testSimpleMatchDifferentMatchers() throws BadLocationException {
75
		performMatch("()[]{}", "#(   )%");
76
		performMatch("()[]{}", "#[   ]%");
77
		performMatch("()[]{}", "#{   }%");
78
		performMatch("()[]{}", "(%   )#");
79
		performMatch("()[]{}", "[%   ]#");
80
		performMatch("()[]{}", "{%   }#");
81
	}
82
83
	/**
84
	 * Close matches.
85
	 * 
86
	 * @throws BadLocationException
87
	 */
88
	public void testCloseMatches() throws BadLocationException {
89
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
90
		performMatch(matcher, "#()%");
91
		performMatch(matcher, "(%)#");
92
		performMatch(matcher, "#(())%");
93
		performMatch(matcher, "(%())#");
94
		performMatch(matcher, "((%)#)");
95
		performMatch(matcher, "(#()%)");
96
		matcher.dispose();
97
	}
98
99
	/**
100
	 * Checks of simple situations where no matches should be found.
101
	 * 
102
	 * @throws BadLocationException
103
	 */
104
	public void testIncompleteMatch() throws BadLocationException {
105
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
106
		performMatch(matcher, "(% ");
107
		performMatch(matcher, "%(  )");
108
		performMatch(matcher, "( % )");
109
		performMatch(matcher, "(  %)");
110
		performMatch(matcher, "%");
111
		matcher.dispose();
112
	}
113
114
	/**
115
	 * Test that it doesn't match across different partitions.
116
	 * 
117
	 * @throws BadLocationException
118
	 */
119
	public void testPartitioned() throws BadLocationException {
120
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
121
		performMatch(matcher, "(% |a a| )#");
122
		performMatch(matcher, "#( |a a| )%");
123
		performMatch(matcher, "|b #( )% b|");
124
		performMatch(matcher, "( |b )% b|");
125
		performMatch(matcher, "(% |b ) b|");
126
		performMatch(matcher, "|a ( a| )%");
127
		performMatch(matcher, "|a (% a| )");
128
		performMatch(matcher, "|c #( c| ) ( |c )% c|");
129
		performMatch(matcher, "|c (% c| ) ( |c )# c|");
130
		performMatch(matcher, "(% |a ) a| |b ) b| |c ) c| )#");
131
		matcher.dispose();
132
	}
133
134
	/**
135
	 * Test that it works properly next to partition boundaries.
136
	 * 
137
	 * @throws BadLocationException
138
	 */
139
	public void testTightPartitioned() throws BadLocationException {
140
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
141
		performMatch(matcher, "(|b)%b|");
142
		performMatch(matcher, "(%|b)b|");
143
		performMatch(matcher, "|a(a|)%");
144
		performMatch(matcher, "|a(%a|)");
145
		performMatch(matcher, "|c#(c|)(|c)%c|");
146
		performMatch(matcher, "|c(%c|)(|c)#c|");
147
		performMatch(matcher, "(%|a)a||b)b||c)c|)#");
148
		matcher.dispose();
149
	}
150
151
	/** Test that nesting works properly */
152
	public void testNesting() {
153
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
154
		performMatch(matcher, " ( #( ( ( ) ) ( ) )% ) ");
155
		performMatch(matcher, " ( (% ( ( ) ) ( ) )# ) ");
156
		performMatch(matcher, " ( #( { ( ) } [ ] )% ) ");
157
		performMatch(matcher, " ( (% { ( ) } [ ] )# ) ");
158
		performMatch(matcher, " ( ( #{ ( ) }% [ ] ) ) ");
159
		performMatch(matcher, " ( ( {% ( ) }# [ ] ) ) ");
160
		performMatch(matcher, "a(b#(c(d(e)f)g(h)i)%j)k");
161
		performMatch(matcher, "a(b(%c(d(e)f)g(h)i)#j)k");
162
		performMatch(matcher, "a(b#(c{d(e)f}g[h]i)%j)k");
163
		performMatch(matcher, "a(b(%c{d(e)f}g[h]i)#j)k");
164
		performMatch(matcher, "a(b(c#{d(e)f}%g[h]i)j)k");
165
		performMatch(matcher, "a(b(c{%d(e)f}#g[h]i)j)k");
166
		matcher.dispose();
167
	}
168
169
	/**
170
	 * Test a few boundary conditions.
171
	 * 
172
	 * * @throws BadLocationException
173
	 */
174
	public void testBoundaries() throws BadLocationException {
175
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
176
		final StringDocument doc= new StringDocument("abcdefghijkl");
177
		assertNull(matcher.match(null, 0));
178
		assertNull(matcher.match(doc, -1));
179
		assertNull(matcher.match(doc, doc.getLength() + 1));
180
		matcher.dispose();
181
	}
182
183
	public void testBug156426() {
184
		final ICharacterPairMatcher matcher= createMatcher("()[]{}<>");
185
		performMatch(matcher, " #( a < b )% ");
186
		performMatch(matcher, " (% a < b )# ");
187
		performMatch(matcher, " #( a > b )% ");
188
		performMatch(matcher, " (% a > b )# ");
189
		matcher.dispose();
190
	}
191
192
	protected void checkResult(final PairMatcherTestCase test, final IRegion region, final boolean isForward) {
193
		final int offset= isForward ? test.getOffset() : test.getOffset() - 1;
194
		final int length= isForward ? test.getLength() : test.getLength() + 1;
195
		assertEquals(length, region.getLength());
196
		assertEquals(offset, region.getOffset());
197
	}
44
}
198
}
(-)a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DefaultPairMatcherTest2.java (+196 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2012 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jface.text.tests;
12
13
import junit.framework.Test;
14
import junit.framework.TestSuite;
15
16
import org.eclipse.jface.text.BadLocationException;
17
import org.eclipse.jface.text.IDocumentExtension3;
18
import org.eclipse.jface.text.IRegion;
19
import org.eclipse.jface.text.source.DefaultCharacterPairMatcher;
20
import org.eclipse.jface.text.source.ICharacterPairMatcher;
21
22
/**
23
 * Tests for the default pair matcher.
24
 * 
25
 * @since 3.8
26
 */
27
public class DefaultPairMatcherTest2 extends AbstractPairMatcherTest {
28
29
	public static Test suite() {
30
		return new TestSuite(DefaultPairMatcherTest2.class);
31
	}
32
33
	protected ICharacterPairMatcher createMatcher(String chars) {
34
		return new DefaultCharacterPairMatcher(chars.toCharArray(), getDocumentPartitioning(), true);
35
	}
36
37
	/*
38
	 * @see org.eclipse.jface.text.tests.AbstractPairMatcherTest#getDocumentPartitioning()
39
	 * @since 3.3
40
	 */
41
	protected String getDocumentPartitioning() {
42
		return IDocumentExtension3.DEFAULT_PARTITIONING;
43
	}
44
45
	/** Tests that the test case reader works */
46
	public void testTestCaseReader() {
47
		performReaderTest("#( %)", 2,  0,  "( )");
48
		performReaderTest("%( )#", 0,  3,  "( )");
49
		performReaderTest("( %)",  2, -1,  "( )");
50
		performReaderTest("#%",    0,  0,  "");
51
	}
52
53
	/**
54
	 * Very simple checks.
55
	 * 
56
	 * @throws BadLocationException
57
	 */
58
	public void testSimpleMatchSameMatcher() throws BadLocationException {
59
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
60
		performMatch(matcher, "#(   %)");
61
		performMatch(matcher, "#[   %]");
62
		performMatch(matcher, "#{   %}");
63
		performMatch(matcher, "(%   )#");
64
		performMatch(matcher, "[%   ]#");
65
		performMatch(matcher, "{%   }#");
66
		matcher.dispose();
67
	}
68
69
	/**
70
	 * Very simple checks.
71
	 * 
72
	 * @throws BadLocationException
73
	 */
74
	public void testSimpleMatchDifferentMatchers() throws BadLocationException {
75
		performMatch("()[]{}", "#(   %)");
76
		performMatch("()[]{}", "#[   %]");
77
		performMatch("()[]{}", "#{   %}");
78
		performMatch("()[]{}", "(%   )#");
79
		performMatch("()[]{}", "[%   ]#");
80
		performMatch("()[]{}", "{%   }#");
81
	}
82
83
	/**
84
	 * Close matches.
85
	 * 
86
	 * @throws BadLocationException
87
	 */
88
	public void testCloseMatches() throws BadLocationException {
89
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
90
		performMatch(matcher, "(%)#");
91
		performMatch(matcher, "#(()%)");
92
		performMatch(matcher, "(%())#");
93
		performMatch(matcher, "((%)#)");
94
		matcher.dispose();
95
	}
96
97
	/**
98
	 * Checks of simple situations where no matches should be found.
99
	 * 
100
	 * @throws BadLocationException
101
	 */
102
	public void testIncompleteMatch() throws BadLocationException {
103
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
104
		performMatch(matcher, "(% ");
105
		performMatch(matcher, "%(  )");
106
		performMatch(matcher, "( % )");
107
		performMatch(matcher, "(  )%");
108
		performMatch(matcher, "%");
109
		matcher.dispose();
110
	}
111
112
	/**
113
	 * Test that it doesn't match across different partitions.
114
	 * 
115
	 * @throws BadLocationException
116
	 */
117
	public void testPartitioned() throws BadLocationException {
118
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
119
		performMatch(matcher, "(% |a a| )#");
120
		performMatch(matcher, "#( |a a| %)");
121
		performMatch(matcher, "|b #( %) b|");
122
		performMatch(matcher, "( |b %) b|");
123
		performMatch(matcher, "(% |b ) b|");
124
		performMatch(matcher, "|a ( a| %)");
125
		performMatch(matcher, "|a (% a| )");
126
		performMatch(matcher, "|c #( c| ) ( |c %) c|");
127
		performMatch(matcher, "|c (% c| ) ( |c )# c|");
128
		performMatch(matcher, "(% |a ) a| |b ) b| |c ) c| )#");
129
		matcher.dispose();
130
	}
131
132
	/**
133
	 * Test that it works properly next to partition boundaries.
134
	 * 
135
	 * @throws BadLocationException
136
	 */
137
	public void testTightPartitioned() throws BadLocationException {
138
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
139
		performMatch(matcher, "(|b%)b|");
140
		performMatch(matcher, "(%|b)b|");
141
		performMatch(matcher, "|a(a|%)");
142
		performMatch(matcher, "|a(%a|)");
143
		performMatch(matcher, "|c#(c|)(|c%)c|");
144
		performMatch(matcher, "|c(%c|)(|c)#c|");
145
		performMatch(matcher, "(%|a)a||b)b||c)c|)#");
146
		matcher.dispose();
147
	}
148
149
	/** Test that nesting works properly */
150
	public void testNesting() {
151
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
152
		performMatch(matcher, " ( #( ( ( ) ) ( ) %) ) ");
153
		performMatch(matcher, " ( (% ( ( ) ) ( ) )# ) ");
154
		performMatch(matcher, " ( #( { ( ) } [ ] %) ) ");
155
		performMatch(matcher, " ( (% { ( ) } [ ] )# ) ");
156
		performMatch(matcher, " ( ( #{ ( ) %} [ ] ) ) ");
157
		performMatch(matcher, " ( ( {% ( ) }# [ ] ) ) ");
158
		performMatch(matcher, "a(b#(c(d(e)f)g(h)i%)j)k");
159
		performMatch(matcher, "a(b(%c(d(e)f)g(h)i)#j)k");
160
		performMatch(matcher, "a(b#(c{d(e)f}g[h]i%)j)k");
161
		performMatch(matcher, "a(b(%c{d(e)f}g[h]i)#j)k");
162
		performMatch(matcher, "a(b(c#{d(e)f%}g[h]i)j)k");
163
		performMatch(matcher, "a(b(c{%d(e)f}#g[h]i)j)k");
164
		matcher.dispose();
165
	}
166
167
	/**
168
	 * Test a few boundary conditions.
169
	 * 
170
	 * * @throws BadLocationException
171
	 */
172
	public void testBoundaries() throws BadLocationException {
173
		final ICharacterPairMatcher matcher= createMatcher("()[]{}");
174
		final StringDocument doc= new StringDocument("abcdefghijkl");
175
		assertNull(matcher.match(null, 0));
176
		assertNull(matcher.match(doc, -1));
177
		assertNull(matcher.match(doc, doc.getLength() + 1));
178
		matcher.dispose();
179
	}
180
181
	public void testBug156426() {
182
		final ICharacterPairMatcher matcher= createMatcher("()[]{}<>");
183
		performMatch(matcher, " #( a < b %) ");
184
		performMatch(matcher, " (% a < b )# ");
185
		performMatch(matcher, " #( a > b %) ");
186
		performMatch(matcher, " (% a > b )# ");
187
		matcher.dispose();
188
	}
189
190
	protected void checkResult(final PairMatcherTestCase test, final IRegion region, final boolean isForward) {
191
		final int offset= isForward ? test.getOffset() : test.getOffset() - 1;
192
		final int length= test.getLength() + 1;
193
		assertEquals(length, region.getLength());
194
		assertEquals(offset, region.getOffset());
195
	}
196
}
(-)a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/DefaultCharacterPairMatcher.java (-14 / +54 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2010 IBM Corporation and others.
2
 * Copyright (c) 2006, 2012 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 34-39 Link Here
34
	private int fAnchor= -1;
34
	private int fAnchor= -1;
35
	private final CharPairs fPairs;
35
	private final CharPairs fPairs;
36
	private final String fPartitioning;
36
	private final String fPartitioning;
37
	private final boolean fCaretInsideMatchedPair;
37
38
38
	/**
39
	/**
39
	 * Creates a new character pair matcher that matches the specified characters within the
40
	 * Creates a new character pair matcher that matches the specified characters within the
Lines 50-59 Link Here
50
	 * @param partitioning the partitioning to match within
51
	 * @param partitioning the partitioning to match within
51
	 */
52
	 */
52
	public DefaultCharacterPairMatcher(char[] chars, String partitioning) {
53
	public DefaultCharacterPairMatcher(char[] chars, String partitioning) {
54
		this(chars, partitioning, false);
55
	}
56
57
	/**
58
	 * Creates a new character pair matcher that matches the specified characters within the
59
	 * specified partitioning. The specified list of characters must have the form <blockquote>{
60
	 * <i>start</i>, <i>end</i>, <i>start</i>, <i>end</i>, ..., <i>start</i>, <i>end</i>
61
	 * }</blockquote> For instance:
62
	 * 
63
	 * <pre>
64
	 * char[] chars = new char[] {'(', ')', '{', '}', '[', ']'};
65
	 * new DefaultCharacterPairMatcher(chars, ...);
66
	 * </pre>
67
	 * 
68
	 * @param chars a list of characters
69
	 * @param partitioning the partitioning to match within
70
	 * @param caretInsideMatchedPair controls the matching behavior. When <code>true</code>, the
71
	 *            matching start peer will be found when the caret is placed before the end
72
	 *            character. When <code>false</code>, the matching start peer will be found when the
73
	 *            caret is placed after the end character.
74
	 * @since 3.8
75
	 */
76
	public DefaultCharacterPairMatcher(char[] chars, String partitioning, boolean caretInsideMatchedPair) {
53
		Assert.isLegal(chars.length % 2 == 0);
77
		Assert.isLegal(chars.length % 2 == 0);
54
		Assert.isNotNull(partitioning);
78
		Assert.isNotNull(partitioning);
55
		fPairs= new CharPairs(chars);
79
		fPairs= new CharPairs(chars);
56
		fPartitioning= partitioning;
80
		fPartitioning= partitioning;
81
		fCaretInsideMatchedPair= caretInsideMatchedPair;
57
	}
82
	}
58
83
59
	/**
84
	/**
Lines 86-106 Link Here
86
	 * Performs the actual work of matching for #match(IDocument, int).
111
	 * Performs the actual work of matching for #match(IDocument, int).
87
	 */
112
	 */
88
	private IRegion performMatch(IDocument doc, int caretOffset) throws BadLocationException {
113
	private IRegion performMatch(IDocument doc, int caretOffset) throws BadLocationException {
89
		final int charOffset= caretOffset - 1;
114
		final char prevChar= doc.getChar(Math.max(caretOffset - 1, 0));
90
		final char prevChar= doc.getChar(Math.max(charOffset, 0));
115
		boolean isForward;
91
		if (!fPairs.contains(prevChar)) return null;
116
		final char ch;
92
		final boolean isForward= fPairs.isStartCharacter(prevChar);
117
		if (fCaretInsideMatchedPair) {
118
			final char currChar= doc.getChar(caretOffset);
119
			isForward= fPairs.contains(prevChar) && fPairs.isStartCharacter(prevChar);
120
			boolean isBackward= fPairs.contains(currChar) && !fPairs.isStartCharacter(currChar);
121
			if (!isForward && !isBackward) {
122
				return null;
123
			}
124
			ch= isForward ? prevChar : currChar;
125
		} else {
126
			if (!fPairs.contains(prevChar))
127
				return null;
128
			isForward= fPairs.isStartCharacter(prevChar);
129
			ch= prevChar;
130
		}
131
93
		fAnchor= isForward ? ICharacterPairMatcher.LEFT : ICharacterPairMatcher.RIGHT;
132
		fAnchor= isForward ? ICharacterPairMatcher.LEFT : ICharacterPairMatcher.RIGHT;
94
		final int searchStartPosition= isForward ? caretOffset : caretOffset - 2;
133
		final int searchStartPosition= isForward ? caretOffset : (fCaretInsideMatchedPair ? caretOffset - 1 : caretOffset - 2);
95
		final int adjustedOffset= isForward ? charOffset : caretOffset;
134
		final int adjustedOffset= isForward ? caretOffset - 1 : (fCaretInsideMatchedPair ? caretOffset + 1 : caretOffset);
96
		final String partition= TextUtilities.getContentType(doc, fPartitioning, charOffset, false);
135
		final String partition= TextUtilities.getContentType(doc, fPartitioning, ((!isForward && fCaretInsideMatchedPair) ? caretOffset : caretOffset - 1), false);
97
		final DocumentPartitionAccessor partDoc= new DocumentPartitionAccessor(doc, fPartitioning, partition);
136
		final DocumentPartitionAccessor partDoc= new DocumentPartitionAccessor(doc, fPartitioning, partition);
98
		int endOffset= findMatchingPeer(partDoc, prevChar, fPairs.getMatching(prevChar),
137
		int endOffset= findMatchingPeer(partDoc, ch, fPairs.getMatching(ch),
99
				isForward,  isForward ? doc.getLength() : -1,
138
				isForward, isForward ? doc.getLength() : -1, searchStartPosition);
100
				searchStartPosition);
139
		if (endOffset == -1)
101
		if (endOffset == -1) return null;
140
			return null;
102
		final int adjustedEndOffset= isForward ? endOffset + 1: endOffset;
141
		final int adjustedEndOffset= isForward ? endOffset + 1 : endOffset;
103
		if (adjustedEndOffset == adjustedOffset) return null;
142
		if (adjustedEndOffset == adjustedOffset)
143
			return null;
104
		return new Region(Math.min(adjustedOffset, adjustedEndOffset),
144
		return new Region(Math.min(adjustedOffset, adjustedEndOffset),
105
				Math.abs(adjustedEndOffset - adjustedOffset));
145
				Math.abs(adjustedEndOffset - adjustedOffset));
106
	}
146
	}

Return to bug 9503