Mercurial > projects > dwt-addons
annotate dwtx/jface/text/rules/RuleBasedPartitioner.d @ 199:eb98a5cbfd78
Fix: potential problem with synchronized, thx torhu.
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Fri, 13 Mar 2009 17:03:26 +0100 |
parents | 1a5b8f8129df |
children |
rev | line source |
---|---|
129 | 1 /******************************************************************************* |
2 * Copyright (c) 2000, 2006 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 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 | |
131 | 14 |
151 | 15 module dwtx.jface.text.rules.RuleBasedPartitioner; |
16 | |
131 | 17 import dwtx.jface.text.rules.FastPartitioner; // packageimport |
18 import dwtx.jface.text.rules.ITokenScanner; // packageimport | |
19 import dwtx.jface.text.rules.Token; // packageimport | |
20 import dwtx.jface.text.rules.RuleBasedScanner; // packageimport | |
21 import dwtx.jface.text.rules.EndOfLineRule; // packageimport | |
22 import dwtx.jface.text.rules.WordRule; // packageimport | |
23 import dwtx.jface.text.rules.WhitespaceRule; // packageimport | |
24 import dwtx.jface.text.rules.WordPatternRule; // packageimport | |
25 import dwtx.jface.text.rules.IPredicateRule; // packageimport | |
26 import dwtx.jface.text.rules.DefaultPartitioner; // packageimport | |
27 import dwtx.jface.text.rules.NumberRule; // packageimport | |
28 import dwtx.jface.text.rules.SingleLineRule; // packageimport | |
29 import dwtx.jface.text.rules.PatternRule; // packageimport | |
30 import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport | |
31 import dwtx.jface.text.rules.ICharacterScanner; // packageimport | |
32 import dwtx.jface.text.rules.IRule; // packageimport | |
33 import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport | |
34 import dwtx.jface.text.rules.IToken; // packageimport | |
35 import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport | |
36 import dwtx.jface.text.rules.MultiLineRule; // packageimport | |
37 import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport | |
38 import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport | |
39 import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport | |
40 | |
129 | 41 import dwt.dwthelper.utils; |
42 | |
43 | |
153
f70d9508c95c
Fix java Collection imports
Frank Benoit <benoit@tionex.de>
parents:
151
diff
changeset
|
44 import dwtx.dwtxhelper.Collection; |
f70d9508c95c
Fix java Collection imports
Frank Benoit <benoit@tionex.de>
parents:
151
diff
changeset
|
45 |
129 | 46 |
47 import dwtx.core.runtime.Assert; | |
48 import dwtx.jface.text.BadLocationException; | |
49 import dwtx.jface.text.BadPositionCategoryException; | |
50 import dwtx.jface.text.DefaultPositionUpdater; | |
51 import dwtx.jface.text.DocumentEvent; | |
52 import dwtx.jface.text.IDocument; | |
53 import dwtx.jface.text.IDocumentPartitioner; | |
54 import dwtx.jface.text.IDocumentPartitionerExtension; | |
55 import dwtx.jface.text.IDocumentPartitionerExtension2; | |
56 import dwtx.jface.text.IRegion; | |
57 import dwtx.jface.text.ITypedRegion; | |
58 import dwtx.jface.text.Position; | |
59 import dwtx.jface.text.Region; | |
60 import dwtx.jface.text.TextUtilities; | |
61 import dwtx.jface.text.TypedPosition; | |
62 import dwtx.jface.text.TypedRegion; | |
63 | |
64 | |
65 | |
66 /** | |
67 * A standard implementation of a syntax driven document partitioner. | |
68 * It uses a rule based scanner to scan the document and to determine | |
69 * the document's partitioning. The tokens returned by the rules the | |
70 * scanner is configured with are supposed to return the partition type | |
71 * as their data. The partitioner remembers the document's partitions | |
72 * in the document itself rather than maintaining its own data structure. | |
73 * | |
74 * @see IRule | |
75 * @see RuleBasedScanner | |
76 * | |
77 * @deprecated use <code>FastPartitioner</code> instead | |
78 */ | |
79 public class RuleBasedPartitioner : IDocumentPartitioner, IDocumentPartitionerExtension, IDocumentPartitionerExtension2 { | |
80 | |
81 /** | |
82 * The position category this partitioner uses to store the document's partitioning information | |
83 * @deprecated As of 3.0, use <code>getManagingPositionCategories()</code>. | |
84 */ | |
146 | 85 public const static String CONTENT_TYPES_CATEGORY= "__content_types_category"; //$NON-NLS-1$ |
129 | 86 |
87 | |
88 /** The partitioner's scanner */ | |
89 protected RuleBasedScanner fScanner; | |
90 /** The legal content types of this partitioner */ | |
91 protected String[] fLegalContentTypes; | |
92 /** The partitioner's document */ | |
93 protected IDocument fDocument; | |
94 /** The document length before a document change occurred */ | |
95 protected int fPreviousDocumentLength; | |
96 /** The position updater used to for the default updating of partitions */ | |
97 protected DefaultPositionUpdater fPositionUpdater; | |
98 /** The offset at which the first changed partition starts */ | |
99 protected int fStartOffset; | |
100 /** The offset at which the last changed partition ends */ | |
101 protected int fEndOffset; | |
102 /**The offset at which a partition has been deleted */ | |
103 protected int fDeleteOffset; | |
104 /** | |
105 * The position category for managing partitioning information. | |
106 * @since 3.0 | |
107 */ | |
108 private String fPositionCategory; | |
109 | |
110 | |
111 /** | |
112 * Creates a new partitioner that uses the given scanner and may return | |
113 * partitions of the given legal content types. | |
114 * | |
115 * @param scanner the scanner this partitioner is supposed to use | |
116 * @param legalContentTypes the legal content types of this partitioner | |
117 */ | |
133
7d818bd32d63
Fix ctors to this with gvim regexp
Frank Benoit <benoit@tionex.de>
parents:
131
diff
changeset
|
118 public this(RuleBasedScanner scanner, String[] legalContentTypes) { |
129 | 119 fScanner= scanner; |
120 fLegalContentTypes= TextUtilities.copy(legalContentTypes); | |
162 | 121 fPositionCategory= CONTENT_TYPES_CATEGORY ~ Integer.toString(toHash()); |
129 | 122 fPositionUpdater= new DefaultPositionUpdater(fPositionCategory); |
123 } | |
124 | |
125 /* | |
126 * @see dwtx.jface.text.IDocumentPartitionerExtension2#getManagingPositionCategories() | |
127 * @since 3.0 | |
128 */ | |
129 public String[] getManagingPositionCategories() { | |
150 | 130 return [ fPositionCategory ]; |
129 | 131 } |
132 | |
133 /* | |
134 * @see IDocumentPartitioner#connect | |
135 */ | |
136 public void connect(IDocument document) { | |
162 | 137 Assert.isNotNull(cast(Object)document); |
129 | 138 Assert.isTrue(!document.containsPositionCategory(fPositionCategory)); |
139 | |
140 fDocument= document; | |
141 fDocument.addPositionCategory(fPositionCategory); | |
142 | |
143 initialize(); | |
144 } | |
145 | |
146 /** | |
147 * Performs the initial partitioning of the partitioner's document. | |
148 */ | |
149 protected void initialize() { | |
150 | |
151 fScanner.setRange(fDocument, 0, fDocument.getLength()); | |
152 | |
153 try { | |
154 IToken token= fScanner.nextToken(); | |
155 while (!token.isEOF()) { | |
156 | |
157 String contentType= getTokenContentType(token); | |
158 | |
159 if (isSupportedContentType(contentType)) { | |
160 TypedPosition p= new TypedPosition(fScanner.getTokenOffset(), fScanner.getTokenLength(), contentType); | |
161 fDocument.addPosition(fPositionCategory, p); | |
162 } | |
163 | |
164 token= fScanner.nextToken(); | |
165 } | |
166 } catch (BadLocationException x) { | |
167 // cannot happen as offsets come from scanner | |
168 } catch (BadPositionCategoryException x) { | |
169 // cannot happen if document has been connected before | |
170 } | |
171 } | |
172 | |
173 /* | |
174 * @see IDocumentPartitioner#disconnect | |
175 */ | |
176 public void disconnect() { | |
177 | |
178 Assert.isTrue(fDocument.containsPositionCategory(fPositionCategory)); | |
179 | |
180 try { | |
181 fDocument.removePositionCategory(fPositionCategory); | |
182 } catch (BadPositionCategoryException x) { | |
183 // can not happen because of Assert | |
184 } | |
185 } | |
186 | |
187 /* | |
188 * @see IDocumentPartitioner#documentAboutToBeChanged | |
189 */ | |
190 public void documentAboutToBeChanged(DocumentEvent e) { | |
191 | |
192 Assert.isTrue(e.getDocument() is fDocument); | |
193 | |
194 fPreviousDocumentLength= e.getDocument().getLength(); | |
195 fStartOffset= -1; | |
196 fEndOffset= -1; | |
197 fDeleteOffset= -1; | |
198 } | |
199 | |
200 /* | |
201 * @see IDocumentPartitioner#documentChanged | |
202 */ | |
203 public bool documentChanged(DocumentEvent e) { | |
204 IRegion region= documentChanged2(e); | |
205 return (region !is null); | |
206 } | |
207 | |
208 /** | |
209 * Helper method for tracking the minimal region containing all partition changes. | |
210 * If <code>offset</code> is smaller than the remembered offset, <code>offset</code> | |
211 * will from now on be remembered. If <code>offset + length</code> is greater than | |
212 * the remembered end offset, it will be remembered from now on. | |
213 * | |
214 * @param offset the offset | |
215 * @param length the length | |
216 */ | |
217 private void rememberRegion(int offset, int length) { | |
218 // remember start offset | |
219 if (fStartOffset is -1) | |
220 fStartOffset= offset; | |
221 else if (offset < fStartOffset) | |
222 fStartOffset= offset; | |
223 | |
224 // remember end offset | |
225 int endOffset= offset + length; | |
226 if (fEndOffset is -1) | |
227 fEndOffset= endOffset; | |
228 else if (endOffset > fEndOffset) | |
229 fEndOffset= endOffset; | |
230 } | |
231 | |
232 /** | |
233 * Remembers the given offset as the deletion offset. | |
234 * | |
235 * @param offset the offset | |
236 */ | |
237 private void rememberDeletedOffset(int offset) { | |
238 fDeleteOffset= offset; | |
239 } | |
240 | |
241 /** | |
242 * Creates the minimal region containing all partition changes using the | |
243 * remembered offset, end offset, and deletion offset. | |
244 * @return the minimal region containing all the partition changes | |
245 */ | |
246 private IRegion createRegion() { | |
247 if (fDeleteOffset is -1) { | |
248 if (fStartOffset is -1 || fEndOffset is -1) | |
249 return null; | |
250 return new Region(fStartOffset, fEndOffset - fStartOffset); | |
251 } else if (fStartOffset is -1 || fEndOffset is -1) { | |
252 return new Region(fDeleteOffset, 0); | |
253 } else { | |
254 int offset= Math.min(fDeleteOffset, fStartOffset); | |
255 int endOffset= Math.max(fDeleteOffset, fEndOffset); | |
256 return new Region(offset, endOffset - offset); | |
257 } | |
258 } | |
259 | |
260 /* | |
261 * @see IDocumentPartitionerExtension#documentChanged2(DocumentEvent) | |
262 * @since 2.0 | |
263 */ | |
264 public IRegion documentChanged2(DocumentEvent e) { | |
265 | |
266 try { | |
267 | |
268 IDocument d= e.getDocument(); | |
269 Position[] category= d.getPositions(fPositionCategory); | |
270 int first= 0; | |
271 int reparseStart= 0; | |
272 int originalSize= category.length; | |
273 | |
274 if (originalSize > 0) { | |
275 | |
276 /* | |
277 * determine character position at which the scanner starts: | |
278 * first position behind the last non-default partition the actual position is not involved with | |
279 */ | |
280 | |
281 first= d.computeIndexInCategory(fPositionCategory, e.getOffset()); | |
282 | |
283 Position p= null; | |
284 do { | |
285 --first; | |
286 if (first < 0) | |
287 break; | |
288 | |
289 p= category[first]; | |
290 | |
291 } while (p.overlapsWith(e.getOffset(), e.getLength()) || | |
292 (e.getOffset() is fPreviousDocumentLength && | |
293 (p.getOffset() + p.getLength() is fPreviousDocumentLength))); | |
294 | |
295 fPositionUpdater.update(e); | |
296 for (int i= 0; i < category.length; i++) { | |
297 p= category[i]; | |
298 if (p.isDeleted) { | |
299 rememberDeletedOffset(e.getOffset()); | |
300 break; | |
301 } | |
302 } | |
303 category= d.getPositions(fPositionCategory); | |
304 | |
305 if (first >= 0) { | |
306 p= category[first]; | |
307 reparseStart= p.getOffset() + p.getLength(); | |
308 } | |
309 | |
310 ++first; | |
311 } | |
312 | |
313 fScanner.setRange(d, reparseStart, d.getLength() - reparseStart); | |
314 | |
315 int lastScannedPosition= reparseStart; | |
316 IToken token= fScanner.nextToken(); | |
317 | |
318 while (!token.isEOF()) { | |
319 | |
320 | |
321 String contentType= getTokenContentType(token); | |
322 | |
323 if (!isSupportedContentType(contentType)) { | |
324 token= fScanner.nextToken(); | |
325 continue; | |
326 } | |
327 | |
328 int start= fScanner.getTokenOffset(); | |
329 int length= fScanner.getTokenLength(); | |
330 | |
331 lastScannedPosition= start + length - 1; | |
332 | |
333 // remove all affected positions | |
334 while (first < category.length) { | |
134 | 335 TypedPosition p= cast(TypedPosition) category[first]; |
129 | 336 if (lastScannedPosition >= p.offset + p.length || |
337 (p.overlapsWith(start, length) && | |
338 (!d.containsPosition(fPositionCategory, start, length) || | |
339 !contentType.equals(p.getType())))) { | |
340 | |
341 rememberRegion(p.offset, p.length); | |
342 d.removePosition(fPositionCategory, p); | |
343 ++ first; | |
344 | |
345 } else | |
346 break; | |
347 } | |
348 | |
349 // if position already exists we are done | |
350 if (d.containsPosition(fPositionCategory, start, length)) | |
351 return createRegion(); | |
352 | |
353 // insert the new type position | |
354 try { | |
355 d.addPosition(fPositionCategory, new TypedPosition(start, length, contentType)); | |
356 rememberRegion(start, length); | |
357 } catch (BadPositionCategoryException x) { | |
358 } catch (BadLocationException x) { | |
359 } | |
360 | |
361 token= fScanner.nextToken(); | |
362 } | |
363 | |
364 | |
365 // remove all positions behind lastScannedPosition since there aren't any further types | |
366 if (lastScannedPosition !is reparseStart) { | |
367 // if this condition is not met, nothing has been scanned because of a delete | |
368 ++ lastScannedPosition; | |
369 } | |
370 first= d.computeIndexInCategory(fPositionCategory, lastScannedPosition); | |
371 | |
372 TypedPosition p; | |
373 while (first < category.length) { | |
134 | 374 p= cast(TypedPosition) category[first++]; |
129 | 375 d.removePosition(fPositionCategory, p); |
376 rememberRegion(p.offset, p.length); | |
377 } | |
378 | |
379 } catch (BadPositionCategoryException x) { | |
380 // should never happen on connected documents | |
381 } catch (BadLocationException x) { | |
382 } | |
383 | |
384 return createRegion(); | |
385 } | |
386 | |
387 | |
388 /** | |
389 * Returns the position in the partitoner's position category which is | |
390 * close to the given offset. This is, the position has either an offset which | |
391 * is the same as the given offset or an offset which is smaller than the given | |
392 * offset. This method profits from the knowledge that a partitioning is | |
393 * a ordered set of disjoint position. | |
394 * | |
395 * @param offset the offset for which to search the closest position | |
396 * @return the closest position in the partitioner's category | |
397 */ | |
398 protected TypedPosition findClosestPosition(int offset) { | |
399 | |
400 try { | |
401 | |
402 int index= fDocument.computeIndexInCategory(fPositionCategory, offset); | |
403 Position[] category= fDocument.getPositions(fPositionCategory); | |
404 | |
405 if (category.length is 0) | |
406 return null; | |
407 | |
408 if (index < category.length) { | |
409 if (offset is category[index].offset) | |
134 | 410 return cast(TypedPosition) category[index]; |
129 | 411 } |
412 | |
413 if (index > 0) | |
414 index--; | |
415 | |
134 | 416 return cast(TypedPosition) category[index]; |
129 | 417 |
418 } catch (BadPositionCategoryException x) { | |
419 } catch (BadLocationException x) { | |
420 } | |
421 | |
422 return null; | |
423 } | |
424 | |
425 | |
426 /* | |
427 * @see IDocumentPartitioner#getContentType | |
428 */ | |
429 public String getContentType(int offset) { | |
430 | |
431 TypedPosition p= findClosestPosition(offset); | |
432 if (p !is null && p.includes(offset)) | |
433 return p.getType(); | |
434 | |
435 return IDocument.DEFAULT_CONTENT_TYPE; | |
436 } | |
437 | |
438 /* | |
439 * @see IDocumentPartitioner#getPartition | |
440 */ | |
441 public ITypedRegion getPartition(int offset) { | |
442 | |
443 try { | |
444 | |
445 Position[] category = fDocument.getPositions(fPositionCategory); | |
446 | |
447 if (category is null || category.length is 0) | |
448 return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE); | |
449 | |
450 int index= fDocument.computeIndexInCategory(fPositionCategory, offset); | |
451 | |
452 if (index < category.length) { | |
453 | |
134 | 454 TypedPosition next= cast(TypedPosition) category[index]; |
129 | 455 |
456 if (offset is next.offset) | |
457 return new TypedRegion(next.getOffset(), next.getLength(), next.getType()); | |
458 | |
459 if (index is 0) | |
460 return new TypedRegion(0, next.offset, IDocument.DEFAULT_CONTENT_TYPE); | |
461 | |
134 | 462 TypedPosition previous= cast(TypedPosition) category[index - 1]; |
129 | 463 if (previous.includes(offset)) |
464 return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType()); | |
465 | |
466 int endOffset= previous.getOffset() + previous.getLength(); | |
467 return new TypedRegion(endOffset, next.getOffset() - endOffset, IDocument.DEFAULT_CONTENT_TYPE); | |
468 } | |
469 | |
134 | 470 TypedPosition previous= cast(TypedPosition) category[category.length - 1]; |
129 | 471 if (previous.includes(offset)) |
472 return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType()); | |
473 | |
474 int endOffset= previous.getOffset() + previous.getLength(); | |
475 return new TypedRegion(endOffset, fDocument.getLength() - endOffset, IDocument.DEFAULT_CONTENT_TYPE); | |
476 | |
477 } catch (BadPositionCategoryException x) { | |
478 } catch (BadLocationException x) { | |
479 } | |
480 | |
481 return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE); | |
482 } | |
483 | |
484 /* | |
485 * @see IDocumentPartitioner#computePartitioning | |
486 */ | |
487 public ITypedRegion[] computePartitioning(int offset, int length) { | |
488 return computePartitioning(offset, length, false); | |
489 } | |
490 | |
491 /* | |
492 * @see IDocumentPartitioner#getLegalContentTypes | |
493 */ | |
494 public String[] getLegalContentTypes() { | |
495 return TextUtilities.copy(fLegalContentTypes); | |
496 } | |
497 | |
498 /** | |
499 * Returns whether the given type is one of the legal content types. | |
500 * | |
501 * @param contentType the content type to check | |
502 * @return <code>true</code> if the content type is a legal content type | |
503 */ | |
504 protected bool isSupportedContentType(String contentType) { | |
505 if (contentType !is null) { | |
506 for (int i= 0; i < fLegalContentTypes.length; i++) { | |
507 if (fLegalContentTypes[i].equals(contentType)) | |
508 return true; | |
509 } | |
510 } | |
511 | |
512 return false; | |
513 } | |
514 | |
515 /** | |
516 * Returns a content type encoded in the given token. If the token's | |
517 * data is not <code>null</code> and a string it is assumed that | |
518 * it is the encoded content type. | |
519 * | |
520 * @param token the token whose content type is to be determined | |
521 * @return the token's content type | |
522 */ | |
523 protected String getTokenContentType(IToken token) { | |
524 Object data= token.getData(); | |
162 | 525 if ( auto str = cast(ArrayWrapperString)data ) |
526 return str.array; | |
129 | 527 return null; |
528 } | |
529 | |
530 /* zero-length partition support */ | |
531 | |
532 /* | |
533 * @see dwtx.jface.text.IDocumentPartitionerExtension2#getContentType(int) | |
534 * @since 3.0 | |
535 */ | |
536 public String getContentType(int offset, bool preferOpenPartitions) { | |
537 return getPartition(offset, preferOpenPartitions).getType(); | |
538 } | |
539 | |
540 /* | |
541 * @see dwtx.jface.text.IDocumentPartitionerExtension2#getPartition(int) | |
542 * @since 3.0 | |
543 */ | |
544 public ITypedRegion getPartition(int offset, bool preferOpenPartitions) { | |
545 ITypedRegion region= getPartition(offset); | |
546 if (preferOpenPartitions) { | |
547 if (region.getOffset() is offset && !region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) { | |
548 if (offset > 0) { | |
549 region= getPartition(offset - 1); | |
550 if (region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) | |
551 return region; | |
552 } | |
553 return new TypedRegion(offset, 0, IDocument.DEFAULT_CONTENT_TYPE); | |
554 } | |
555 } | |
556 return region; | |
557 } | |
558 | |
559 /* | |
560 * @see dwtx.jface.text.IDocumentPartitionerExtension2#computePartitioning(int, int) | |
561 * @since 3.0 | |
562 */ | |
563 public ITypedRegion[] computePartitioning(int offset, int length, bool includeZeroLengthPartitions) { | |
564 List list= new ArrayList(); | |
565 | |
566 try { | |
567 | |
568 int endOffset= offset + length; | |
569 | |
570 Position[] category= fDocument.getPositions(fPositionCategory); | |
571 | |
572 TypedPosition previous= null, current= null; | |
573 int start, end, gapOffset; | |
574 Position gap= null; | |
575 | |
576 for (int i= 0; i < category.length; i++) { | |
577 | |
134 | 578 current= cast(TypedPosition) category[i]; |
129 | 579 |
580 gapOffset= (previous !is null) ? previous.getOffset() + previous.getLength() : 0; | |
581 gap= new Position(gapOffset, current.getOffset() - gapOffset); | |
582 if ((includeZeroLengthPartitions || gap.getLength() > 0) && gap.overlapsWith(offset, length)) { | |
583 start= Math.max(offset, gapOffset); | |
584 end= Math.min(endOffset, gap.getOffset() + gap.getLength()); | |
585 list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE)); | |
586 } | |
587 | |
588 if (current.overlapsWith(offset, length)) { | |
589 start= Math.max(offset, current.getOffset()); | |
590 end= Math.min(endOffset, current.getOffset() + current.getLength()); | |
591 list.add(new TypedRegion(start, end - start, current.getType())); | |
592 } | |
593 | |
594 previous= current; | |
595 } | |
596 | |
597 if (previous !is null) { | |
598 gapOffset= previous.getOffset() + previous.getLength(); | |
599 gap= new Position(gapOffset, fDocument.getLength() - gapOffset); | |
600 if ((includeZeroLengthPartitions || gap.getLength() > 0) && ((includeZeroLengthPartitions && offset + length is gapOffset && gap.length is 0) || gap.overlapsWith(offset, length))) { | |
601 start= Math.max(offset, gapOffset); | |
602 end= Math.min(endOffset, fDocument.getLength()); | |
603 list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE)); | |
604 } | |
605 } | |
606 | |
607 if (list.isEmpty()) | |
608 list.add(new TypedRegion(offset, length, IDocument.DEFAULT_CONTENT_TYPE)); | |
609 | |
610 } catch (BadPositionCategoryException x) { | |
611 } | |
612 | |
162 | 613 return arraycast!(ITypedRegion)(list.toArray()); |
129 | 614 } |
615 } |