1 11 12 package org.eclipse.jdt.internal.ui.text.comment; 13 14 import java.util.Iterator ; 15 import java.util.LinkedList ; 16 import java.util.Map ; 17 18 import org.eclipse.text.edits.InsertEdit; 19 import org.eclipse.text.edits.MalformedTreeException; 20 import org.eclipse.text.edits.MultiTextEdit; 21 import org.eclipse.text.edits.ReplaceEdit; 22 import org.eclipse.text.edits.TextEdit; 23 24 import org.eclipse.jface.preference.IPreferenceStore; 25 26 import org.eclipse.jface.text.BadLocationException; 27 import org.eclipse.jface.text.ConfigurableLineTracker; 28 import org.eclipse.jface.text.IDocument; 29 import org.eclipse.jface.text.ILineTracker; 30 import org.eclipse.jface.text.IRegion; 31 import org.eclipse.jface.text.TypedPosition; 32 33 import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; 34 35 import org.eclipse.jdt.ui.PreferenceConstants; 36 37 import org.eclipse.jdt.internal.ui.JavaPlugin; 38 import org.eclipse.jdt.internal.ui.text.javadoc.IHtmlTagConstants; 39 40 45 public class CommentRegion extends TypedPosition implements IHtmlTagConstants, IBorderAttributes, ICommentAttributes { 46 47 48 public static final int COMMENT_PREFIX_LENGTH= 3; 49 50 51 protected static final String COMMENT_RANGE_DELIMITER= " "; 53 54 private int fBorders= 0; 55 56 57 private final boolean fClear; 58 59 60 private final String fDelimiter; 61 62 63 private final IDocument fDocument; 64 65 66 private final ITextMeasurement fTextMeasurement; 67 68 69 private final LinkedList fLines= new LinkedList (); 70 71 72 private final Map fPreferences; 73 74 75 private final LinkedList fRanges= new LinkedList (); 76 77 78 private MultiTextEdit fResult= new MultiTextEdit(); 79 80 81 private final boolean fSingleLine; 82 83 84 private int fTabs; 85 86 100 protected CommentRegion(final IDocument document, final TypedPosition position, final String delimiter, final Map preferences, final ITextMeasurement textMeasurement) { 101 super(position.getOffset(), position.getLength(), position.getType()); 102 103 fDelimiter= delimiter; 104 fPreferences= preferences; 105 fDocument= document; 106 107 fClear= fPreferences.get(PreferenceConstants.FORMATTER_COMMENT_CLEARBLANKLINES) == IPreferenceStore.TRUE; 108 109 fTextMeasurement= textMeasurement; 110 111 if (fPreferences.containsKey(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE)) 112 try { 113 fTabs= Integer.parseInt((String ) fPreferences.get(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE)); 114 } catch (NumberFormatException e) { 115 fTabs= 4; 116 } 117 else 118 fTabs= 4; 119 120 final ILineTracker tracker= new ConfigurableLineTracker(new String [] { delimiter }); 121 122 IRegion range= null; 123 CommentLine line= null; 124 125 tracker.set(getText(0, getLength())); 126 final int lines= tracker.getNumberOfLines(); 127 128 fSingleLine= lines == 1; 129 130 try { 131 132 for (int index= 0; index < lines; index++) { 133 134 range= tracker.getLineInformation(index); 135 line= CommentObjectFactory.createLine(this); 136 line.append(new CommentRange(range.getOffset(), range.getLength())); 137 138 fLines.add(line); 139 } 140 141 } catch (BadLocationException exception) { 142 } 144 } 145 146 152 protected final void append(final CommentRange range) { 153 fRanges.addLast(range); 154 } 155 156 176 protected boolean canAppend(final CommentLine line, final CommentRange previous, final CommentRange next, final int index, final int width) { 177 return index == 0 || index + next.getLength() <= width; 178 } 179 180 190 protected boolean canFormat(final CommentRange previous, final CommentRange next) { 191 return true; 192 } 193 194 200 public final TextEdit format(final String indentation) { 201 202 fResult= new MultiTextEdit(); 203 204 final String probe= getText(0, CommentLine.NON_FORMAT_START_PREFIX.length()); 205 if (!probe.startsWith(CommentLine.NON_FORMAT_START_PREFIX)) { 206 207 int margin= 80; 208 try { 209 margin= Integer.parseInt(fPreferences.get(PreferenceConstants.FORMATTER_COMMENT_LINELENGTH).toString()); 210 } catch (Exception exception) { 211 } 213 margin= Math.max(COMMENT_PREFIX_LENGTH + 1, margin - stringToLength(indentation) - COMMENT_PREFIX_LENGTH); 214 215 tokenizeRegion(); 216 markRegion(); 217 wrapRegion(margin); 218 formatRegion(indentation, margin); 219 220 } 221 return fResult; 222 } 223 224 233 protected void formatRegion(final String indentation, final int width) { 234 235 final int last= fLines.size() - 1; 236 if (last >= 0) { 237 238 CommentLine previous= null; 239 CommentLine next= (CommentLine)fLines.get(last); 240 241 CommentRange range= next.getLast(); 242 next.formatLowerBorder(range, indentation, width); 243 244 for (int line= last; line >= 0; line--) { 245 246 previous= next; 247 next= (CommentLine)fLines.get(line); 248 249 range= next.formatLine(previous, range, indentation, line); } 251 next.formatUpperBorder(range, indentation, width); 252 } 253 } 254 255 260 protected final String getDelimiter() { 261 return fDelimiter; 262 } 263 264 279 protected String getDelimiter(final CommentLine predecessor, final CommentLine successor, final CommentRange previous, final CommentRange next, final String indentation) { 280 return fDelimiter + indentation + successor.getContentPrefix(); 281 } 282 283 293 protected String getDelimiter(final CommentRange previous, final CommentRange next) { 294 return COMMENT_RANGE_DELIMITER; 295 } 296 297 302 protected final IDocument getDocument() { 303 return fDocument; 304 } 305 306 311 public final Map getPreferences() { 312 return fPreferences; 313 } 314 315 320 protected final LinkedList getRanges() { 321 return fRanges; 322 } 323 324 329 protected final int getSize() { 330 return fLines.size(); 331 } 332 333 343 protected final String getText(final int position, final int count) { 344 345 String content= ""; try { 347 content= fDocument.get(getOffset() + position, count); 348 } catch (BadLocationException exception) { 349 } 351 return content; 352 } 353 354 362 protected final boolean hasBorder(final int border) { 363 return (fBorders & border) == border; 364 } 365 366 374 protected final boolean isAlphaNumeric(final CommentRange range) { 375 376 final String token= getText(range.getOffset(), range.getLength()); 377 378 for (int index= 0; index < token.length(); index++) { 379 if (!Character.isLetterOrDigit(token.charAt(index))) 380 return false; 381 } 382 return true; 383 } 384 385 393 protected final boolean isNonAlphaNumeric(final CommentRange range) { 394 395 final String token= getText(range.getOffset(), range.getLength()); 396 397 for (int index= 0; index < token.length(); index++) { 398 if (Character.isLetterOrDigit(token.charAt(index))) 399 return false; 400 } 401 return true; 402 } 403 404 410 protected final boolean isClearLines() { 411 return fClear; 412 } 413 414 420 protected final boolean isSingleLine() { 421 return fSingleLine; 422 } 423 424 437 protected final TextEdit logEdit(final String change, final int position, final int count) { 438 439 TextEdit child= null; 440 try { 441 442 final int base= getOffset() + position; 443 final String content= fDocument.get(base, count); 444 445 if (!change.equals(content)) { 446 447 if (count > 0) 448 child= new ReplaceEdit(base, count, change); 449 else 450 child= new InsertEdit(base, change); 451 452 fResult.addChild(child); 453 } 454 455 } catch (BadLocationException exception) { 456 } catch (MalformedTreeException exception) { 458 JavaPlugin.log(exception); 460 } 461 return child; 462 } 463 464 467 protected void markRegion() { 468 } 470 471 477 protected final void setBorder(final int border) { 478 fBorders |= border; 479 } 480 481 491 protected final String stringToIndent(final String reference, final boolean tabs) { 492 493 int space; 494 int pixels; 495 496 if (fTextMeasurement != null) { 497 pixels= stringToPixels(reference); 498 space= fTextMeasurement.computeWidth(" "); } else { 500 space= 1; 501 pixels= reference.length(); 502 int index= -1; 503 while ((index= reference.indexOf('\t', index+1)) >= 0) 504 pixels += fTabs-1; 505 } 506 507 final StringBuffer buffer= new StringBuffer (); 508 final int spaces= pixels / space; 509 510 if (tabs) { 511 512 final int count= spaces / fTabs; 513 final int modulo= spaces % fTabs; 514 515 for (int index= 0; index < count; index++) 516 buffer.append('\t'); 517 518 for (int index= 0; index < modulo; index++) 519 buffer.append(' '); 520 521 } else { 522 523 for (int index= 0; index < spaces; index++) 524 buffer.append(' '); 525 } 526 return buffer.toString(); 527 } 528 529 536 protected final int stringToLength(final String reference) { 537 538 int tabs= 0; 539 int count= reference.length(); 540 541 for (int index= 0; index < count; index++) { 542 543 if (reference.charAt(index) == '\t') 544 tabs++; 545 } 546 count += tabs * (fTabs - 1); 547 548 return count; 549 } 550 551 558 protected final int stringToPixels(final String reference) { 559 560 final StringBuffer buffer= new StringBuffer (); 561 562 char character= 0; 563 for (int index= 0; index < reference.length(); index++) { 564 565 character= reference.charAt(index); 566 if (character == '\t') { 567 568 for (int tab= 0; tab < fTabs; tab++) 569 buffer.append(' '); 570 571 } else 572 buffer.append(character); 573 } 574 return fTextMeasurement.computeWidth(buffer.toString()); 575 } 576 577 580 protected void tokenizeRegion() { 581 582 int index= 0; 583 CommentLine line= null; 584 585 for (final Iterator iterator= fLines.iterator(); iterator.hasNext(); index++) { 586 587 line= (CommentLine)iterator.next(); 588 589 line.scanLine(index); 590 line.tokenizeLine(index); 591 } 592 } 593 594 601 protected void wrapRegion(final int width) { 602 603 fLines.clear(); 604 605 int index= 0; 606 boolean adapted= false; 607 608 CommentLine successor= null; 609 CommentLine predecessor= null; 610 611 CommentRange previous= null; 612 CommentRange next= null; 613 614 while (!fRanges.isEmpty()) { 615 616 index= 0; 617 adapted= false; 618 619 predecessor= successor; 620 successor= CommentObjectFactory.createLine(this); 621 fLines.add(successor); 622 623 while (!fRanges.isEmpty()) { 624 next= (CommentRange)fRanges.getFirst(); 625 626 if (canAppend(successor, previous, next, index, width)) { 627 628 if (!adapted && predecessor != null) { 629 630 successor.adapt(predecessor); 631 adapted= true; 632 } 633 634 fRanges.removeFirst(); 635 successor.append(next); 636 637 index += (next.getLength() + 1); 638 previous= next; 639 } else 640 break; 641 } 642 } 643 } 644 } 645 | Popular Tags |