1 19 20 package org.netbeans.modules.editor.java; 21 22 import com.sun.source.tree.*; 23 import com.sun.source.util.TreePath; 24 import java.awt.Color ; 25 import java.awt.Font ; 26 import java.awt.Graphics ; 27 import java.awt.event.KeyEvent ; 28 import java.io.IOException ; 29 import java.util.*; 30 import java.util.logging.Level ; 31 import java.util.logging.Logger ; 32 import javax.lang.model.element.*; 33 import javax.lang.model.type.*; 34 import javax.lang.model.util.Elements; 35 import javax.swing.ImageIcon ; 36 import javax.swing.text.BadLocationException ; 37 import javax.swing.text.JTextComponent ; 38 import javax.swing.text.Position ; 39 import org.netbeans.api.editor.completion.Completion; 40 import org.netbeans.api.java.lexer.JavaTokenId; 41 import org.netbeans.api.java.source.*; 42 import org.netbeans.api.java.source.JavaSource.Phase; 43 import org.netbeans.api.lexer.TokenSequence; 44 import org.netbeans.editor.BaseDocument; 45 import org.netbeans.lib.editor.codetemplates.api.CodeTemplateManager; 46 import org.netbeans.modules.java.editor.codegen.GeneratorUtils; 47 import org.netbeans.spi.editor.completion.CompletionItem; 48 import org.netbeans.spi.editor.completion.CompletionTask; 49 import org.netbeans.spi.editor.completion.support.CompletionUtilities; 50 import org.openide.xml.XMLUtil; 51 52 56 public abstract class JavaCompletionItem implements CompletionItem { 57 58 protected static int SMART_TYPE = 1000; 59 60 public static final JavaCompletionItem createKeywordItem(String kwd, String postfix, int substitutionOffset, boolean smartType) { 61 return new KeywordItem(kwd, 0, postfix, substitutionOffset, smartType); 62 } 63 64 public static final JavaCompletionItem createPackageItem(String pkgFQN, int substitutionOffset, boolean isDeprecated) { 65 return new PackageItem(pkgFQN, substitutionOffset, isDeprecated); 66 } 67 68 public static final JavaCompletionItem createTypeItem(TypeElement elem, DeclaredType type, int substitutionOffset, boolean displayPkgName, boolean isDeprecated, boolean smartType) { 69 switch (elem.getKind()) { 70 case CLASS: 71 return new ClassItem(elem, type, 0, substitutionOffset, displayPkgName, isDeprecated, smartType); 72 case INTERFACE: 73 return new InterfaceItem(elem, type, 0, substitutionOffset, displayPkgName, isDeprecated, smartType); 74 case ENUM: 75 return new EnumItem(elem, type, 0, substitutionOffset, displayPkgName, isDeprecated, smartType); 76 case ANNOTATION_TYPE: 77 return new AnnotationTypeItem(elem, type, 0, substitutionOffset, displayPkgName, isDeprecated, smartType); 78 default: 79 throw new IllegalArgumentException ("kind=" + elem.getKind()); 80 } 81 } 82 83 public static final JavaCompletionItem createArrayItem(ArrayType type, int substitutionOffset, Elements elements) { 84 int dim = 0; 85 TypeMirror tm = type; 86 while(tm.getKind() == TypeKind.ARRAY) { 87 tm = ((ArrayType)tm).getComponentType(); 88 dim++; 89 } 90 if (tm.getKind().isPrimitive()) 91 return new KeywordItem(tm.toString(), dim, null, substitutionOffset, true); 92 if (tm.getKind() == TypeKind.DECLARED || tm.getKind() == TypeKind.ERROR) { 93 DeclaredType dt = (DeclaredType)tm; 94 TypeElement elem = (TypeElement)dt.asElement(); 95 switch (elem.getKind()) { 96 case CLASS: 97 return new ClassItem(elem, dt, dim, substitutionOffset, true, elements.isDeprecated(elem), true); 98 case INTERFACE: 99 return new InterfaceItem(elem, dt, dim, substitutionOffset, true, elements.isDeprecated(elem), true); 100 case ENUM: 101 return new EnumItem(elem, dt, dim, substitutionOffset, true, elements.isDeprecated(elem), true); 102 case ANNOTATION_TYPE: 103 return new AnnotationTypeItem(elem, dt, dim, substitutionOffset, true, elements.isDeprecated(elem), true); 104 } 105 } 106 throw new IllegalArgumentException ("array element kind=" + tm.getKind()); 107 } 108 109 public static final JavaCompletionItem createTypeParameterItem(TypeParameterElement elem, int substitutionOffset) { 110 return new TypeParameterItem(elem, substitutionOffset); 111 } 112 113 public static final JavaCompletionItem createVariableItem(VariableElement elem, TypeMirror type, int substitutionOffset, boolean isInherited, boolean isDeprecated, boolean smartType) { 114 switch (elem.getKind()) { 115 case LOCAL_VARIABLE: 116 case PARAMETER: 117 case EXCEPTION_PARAMETER: 118 return new VariableItem(type, elem.getSimpleName().toString(), substitutionOffset, smartType); 119 case ENUM_CONSTANT: 120 case FIELD: 121 return new FieldItem(elem, type, substitutionOffset, isInherited, isDeprecated, smartType); 122 default: 123 throw new IllegalArgumentException ("kind=" + elem.getKind()); 124 } 125 } 126 127 public static final JavaCompletionItem createVariableItem(String varName, int substitutionOffset, boolean smartType) { 128 return new VariableItem(null, varName, substitutionOffset, smartType); 129 } 130 131 public static final JavaCompletionItem createExecutableItem(ExecutableElement elem, ExecutableType type, int substitutionOffset, boolean isInherited, boolean isDeprecated, boolean inImport, boolean smartType) { 132 switch (elem.getKind()) { 133 case METHOD: 134 return new MethodItem(elem, type, substitutionOffset, isInherited, isDeprecated, inImport, smartType); 135 case CONSTRUCTOR: 136 return new ConstructorItem(elem, type, substitutionOffset, isDeprecated); 137 default: 138 throw new IllegalArgumentException ("kind=" + elem.getKind()); 139 } 140 } 141 142 public static final JavaCompletionItem createOverrideMethodItem(ExecutableElement elem, ExecutableType type, int substitutionOffset, boolean implement) { 143 switch (elem.getKind()) { 144 case METHOD: 145 return new OverrideMethodItem(elem, type, substitutionOffset, implement); 146 default: 147 throw new IllegalArgumentException ("kind=" + elem.getKind()); 148 } 149 } 150 151 public static final JavaCompletionItem createDefaultConstructorItem(TypeElement elem, int substitutionOffset) { 152 return new DefaultConstructorItem(elem, substitutionOffset); 153 } 154 155 public static final JavaCompletionItem createAnnotationItem(TypeElement elem, DeclaredType type, int substitutionOffset, boolean isDeprecated) { 156 return new AnnotationItem(elem, type, substitutionOffset, isDeprecated, true); 157 } 158 159 public static final JavaCompletionItem createAttributeItem(ExecutableElement elem, ExecutableType type, int substitutionOffset, boolean isDeprecated) { 160 return new AttributeItem(elem, type, substitutionOffset, isDeprecated); 161 } 162 163 public static final JavaCompletionItem createStaticMemberItem(DeclaredType type, Element memberElem, TypeMirror memberType, int substitutionOffset, boolean isDeprecated) { 164 switch (memberElem.getKind()) { 165 case METHOD: 166 case ENUM_CONSTANT: 167 case FIELD: 168 return new StaticMemberItem(type, memberElem, memberType, substitutionOffset, isDeprecated); 169 default: 170 throw new IllegalArgumentException ("kind=" + memberElem.getKind()); 171 } 172 } 173 174 public static final JavaCompletionItem createInitializeAllConstructorItem(Iterable <? extends VariableElement> fields, TypeElement parent, int substitutionOffset) { 175 return new InitializeAllConstructorItem(fields, parent, substitutionOffset); 176 } 177 178 public static final String COLOR_END = "</font>"; public static final String STRIKE = "<s>"; public static final String STRIKE_END = "</s>"; public static final String BOLD = "<b>"; public static final String BOLD_END = "</b>"; 184 protected int substitutionOffset; 185 186 JavaCompletionItem(int substitutionOffset) { 187 this.substitutionOffset = substitutionOffset; 188 } 189 190 public void defaultAction(JTextComponent component) { 191 if (component != null) { 192 Completion.get().hideDocumentation(); 193 Completion.get().hideCompletion(); 194 int caretOffset = component.getSelectionEnd(); 195 substituteText(component, substitutionOffset, caretOffset - substitutionOffset, null); 196 } 197 } 198 199 public void processKeyEvent(KeyEvent evt) { 200 if (evt.getID() == KeyEvent.KEY_TYPED) { 201 switch (evt.getKeyChar()) { 202 case ';': 203 case ',': 204 case '(': 205 Completion.get().hideDocumentation(); 206 Completion.get().hideCompletion(); 207 case '.': 208 JTextComponent component = (JTextComponent )evt.getSource(); 209 int caretOffset = component.getSelectionEnd(); 210 substituteText(component, substitutionOffset, caretOffset - substitutionOffset, Character.toString(evt.getKeyChar())); 211 if (evt.getKeyChar() == '.') 212 Completion.get().showCompletion(); 213 evt.consume(); 214 break; 215 } 216 } 217 } 218 219 public boolean instantSubstitution(JTextComponent component) { 220 defaultAction(component); 221 return true; 222 } 223 224 public CompletionTask createDocumentationTask() { 225 return null; 226 } 227 228 public CompletionTask createToolTipTask() { 229 return null; 230 } 231 232 public int getPreferredWidth(Graphics g, Font defaultFont) { 233 return CompletionUtilities.getPreferredWidth(getLeftHtmlText(), getRightHtmlText(), g, defaultFont); 234 } 235 236 public void render(Graphics g, Font defaultFont, Color defaultColor, Color backgroundColor, int width, int height, boolean selected) { 237 CompletionUtilities.renderHtml(getIcon(), getLeftHtmlText(), getRightHtmlText(), g, defaultFont, defaultColor, width, height, selected); 238 } 239 240 protected ImageIcon getIcon() { 241 return null; 242 } 243 244 protected String getLeftHtmlText() { 245 return null; 246 } 247 248 protected String getRightHtmlText() { 249 return null; 250 } 251 252 protected void substituteText(JTextComponent c, int offset, int len, String toAdd) { 253 BaseDocument doc = (BaseDocument)c.getDocument(); 254 String text = getInsertPrefix().toString(); 255 if (text != null) { 256 if (toAdd != null && !toAdd.equals("\n")) { TokenSequence<JavaTokenId> sequence = Utilities.getJavaTokenSequence(c, offset + len); 258 if (sequence == null) { 259 text += toAdd; 260 toAdd = null; 261 } 262 boolean added = false; 263 while(toAdd != null && toAdd.length() > 0) { 264 String tokenText = sequence.token().text().toString(); 265 if (tokenText.startsWith(toAdd)) { 266 len = sequence.offset() - offset + toAdd.length(); 267 text += toAdd; 268 toAdd = null; 269 } else if (toAdd.startsWith(tokenText)) { 270 sequence.moveNext(); 271 len = sequence.offset() - offset; 272 text += toAdd.substring(0, tokenText.length()); 273 toAdd = toAdd.substring(tokenText.length()); 274 added = true; 275 } else if (sequence.token().id() == JavaTokenId.WHITESPACE && sequence.token().text().toString().indexOf('\n') < 0) { if (!sequence.moveNext()) { 277 text += toAdd; 278 toAdd = null; 279 } 280 } else { 281 if (!added) 282 text += toAdd; 283 toAdd = null; 284 } 285 } 286 } 287 doc.atomicLock(); 289 try { 290 String textToReplace = doc.getText(offset, len); 291 if (text.equals(textToReplace)) return; 292 293 Position position = doc.createPosition(offset); 294 doc.remove(offset, len); 295 doc.insertString(position.getOffset(), text, null); 296 } catch (BadLocationException e) { 297 } finally { 299 doc.atomicUnlock(); 300 } 301 } 302 } 303 304 private static class KeywordItem extends JavaCompletionItem { 305 306 private static final String JAVA_KEYWORD = "org/netbeans/modules/java/editor/resources/javakw_16.png"; private static final String KEYWORD_COLOR = "<font color=#000099>"; private static ImageIcon icon; 309 310 private String kwd; 311 private int dim; 312 private String postfix; 313 private boolean smartType; 314 private String leftText; 315 316 private KeywordItem(String kwd, int dim, String postfix, int substitutionOffset, boolean smartType) { 317 super(substitutionOffset); 318 this.kwd = kwd; 319 this.dim = dim; 320 this.postfix = postfix; 321 this.smartType = smartType; 322 } 323 324 public int getSortPriority() { 325 return smartType ? 600 - SMART_TYPE : 600; 326 } 327 328 public CharSequence getSortText() { 329 return kwd; 330 } 331 332 public CharSequence getInsertPrefix() { 333 return kwd; 334 } 335 336 protected ImageIcon getIcon(){ 337 if (icon == null) icon = new ImageIcon (org.openide.util.Utilities.loadImage(JAVA_KEYWORD)); 338 return icon; 339 } 340 341 protected String getLeftHtmlText() { 342 if (leftText == null) { 343 StringBuilder sb = new StringBuilder (); 344 sb.append(KEYWORD_COLOR); 345 sb.append(BOLD); 346 sb.append(kwd); 347 for(int i = 0; i < dim; i++) 348 sb.append("[]"); sb.append(BOLD_END); 350 sb.append(COLOR_END); 351 leftText = sb.toString(); 352 } 353 return leftText; 354 } 355 356 protected void substituteText(JTextComponent c, int offset, int len, String toAdd) { 357 if (dim == 0) { 358 super.substituteText(c, offset, len, toAdd != null ? toAdd : postfix); 359 return; 360 } 361 BaseDocument doc = (BaseDocument)c.getDocument(); 362 final StringBuilder text = new StringBuilder (); 363 if (toAdd != null && !toAdd.equals("\n")) { TokenSequence<JavaTokenId> sequence = Utilities.getJavaTokenSequence(c, offset + len); 365 if (sequence == null) { 366 text.append(toAdd); 367 toAdd = null; 368 } 369 boolean added = false; 370 while(toAdd != null && toAdd.length() > 0) { 371 String tokenText = sequence.token().text().toString(); 372 if (tokenText.startsWith(toAdd)) { 373 len = sequence.offset() - offset + toAdd.length(); 374 text.append(toAdd); 375 toAdd = null; 376 } else if (toAdd.startsWith(tokenText)) { 377 sequence.moveNext(); 378 len = sequence.offset() - offset; 379 text.append(toAdd.substring(0, tokenText.length())); 380 toAdd = toAdd.substring(tokenText.length()); 381 added = true; 382 } else if (sequence.token().id() == JavaTokenId.WHITESPACE && sequence.token().text().toString().indexOf('\n') < 0) { if (!sequence.moveNext()) { 384 text.append(toAdd); 385 toAdd = null; 386 } 387 } else { 388 if (!added) 389 text.append(toAdd); 390 toAdd = null; 391 } 392 } 393 } 394 StringBuilder sb = new StringBuilder (); 395 int cnt = 1; 396 sb.append(kwd); 397 for(int i = 0; i < dim; i++) { 398 sb.append("[${PAR"); sb.append(cnt++); 400 sb.append(" instanceof=\"int\" default=\"\"}]"); } 402 if (len > 0) { 403 doc.atomicLock(); 404 try { 405 doc.remove(offset, len); 406 } catch (BadLocationException e) { 407 } finally { 409 doc.atomicUnlock(); 410 } 411 } 412 CodeTemplateManager ctm = CodeTemplateManager.get(doc); 413 if (ctm != null) { 414 ctm.createTemporary(sb.append(text).toString()).insert(c); 415 } 416 } 417 418 public String toString() { 419 return kwd; 420 } 421 } 422 423 private static class PackageItem extends JavaCompletionItem { 424 425 private static final String PACKAGE = "org/netbeans/modules/java/editor/resources/package.gif"; private static final String PACKAGE_COLOR = "<font color=#005600>"; private static ImageIcon icon; 428 429 private boolean isDeprecated; 430 private String simpleName; 431 private String sortText; 432 private String leftText; 433 434 private PackageItem(String pkgFQN, int substitutionOffset, boolean isDeprecated) { 435 super(substitutionOffset); 436 this.isDeprecated = isDeprecated; 437 int idx = pkgFQN.lastIndexOf('.'); 438 this.simpleName = idx < 0 ? pkgFQN : pkgFQN.substring(idx + 1); 439 this.sortText = this.simpleName + "#" + pkgFQN; } 441 442 public int getSortPriority() { 443 return 900; 444 } 445 446 public CharSequence getSortText() { 447 return sortText; 448 } 449 450 public CharSequence getInsertPrefix() { 451 return simpleName; 452 } 453 454 protected ImageIcon getIcon(){ 455 if (icon == null) icon = new ImageIcon (org.openide.util.Utilities.loadImage(PACKAGE)); 456 return icon; 457 } 458 459 protected String getLeftHtmlText() { 460 if (leftText == null) { 461 StringBuilder sb = new StringBuilder (); 462 sb.append(PACKAGE_COLOR); 463 if (isDeprecated) 464 sb.append(STRIKE); 465 sb.append(simpleName); 466 if (isDeprecated) 467 sb.append(STRIKE_END); 468 sb.append(COLOR_END); 469 leftText = sb.toString(); 470 } 471 return leftText; 472 } 473 474 public String toString() { 475 return simpleName; 476 } 477 } 478 479 private static class ClassItem extends JavaCompletionItem { 480 481 private static final String CLASS = "org/netbeans/modules/editor/resources/completion/class_16.png"; private static final String CLASS_COLOR = "<font color=#560000>"; private static final String PKG_COLOR = "<font color=#808080>"; private static ImageIcon icon; 485 486 protected ElementHandle<TypeElement> elementHandle; 487 private TypeMirrorHandle<DeclaredType> typeHandle; 488 private int dim; 489 private boolean isDeprecated; 490 private boolean smartType; 491 private String simpleName; 492 private String typeName; 493 private String enclName; 494 private String sortText; 495 private String leftText; 496 497 private ClassItem(TypeElement elem, DeclaredType type, int dim, int substitutionOffset, boolean displayPkgName, boolean isDeprecated, boolean smartType) { 498 super(substitutionOffset); 499 this.elementHandle = ElementHandle.create(elem); 500 this.typeHandle = TypeMirrorHandle.create(type); 501 this.dim = dim; 502 this.isDeprecated = isDeprecated; 503 this.smartType = smartType; 504 this.simpleName = elem.getSimpleName().toString(); 505 this.typeName = Utilities.getTypeName(type, false).toString(); 506 this.enclName = displayPkgName ? Utilities.getElementName(elem.getEnclosingElement(), true).toString() : null; 507 this.sortText = this.simpleName + "#" + elem.getQualifiedName().toString(); } 509 510 public int getSortPriority() { 511 return smartType ? 800 - SMART_TYPE : 800; 512 } 513 514 public CharSequence getSortText() { 515 return sortText; 516 } 517 518 public CharSequence getInsertPrefix() { 519 return simpleName; 520 } 521 522 public CompletionTask createDocumentationTask() { 523 return JavaCompletionProvider.createDocTask(elementHandle); 524 } 525 526 protected ImageIcon getIcon(){ 527 if (icon == null) icon = new ImageIcon (org.openide.util.Utilities.loadImage(CLASS)); 528 return icon; 529 } 530 531 protected String getLeftHtmlText() { 532 if (leftText == null) { 533 StringBuilder sb = new StringBuilder (); 534 sb.append(getColor()); 535 if (isDeprecated) 536 sb.append(STRIKE); 537 sb.append(escape(typeName)); 538 for(int i = 0; i < dim; i++) 539 sb.append("[]"); if (isDeprecated) 541 sb.append(STRIKE_END); 542 if (enclName != null && enclName.length() > 0) { 543 sb.append(COLOR_END); 544 sb.append(PKG_COLOR); 545 sb.append(" ("); sb.append(enclName); 547 sb.append(")"); } 549 sb.append(COLOR_END); 550 leftText = sb.toString(); 551 } 552 return leftText; 553 } 554 555 protected String getColor() { 556 return CLASS_COLOR; 557 } 558 559 protected void substituteText(final JTextComponent c, final int offset, int len, String toAdd) { 560 if (enclName == null) { 561 super.substituteText(c, offset, len, toAdd); 562 return; 563 } 564 final BaseDocument doc = (BaseDocument)c.getDocument(); 565 final StringBuilder text = new StringBuilder (); 566 if (toAdd != null && !toAdd.equals("\n")) { TokenSequence<JavaTokenId> sequence = Utilities.getJavaTokenSequence(c, offset + len); 568 if (sequence == null) { 569 text.append(toAdd); 570 toAdd = null; 571 } 572 boolean added = false; 573 while(toAdd != null && toAdd.length() > 0) { 574 String tokenText = sequence.token().text().toString(); 575 if (tokenText.startsWith(toAdd)) { 576 len = sequence.offset() - offset + toAdd.length(); 577 text.append(toAdd); 578 toAdd = null; 579 } else if (toAdd.startsWith(tokenText)) { 580 sequence.moveNext(); 581 len = sequence.offset() - offset; 582 text.append(toAdd.substring(0, tokenText.length())); 583 toAdd = toAdd.substring(tokenText.length()); 584 added = true; 585 } else if (sequence.token().id() == JavaTokenId.WHITESPACE && sequence.token().text().toString().indexOf('\n') < 0) { if (!sequence.moveNext()) { 587 text.append(toAdd); 588 toAdd = null; 589 } 590 } else { 591 if (!added) 592 text.append(toAdd); 593 toAdd = null; 594 } 595 } 596 } 597 final int finalLen = len; 598 JavaSource js = JavaSource.forDocument(doc); 599 try { 600 js.runUserActionTask(new CancellableTask<CompilationController>() { 601 public void cancel() { 602 } 603 public void run(CompilationController controller) throws IOException { 604 controller.toPhase(Phase.RESOLVED); 605 TypeElement elem = elementHandle.resolve(controller); 606 DeclaredType type = typeHandle.resolve(controller); 607 boolean asTemplate = false; 608 StringBuilder sb = new StringBuilder (); 609 int cnt = 1; 610 sb.append("${PAR"); sb.append(cnt++); 612 if (type.getKind() != TypeKind.ERROR) { 613 sb.append(" type=\""); sb.append(elem.getQualifiedName()); 615 } else { 616 sb.append(" default=\""); sb.append(elem.getQualifiedName()); 618 } 619 sb.append("\" editable=false}"); Iterator<? extends TypeMirror> tas = type.getTypeArguments().iterator(); 621 if (tas.hasNext()) { 622 sb.append('<'); while (tas.hasNext()) { 624 TypeMirror ta = tas.next(); 625 sb.append("${PAR"); sb.append(cnt++); 627 if (ta.getKind() == TypeKind.TYPEVAR) { 628 sb.append(" type=\""); ta = ((TypeVariable)ta).getUpperBound(); 630 sb.append(Utilities.getTypeName(ta, true)); 631 sb.append("\"}"); } else if (ta.getKind() == TypeKind.WILDCARD) { 633 sb.append(" type=\""); TypeMirror bound = ((WildcardType)ta).getExtendsBound(); 635 if (bound == null) 636 bound = ((WildcardType)ta).getSuperBound(); 637 sb.append(bound != null ? Utilities.getTypeName(bound, true) : "java.lang.Object"); sb.append("\"}"); asTemplate = true; 640 } else if (ta.getKind() == TypeKind.ERROR) { 641 sb.append(" default=\"\"}"); asTemplate = true; 643 } else { 644 sb.append(" type=\""); sb.append(Utilities.getTypeName(ta, true)); 646 sb.append("\" editable=false}"); asTemplate = true; 648 } 649 if (tas.hasNext()) 650 sb.append(", "); } 652 sb.append('>'); } 654 for(int i = 0; i < dim; i++) { 655 sb.append("[${PAR"); sb.append(cnt++); 657 sb.append(" instanceof=\"int\" default=\"\"}]"); asTemplate = true; 659 } 660 if (asTemplate) { 661 if (finalLen > 0) { 662 doc.atomicLock(); 663 try { 664 doc.remove(offset, finalLen); 665 } catch (BadLocationException e) { 666 } finally { 668 doc.atomicUnlock(); 669 } 670 } 671 CodeTemplateManager ctm = CodeTemplateManager.get(doc); 672 if (ctm != null) 673 ctm.createTemporary(sb.append(text).toString()).insert(c); 674 } else { 675 doc.atomicLock(); 677 try { 678 TreePath tp = controller.getTreeUtilities().pathFor(offset); 679 text.insert(0, AutoImport.resolveImport(controller, tp, controller.getTypes().getDeclaredType(elem))); 680 String textToReplace = doc.getText(offset, finalLen); 681 if (textToReplace.contentEquals(text)) return; 682 doc.remove(offset, finalLen); 683 doc.insertString(offset, text.toString(), null); 684 } catch (BadLocationException e) { 685 } finally { 687 doc.atomicUnlock(); 688 } 689 } 690 } 691 }, true); 692 } catch (IOException ioe) { 693 } 694 } 695 696 public String toString() { 697 return simpleName; 698 } 699 } 700 701 private static class InterfaceItem extends ClassItem { 702 703 private static final String INTERFACE = "org/netbeans/modules/editor/resources/completion/interface.png"; private static final String INTERFACE_COLOR = "<font color=#404040>"; private static ImageIcon icon; 706 707 private InterfaceItem(TypeElement elem, DeclaredType type, int dim, int substitutionOffset, boolean displayPkgName, boolean isDeprecated, boolean smartType) { 708 super(elem, type, dim, substitutionOffset, displayPkgName, isDeprecated, smartType); 709 } 710 711 protected ImageIcon getIcon(){ 712 if (icon == null) icon = new ImageIcon (org.openide.util.Utilities.loadImage(INTERFACE)); 713 return icon; 714 } 715 716 protected String getColor() { 717 return INTERFACE_COLOR; 718 } 719 } 720 721 private static class EnumItem extends ClassItem { 722 723 private static final String ENUM = "org/netbeans/modules/editor/resources/completion/enum.png"; private static ImageIcon icon; 725 726 private EnumItem(TypeElement elem, DeclaredType type, int dim, int substitutionOffset, boolean displayPkgName, boolean isDeprecated, boolean smartType) { 727 super(elem, type, dim, substitutionOffset, displayPkgName, isDeprecated, smartType); 728 } 729 730 protected ImageIcon getIcon(){ 731 if (icon == null) icon = new ImageIcon (org.openide.util.Utilities.loadImage(ENUM)); 732 return icon; 733 } 734 } 735 736 private static class AnnotationTypeItem extends ClassItem { 737 738 private static final String ANNOTATION = "org/netbeans/modules/editor/resources/completion/annotation_type.png"; private static ImageIcon icon; 740 741 private AnnotationTypeItem(TypeElement elem, DeclaredType type, int dim, int substitutionOffset, boolean displayPkgName, boolean isDeprecated, boolean smartType) { 742 super(elem, type, dim, substitutionOffset, displayPkgName, isDeprecated, smartType); 743 } 744 745 protected ImageIcon getIcon(){ 746 if (icon == null) icon = new ImageIcon (org.openide.util.Utilities.loadImage(ANNOTATION)); 747 return icon; 748 } 749 } 750 751 private static class TypeParameterItem extends JavaCompletionItem { 752 753 private static final String TYPE_PARAMETER_COLOR = "<font color=#000000>"; 755 private String simpleName; 756 private String leftText; 757 758 private TypeParameterItem(TypeParameterElement elem, int substitutionOffset) { 759 super(substitutionOffset); 760 this.simpleName = elem.getSimpleName().toString(); 761 } 762 763 public int getSortPriority() { 764 return 700; 765 } 766 767 public CharSequence getSortText() { 768 return simpleName; 769 } 770 771 public CharSequence getInsertPrefix() { 772 return simpleName; 773 } 774 775 protected String getLeftHtmlText() { 776 if (leftText == null) 777 leftText = TYPE_PARAMETER_COLOR + simpleName + COLOR_END; 778 return leftText; 779 } 780 781 public String toString() { 782 return simpleName; 783 } 784 } 785 786 private static class VariableItem extends JavaCompletionItem { 787 788 private static final String LOCAL_VARIABLE = "org/netbeans/modules/editor/resources/completion/localVariable.gif"; private static final String PARAMETER_COLOR = "<font color=#00007c>"; private static ImageIcon icon; 791 792 private String varName; 793 private boolean smartType; 794 private String typeName; 795 private String leftText; 796 private String rightText; 797 798 private VariableItem(TypeMirror type, String varName, int substitutionOffset, boolean smartType) { 799 super(substitutionOffset); 800 this.varName = varName; 801 this.smartType = smartType; 802 this.typeName = type != null ? Utilities.getTypeName(type, false).toString() : null; 803 } 804 805 public int getSortPriority() { 806 return smartType ? 200 - SMART_TYPE : 200; 807 } 808 809 public CharSequence getSortText() { 810 return varName; 811 } 812 813 public CharSequence getInsertPrefix() { 814 return varName; 815 } 816 817 protected String getLeftHtmlText() { 818 if (leftText == null) 819 leftText = PARAMETER_COLOR + BOLD + varName + BOLD_END + COLOR_END; 820 return leftText; 821 } 822 823 protected String getRightHtmlText() { 824 if (rightText == null) 825 rightText = escape(typeName); 826 return rightText; 827 } 828 829 protected ImageIcon getIcon(){ 830 if (icon == null) icon = new ImageIcon (org.openide.util.Utilities.loadImage(LOCAL_VARIABLE)); 831 return icon; 832 } 833 834 public String toString() { 835 return (typeName != null ? typeName + " " : "") + varName; } 837 } 838 839 private static class FieldItem extends JavaCompletionItem { 840 841 private static final String FIELD_PUBLIC = "org/netbeans/modules/editor/resources/completion/field_16.png"; private static final String FIELD_PROTECTED = "org/netbeans/modules/editor/resources/completion/field_protected_16.png"; private static final String FIELD_PACKAGE = "org/netbeans/modules/editor/resources/completion/field_package_private_16.png"; private static final String FIELD_PRIVATE = "org/netbeans/modules/editor/resources/completion/field_private_16.png"; private static final String FIELD_ST_PUBLIC = "org/netbeans/modules/editor/resources/completion/field_static_16.png"; private static final String FIELD_ST_PROTECTED = "org/netbeans/modules/editor/resources/completion/field_static_protected_16.png"; private static final String FIELD_ST_PACKAGE = "org/netbeans/modules/editor/resources/completion/field_static_package_private_16.png"; private static final String FIELD_ST_PRIVATE = "org/netbeans/modules/editor/resources/completion/field_static_private_16.png"; private static final String FIELD_COLOR = "<font color=#008618>"; private static ImageIcon icon[][] = new ImageIcon [2][4]; 851 852 private ElementHandle<VariableElement> elementHandle; 853 private boolean isInherited; 854 private boolean isDeprecated; 855 private boolean smartType; 856 private String simpleName; 857 private Set<Modifier> modifiers; 858 private String typeName; 859 private String leftText; 860 private String rightText; 861 862 private FieldItem(VariableElement elem, TypeMirror type, int substitutionOffset, boolean isInherited, boolean isDeprecated, boolean smartType) { 863 super(substitutionOffset); 864 this.elementHandle = ElementHandle.create(elem); 865 this.isInherited = isInherited; 866 this.isDeprecated = isDeprecated; 867 this.smartType = smartType; 868 this.simpleName = elem.getSimpleName().toString(); 869 this.modifiers = elem.getModifiers(); 870 this.typeName = Utilities.getTypeName(type, false).toString(); 871 } 872 873 public int getSortPriority() { 874 return smartType ? 300 - SMART_TYPE : 300; 875 } 876 877 public CharSequence getSortText() { 878 return simpleName; 879 } 880 881 public CharSequence getInsertPrefix() { 882 return simpleName; 883 } 884 885 public CompletionTask createDocumentationTask() { 886 return JavaCompletionProvider.createDocTask(elementHandle); 887 } 888 889 protected String getLeftHtmlText() { 890 if (leftText == null) { 891 StringBuilder sb = new StringBuilder (); 892 sb.append(FIELD_COLOR); 893 if (!isInherited) 894 sb.append(BOLD); 895 if (isDeprecated) 896 sb.append(STRIKE); 897 sb.append(simpleName); 898 if (isDeprecated) 899 sb.append(STRIKE_END); 900 if (!isInherited) 901 sb.append(BOLD_END); 902 sb.append(COLOR_END); 903 leftText = sb.toString(); 904 } 905 return leftText; 906 } 907 908 protected String getRightHtmlText() { 909 if (rightText == null) 910 rightText = escape(typeName); 911 return rightText; 912 } 913 914 protected ImageIcon getIcon(){ 915 int level = getProtectionLevel(modifiers); 916 boolean isStatic = modifiers.contains(Modifier.STATIC); 917 ImageIcon cachedIcon = icon[isStatic?1:0][level]; 918 if (cachedIcon != null) 919 return cachedIcon; 920 921 String iconPath = FIELD_PUBLIC; 922 if (isStatic) { 923 switch (level) { 924 case PRIVATE_LEVEL: 925 iconPath = FIELD_ST_PRIVATE; 926 break; 927 928 case PACKAGE_LEVEL: 929 iconPath = FIELD_ST_PACKAGE; 930 break; 931 932 case PROTECTED_LEVEL: 933 iconPath = FIELD_ST_PROTECTED; 934 break; 935 936 case PUBLIC_LEVEL: 937 iconPath = FIELD_ST_PUBLIC; 938 break; 939 } 940 }else{ 941 switch (level) { 942 case PRIVATE_LEVEL: 943 iconPath = FIELD_PRIVATE; 944 break; 945 946 case PACKAGE_LEVEL: 947 iconPath = FIELD_PACKAGE; 948 break; 949 950 case PROTECTED_LEVEL: 951 iconPath = FIELD_PROTECTED; 952 break; 953 954 case PUBLIC_LEVEL: 955 iconPath = FIELD_PUBLIC; 956 break; 957 } 958 } 959 ImageIcon newIcon = new ImageIcon (org.openide.util.Utilities.loadImage(iconPath)); 960 icon[isStatic?1:0][level] = newIcon; 961 return newIcon; 962 } 963 964 public String toString() { 965 StringBuilder sb = new StringBuilder (); 966 for(Modifier mod : modifiers) { 967 sb.append(mod.toString()); 968 sb.append(' '); 969 } 970 sb.append(typeName); 971 sb.append(' '); 972 sb.append(simpleName); 973 return sb.toString(); 974 } 975 } 976 977 private static class MethodItem extends JavaCompletionItem { 978 979 private static final String METHOD_PUBLIC = "org/netbeans/modules/editor/resources/completion/method_16.png"; private static final String METHOD_PROTECTED = "org/netbeans/modules/editor/resources/completion/method_protected_16.png"; private static final String METHOD_PACKAGE = "org/netbeans/modules/editor/resources/completion/method_package_private_16.png"; private static final String METHOD_PRIVATE = "org/netbeans/modules/editor/resources/completion/method_private_16.png"; private static final String METHOD_ST_PUBLIC = "org/netbeans/modules/editor/resources/completion/method_static_16.png"; private static final String METHOD_ST_PROTECTED = "org/netbeans/modules/editor/resources/completion/method_static_protected_16.png"; private static final String METHOD_ST_PRIVATE = "org/netbeans/modules/editor/resources/completion/method_static_private_16.png"; private static final String METHOD_ST_PACKAGE = "org/netbeans/modules/editor/resources/completion/method_static_package_private_16.png"; private static final String METHOD_COLOR = "<font color=#000000>"; private static final String PARAMETER_NAME_COLOR = "<font color=#a06001>"; private static ImageIcon icon[][] = new ImageIcon [2][4]; 990 991 protected ElementHandle<ExecutableElement> elementHandle; 992 private boolean isInherited; 993 private boolean isDeprecated; 994 private boolean inImport; 995 private boolean smartType; 996 private String simpleName; 997 protected Set<Modifier> modifiers; 998 private List<ParamDesc> params; 999 private String typeName; 1000 private boolean isPrimitive; 1001 private String sortText; 1002 private String leftText; 1003 private String rightText; 1004 1005 private MethodItem(ExecutableElement elem, ExecutableType type, int substitutionOffset, boolean isInherited, boolean isDeprecated, boolean inImport, boolean smartType) { 1006 super(substitutionOffset); 1007 this.elementHandle = ElementHandle.create(elem); 1008 this.isInherited = isInherited; 1009 this.isDeprecated = isDeprecated; 1010 this.inImport = inImport; 1011 this.smartType = smartType; 1012 this.simpleName = elem.getSimpleName().toString(); 1013 this.modifiers = elem.getModifiers(); 1014 this.params = new ArrayList<ParamDesc>(); 1015 Iterator<? extends VariableElement> it = elem.getParameters().iterator(); 1016 Iterator<? extends TypeMirror> tIt = type.getParameterTypes().iterator(); 1017 while(it.hasNext() && tIt.hasNext()) { 1018 TypeMirror tm = tIt.next(); 1019 this.params.add(new ParamDesc(tm.toString(), Utilities.getTypeName(tm, false, elem.isVarArgs() && !tIt.hasNext()).toString(), it.next().getSimpleName().toString())); 1020 } 1021 TypeMirror retType = type.getReturnType(); 1022 this.typeName = Utilities.getTypeName(retType, false).toString(); 1023 this.isPrimitive = retType.getKind().isPrimitive() || retType.getKind() == TypeKind.VOID; 1024 } 1025 1026 public int getSortPriority() { 1027 return smartType ? 500 - SMART_TYPE : 500; 1028 } 1029 1030 public CharSequence getSortText() { 1031 if (sortText == null) { 1032 StringBuilder sortParams = new StringBuilder (); 1033 sortParams.append('('); 1034 int cnt = 0; 1035 for(Iterator<ParamDesc> it = params.iterator(); it.hasNext();) { 1036 ParamDesc param = it.next(); 1037 sortParams.append(param.typeName); 1038 if (it.hasNext()) { 1039 sortParams.append(','); 1040 } 1041 cnt++; 1042 } 1043 sortParams.append(')'); 1044 sortText = simpleName + "#" + ((cnt < 10 ? "0" : "") + cnt) + "#" + sortParams.toString(); } 1046 return sortText; 1047 } 1048 1049 public CharSequence getInsertPrefix() { 1050 return simpleName; 1051 } 1052 1053 protected String getLeftHtmlText() { 1054 if (leftText == null) { 1055 StringBuilder lText = new StringBuilder (); 1056 lText.append(METHOD_COLOR); 1057 if (!isInherited) 1058 lText.append(BOLD); 1059 if (isDeprecated) 1060 lText.append(STRIKE); 1061 lText.append(simpleName); 1062 if (isDeprecated) 1063 lText.append(STRIKE_END); 1064 if (!isInherited) 1065 lText.append(BOLD_END); 1066 lText.append(COLOR_END); 1067 lText.append('('); 1068 for (Iterator<ParamDesc> it = params.iterator(); it.hasNext();) { 1069 ParamDesc paramDesc = it.next(); 1070 lText.append(escape(paramDesc.typeName)); 1071 lText.append(' '); 1072 lText.append(PARAMETER_NAME_COLOR); 1073 lText.append(paramDesc.name); 1074 lText.append(COLOR_END); 1075 if (it.hasNext()) { 1076 lText.append(", "); } 1078 } 1079 lText.append(')'); 1080 return lText.toString(); 1081 } 1082 return leftText; 1083 } 1084 1085 protected String getRightHtmlText() { 1086 if (rightText == null) 1087 rightText = escape(typeName); 1088 return rightText; 1089 } 1090 1091 public CompletionTask createDocumentationTask() { 1092 return JavaCompletionProvider.createDocTask(elementHandle); 1093 } 1094 1095 protected ImageIcon getIcon() { 1096 int level = getProtectionLevel(modifiers); 1097 boolean isStatic = modifiers.contains(Modifier.STATIC); 1098 ImageIcon cachedIcon = icon[isStatic?1:0][level]; 1099 if (cachedIcon != null) 1100 return cachedIcon; 1101 1102 String iconPath = METHOD_PUBLIC; 1103 if (isStatic) { 1104 switch (level) { 1105 case PRIVATE_LEVEL: 1106 iconPath = METHOD_ST_PRIVATE; 1107 break; 1108 1109 case PACKAGE_LEVEL: 1110 iconPath = METHOD_ST_PACKAGE; 1111 break; 1112 1113 case PROTECTED_LEVEL: 1114 iconPath = METHOD_ST_PROTECTED; 1115 break; 1116 1117 case PUBLIC_LEVEL: 1118 iconPath = METHOD_ST_PUBLIC; 1119 break; 1120 } 1121 }else{ 1122 switch (level) { 1123 case PRIVATE_LEVEL: 1124 iconPath = METHOD_PRIVATE; 1125 break; 1126 1127 case PACKAGE_LEVEL: 1128 iconPath = METHOD_PACKAGE; 1129 break; 1130 1131 case PROTECTED_LEVEL: 1132 iconPath = METHOD_PROTECTED; 1133 break; 1134 1135 case PUBLIC_LEVEL: 1136 iconPath = METHOD_PUBLIC; 1137 break; 1138 } 1139 } 1140 ImageIcon newIcon = new ImageIcon (org.openide.util.Utilities.loadImage(iconPath)); 1141 icon[isStatic?1:0][level] = newIcon; 1142 return newIcon; 1143 } 1144 1145 protected void substituteText(final JTextComponent c, int offset, int len, String toAdd) { 1146 if (toAdd == null) { 1147 if (isPrimitive) { 1148 try { 1149 final String [] ret = new String [1]; 1150 JavaSource js = JavaSource.forDocument(c.getDocument()); 1151 js.runUserActionTask(new CancellableTask<CompilationController>() { 1152 public void cancel() { 1153 } 1154 public void run(CompilationController controller) throws Exception { 1155 controller.toPhase(JavaSource.Phase.PARSED); 1156 TreePath tp = controller.getTreeUtilities().pathFor(c.getSelectionEnd()); 1157 Tree tree = tp.getLeaf(); 1158 if (tree.getKind() == Tree.Kind.IDENTIFIER || tree.getKind() == Tree.Kind.PRIMITIVE_TYPE) 1159 tp = tp.getParentPath(); 1160 if (tp.getLeaf().getKind() == Tree.Kind.MEMBER_SELECT || 1161 (tp.getLeaf().getKind() == Tree.Kind.METHOD_INVOCATION && ((MethodInvocationTree)tp.getLeaf()).getMethodSelect() == tree)) 1162 tp = tp.getParentPath(); 1163 if (tp.getLeaf().getKind() == Tree.Kind.EXPRESSION_STATEMENT || tp.getLeaf().getKind() == Tree.Kind.BLOCK) 1164 ret[0] = ";"; } 1166 }, true); 1167 toAdd = ret[0]; 1168 } catch (IOException ex) { 1169 } 1170 } 1171 } 1172 String add = inImport ? ";" : "()"; if (toAdd != null && !add.startsWith(toAdd)) 1174 add += toAdd; 1175 if (inImport || params.isEmpty()) { 1176 super.substituteText(c, offset, len, add); 1177 } else { 1178 BaseDocument doc = (BaseDocument)c.getDocument(); 1179 String text = ""; TokenSequence<JavaTokenId> sequence = Utilities.getJavaTokenSequence(c, offset + len); 1181 if (sequence == null) { 1182 text += add; 1183 add = null; 1184 } 1185 boolean added = false; 1186 while(add != null && add.length() > 0) { 1187 String tokenText = sequence.token().text().toString(); 1188 if (tokenText.startsWith(add)) { 1189 len = sequence.offset() - offset + add.length(); 1190 text += add; 1191 add = null; 1192 } else if (add.startsWith(tokenText)) { 1193 sequence.moveNext(); 1194 len = sequence.offset() - offset; 1195 text += add.substring(0, tokenText.length()); 1196 add = add.substring(tokenText.length()); 1197 added = true; 1198 } else if (sequence.token().id() == JavaTokenId.WHITESPACE && sequence.token().text().toString().indexOf('\n') < 0) { if (!sequence.moveNext()) { 1200 text += add; 1201 add = null; 1202 } 1203 } else { 1204 if (!added) 1205 text += add; 1206 add = null; 1207 } 1208 } 1209 if (len > 0) { 1210 doc.atomicLock(); 1211 try { 1212 doc.remove(offset, len); 1213 } catch (BadLocationException e) { 1214 } finally { 1216 doc.atomicUnlock(); 1217 } 1218 } 1219 CodeTemplateManager ctm = CodeTemplateManager.get(doc); 1220 if (ctm != null) { 1221 StringBuilder sb = new StringBuilder (); 1222 sb.append(getInsertPrefix()); 1223 sb.append("("); if (text.length() > 1) { 1225 for (Iterator<ParamDesc> it = params.iterator(); it.hasNext();) { 1226 ParamDesc paramDesc = it.next(); 1227 sb.append("${"); sb.append(paramDesc.name); 1229 sb.append(" named instanceof="); sb.append(paramDesc.fullTypeName); 1231 sb.append("}"); if (it.hasNext()) 1233 sb.append(", "); } 1235 sb.append(")"); if (text.length() > 2) 1237 sb.append(text.substring(2)); 1238 } 1239 ctm.createTemporary(sb.toString()).insert(c); 1240 Completion.get().showToolTip(); 1241 } 1242 } 1243 } 1244 1245 public String toString() { 1246 StringBuilder sb = new StringBuilder (); 1247 for (Modifier mod : modifiers) { 1248 sb.append(mod.toString()); 1249 sb.append(' '); 1250 } 1251 sb.append(typeName); 1252 sb.append(' '); 1253 sb.append(simpleName); 1254 sb.append('('); 1255 for (Iterator<ParamDesc> it = params.iterator(); it.hasNext();) { 1256 ParamDesc paramDesc = it.next(); 1257 sb.append(paramDesc.typeName); 1258 sb.append(' '); 1259 sb.append(paramDesc.name); 1260 if (it.hasNext()) { 1261 sb.append(", "); } 1263 } 1264 sb.append(')'); 1265 return sb.toString(); 1266 } 1267 } 1268 1269 private static class OverrideMethodItem extends MethodItem { 1270 1271 private static final String IMPL_BADGE_PATH = "org/netbeans/modules/java/editor/resources/implement_badge.png"; 1272 private static final String OVRD_BADGE_PATH = "org/netbeans/modules/java/editor/resources/override_badge.png"; 1273 1274 private static ImageIcon implementBadge = new ImageIcon (org.openide.util.Utilities.loadImage(IMPL_BADGE_PATH)); 1275 private static ImageIcon overrideBadge = new ImageIcon (org.openide.util.Utilities.loadImage(OVRD_BADGE_PATH)); 1276 private static ImageIcon merged_icon[][] = new ImageIcon [2][4]; 1277 1278 private boolean implement; 1279 private String leftText; 1280 1281 private OverrideMethodItem(ExecutableElement elem, ExecutableType type, int substitutionOffset, boolean implement) { 1282 super(elem, type, substitutionOffset, false, false, false, false); 1283 this.implement = implement; 1284 } 1285 1286 protected String getLeftHtmlText() { 1287 if (leftText == null) 1288 leftText = super.getLeftHtmlText() + (implement ? " - implement" : " - override"); 1289 return leftText; 1290 } 1291 1292 @Override 1293 protected ImageIcon getIcon() { 1294 int level = getProtectionLevel(modifiers); 1295 ImageIcon merged = merged_icon[implement? 0 : 1][level]; 1296 if ( merged != null ) { 1297 return merged; 1298 } 1299 ImageIcon superIcon = super.getIcon(); 1300 merged = new ImageIcon ( org.openide.util.Utilities.mergeImages( 1301 superIcon.getImage(), 1302 implement ? implementBadge.getImage() : overrideBadge.getImage(), 1303 16 - 8, 1304 16 - 8) ); 1305 1306 merged_icon[implement? 0 : 1][level] = merged; 1307 return merged; 1308 } 1309 1310 1311 protected void substituteText(final JTextComponent c, final int offset, final int len, String toAdd) { 1312 BaseDocument doc = (BaseDocument)c.getDocument(); 1313 if (len > 0) { 1314 doc.atomicLock(); 1315 try { 1316 doc.remove(offset, len); 1317 } catch (BadLocationException e) { 1318 } finally { 1320 doc.atomicUnlock(); 1321 } 1322 } 1323 try { 1324 JavaSource js = JavaSource.forDocument(doc); 1325 js.runModificationTask(new CancellableTask<WorkingCopy>() { 1326 public void cancel() { 1327 } 1328 public void run(WorkingCopy copy) throws IOException { 1329 copy.toPhase(Phase.ELEMENTS_RESOLVED); 1330 ExecutableElement ee = elementHandle.resolve(copy); 1331 if (ee == null) 1332 return; 1333 TreePath tp = copy.getTreeUtilities().pathFor(offset); 1334 if (tp.getLeaf().getKind() == Tree.Kind.CLASS) { 1335 if (Utilities.isInMethod(tp)) 1336 copy.toPhase(Phase.RESOLVED); 1337 int idx = 0; 1338 for (Tree tree : ((ClassTree)tp.getLeaf()).getMembers()) { 1339 if (copy.getTrees().getSourcePositions().getStartPosition(tp.getCompilationUnit(), tree) < offset) 1340 idx++; 1341 else 1342 break; 1343 } 1344 if (implement) 1345 GeneratorUtils.generateAbstractMethodImplementation(copy, tp, ee, idx); 1346 else 1347 GeneratorUtils.generateMethodOverride(copy, tp, ee, idx); 1348 } 1349 } 1350 }).commit(); 1351 } catch (IOException ex) { 1352 Logger.getLogger("global").log(Level.WARNING, null, ex); 1353 } 1354 } 1355 1356 public String toString() { 1357 StringBuilder sb = new StringBuilder (); 1358 sb.append(super.toString()); 1359 sb.append(" - "); 1360 sb.append(implement ? "implement" : "override"); 1361 return sb.toString(); 1362 } 1363 1364 public boolean instantSubstitution(JTextComponent component) { 1365 return false; } 1367 } 1368 1369 private static class ConstructorItem extends JavaCompletionItem { 1370 1371 private static final String CONSTRUCTOR_PUBLIC = "org/netbeans/modules/editor/resources/completion/constructor_16.png"; private static final String CONSTRUCTOR_PROTECTED = "org/netbeans/modules/editor/resources/completion/constructor_protected_16.png"; private static final String CONSTRUCTOR_PACKAGE = "org/netbeans/modules/editor/resources/completion/constructor_package_private_16.png"; private static final String CONSTRUCTOR_PRIVATE = "org/netbeans/modules/editor/resources/completion/constructor_private_16.png"; private static final String CONSTRUCTOR_COLOR = "<font color=#b28b00>"; private static final String PARAMETER_NAME_COLOR = "<font color=#a06001>"; private static ImageIcon icon[] = new ImageIcon [4]; 1378 1379 private ElementHandle<ExecutableElement> elementHandle; 1380 private boolean isDeprecated; 1381 private String simpleName; 1382 protected Set<Modifier> modifiers; 1383 private List<ParamDesc> params; 1384 private boolean isAbstract; 1385 private String sortText; 1386 private String leftText; 1387 1388 private ConstructorItem(ExecutableElement elem, ExecutableType type, int substitutionOffset, boolean isDeprecated) { 1389 super(substitutionOffset); 1390 this.elementHandle = ElementHandle.create(elem); 1391 this.isDeprecated = isDeprecated; 1392 this.simpleName = elem.getEnclosingElement().getSimpleName().toString(); 1393 this.modifiers = elem.getModifiers(); 1394 this.params = new ArrayList<ParamDesc>(); 1395 Iterator<? extends VariableElement> it = elem.getParameters().iterator(); 1396 Iterator<? extends TypeMirror> tIt = type.getParameterTypes().iterator(); 1397 while(it.hasNext() && tIt.hasNext()) { 1398 TypeMirror tm = tIt.next(); 1399 this.params.add(new ParamDesc(tm.toString(), Utilities.getTypeName(tm, false, elem.isVarArgs() && !tIt.hasNext()).toString(), it.next().getSimpleName().toString())); 1400 } 1401 this.isAbstract = elem.getEnclosingElement().getModifiers().contains(Modifier.ABSTRACT); 1402 } 1403 1404 public int getSortPriority() { 1405 return 650; 1406 } 1407 1408 public CharSequence getSortText() { 1409 if (sortText == null) { 1410 StringBuilder sortParams = new StringBuilder (); 1411 sortParams.append('('); 1412 int cnt = 0; 1413 for (Iterator<ParamDesc> it = params.iterator(); it.hasNext();) { 1414 ParamDesc paramDesc = it.next(); 1415 sortParams.append(paramDesc.typeName); 1416 if (it.hasNext()) { 1417 sortParams.append(','); 1418 } 1419 cnt++; 1420 } 1421 sortParams.append(')'); 1422 sortText = simpleName + "#" + ((cnt < 10 ? "0" : "") + cnt) + "#" + sortParams.toString(); } 1424 return sortText; 1425 } 1426 1427 public CharSequence getInsertPrefix() { 1428 return simpleName; 1429 } 1430 1431 protected String getLeftHtmlText() { 1432 if (leftText == null) { 1433 StringBuilder lText = new StringBuilder (); 1434 lText.append(CONSTRUCTOR_COLOR); 1435 lText.append(BOLD); 1436 if (isDeprecated) 1437 lText.append(STRIKE); 1438 lText.append(simpleName); 1439 if (isDeprecated) 1440 lText.append(STRIKE_END); 1441 lText.append(BOLD_END); 1442 lText.append(COLOR_END); 1443 lText.append('('); 1444 for (Iterator<ParamDesc> it = params.iterator(); it.hasNext();) { 1445 ParamDesc paramDesc = it.next(); 1446 lText.append(escape(paramDesc.typeName)); 1447 lText.append(' '); 1448 lText.append(PARAMETER_NAME_COLOR); 1449 lText.append(paramDesc.name); 1450 lText.append(COLOR_END); 1451 if (it.hasNext()) { 1452 lText.append(", "); } 1454 } 1455 lText.append(')'); 1456 leftText = lText.toString(); 1457 } 1458 return leftText; 1459 } 1460 1461 public CompletionTask createDocumentationTask() { 1462 return JavaCompletionProvider.createDocTask(elementHandle); 1463 } 1464 1465 protected ImageIcon getIcon() { 1466 int level = getProtectionLevel(modifiers); 1467 ImageIcon cachedIcon = icon[level]; 1468 if (cachedIcon != null) 1469 return cachedIcon; 1470 1471 String iconPath = CONSTRUCTOR_PUBLIC; 1472 switch (level) { 1473 case PRIVATE_LEVEL: 1474 iconPath = CONSTRUCTOR_PRIVATE; 1475 break; 1476 1477 case PACKAGE_LEVEL: 1478 iconPath = CONSTRUCTOR_PACKAGE; 1479 break; 1480 1481 case PROTECTED_LEVEL: 1482 iconPath = CONSTRUCTOR_PROTECTED; 1483 break; 1484 1485 case PUBLIC_LEVEL: 1486 iconPath = CONSTRUCTOR_PUBLIC; 1487 break; 1488 } 1489 ImageIcon newIcon = new ImageIcon (org.openide.util.Utilities.loadImage(iconPath)); 1490 icon[level] = newIcon; 1491 return newIcon; 1492 } 1493 1494 protected void substituteText(JTextComponent c, int offset, int len, String toAdd) { 1495 offset += len; 1496 len = 0; 1497 BaseDocument doc = (BaseDocument)c.getDocument(); 1498 TokenSequence<JavaTokenId> sequence = Utilities.getJavaTokenSequence(c, offset); 1499 if (sequence != null) { 1500 sequence.movePrevious(); 1501 if (sequence.token().id() == JavaTokenId.THIS || sequence.token().id() == JavaTokenId.SUPER) { 1502 isAbstract = false; 1503 if (toAdd == null) 1504 toAdd = ";"; } 1506 sequence.moveNext(); 1507 } 1508 String add = isAbstract ? "() {}" : "()"; if (toAdd != null && !add.startsWith(toAdd)) 1510 add += toAdd; 1511 String text = ""; if (sequence == null) { 1513 text += add; 1514 add = null; 1515 } 1516 boolean added = false; 1517 while(add != null && add.length() > 0) { 1518 String tokenText = sequence.token().text().toString(); 1519 if (tokenText.startsWith(add)) { 1520 len = sequence.offset() - offset + add.length(); 1521 text += add; 1522 add = null; 1523 } else if (add.startsWith(tokenText)) { 1524 sequence.moveNext(); 1525 len = sequence.offset() - offset; 1526 text += add.substring(0, tokenText.length()); 1527 add = add.substring(tokenText.length()); 1528 added = true; 1529 } else if (sequence.token().id() == JavaTokenId.WHITESPACE && sequence.token().text().toString().indexOf('\n') < 0) { if (!sequence.moveNext()) { 1531 text += add; 1532 add = null; 1533 } 1534 } else { 1535 if (!added) 1536 text += add; 1537 add = null; 1538 } 1539 } 1540 doc.atomicLock(); 1541 try { 1542 Position position = doc.createPosition(offset); 1543 doc.remove(offset, len); 1544 doc.insertString(position.getOffset(), text, null); 1545 } catch (BadLocationException e) { 1546 } finally { 1547 doc.atomicUnlock(); 1548 } 1549 Position position = null; 1550 if (isAbstract && text.length() > 3) { 1551 try { 1552 JavaSource js = JavaSource.forDocument(doc); 1553 final int off = offset + 4; 1554 js.runModificationTask(new CancellableTask<WorkingCopy>() { 1555 public void cancel() { 1556 } 1557 public void run(WorkingCopy copy) throws IOException { 1558 copy.toPhase(JavaSource.Phase.RESOLVED); 1559 TreePath path = copy.getTreeUtilities().pathFor(off); 1560 while (path.getLeaf() != path.getCompilationUnit()) { 1561 Tree tree = path.getLeaf(); 1562 Tree parentTree = path.getParentPath().getLeaf(); 1563 if (parentTree.getKind() == Tree.Kind.NEW_CLASS && tree.getKind() == Tree.Kind.CLASS) { 1564 GeneratorUtils.generateAllAbstractMethodImplementations(copy, path); 1565 break; 1566 } 1567 path = path.getParentPath(); 1568 } 1569 } 1570 }).commit(); 1571 } catch (Exception ex) { 1572 } 1573 } 1574 if (!params.isEmpty() && text.length() > 1) { 1575 CodeTemplateManager ctm = CodeTemplateManager.get(doc); 1576 if (ctm != null) { 1577 StringBuilder sb = new StringBuilder (); 1578 for (Iterator<ParamDesc> it = params.iterator(); it.hasNext();) { 1579 ParamDesc paramDesc = it.next(); 1580 sb.append("${"); sb.append(paramDesc.name); 1582 sb.append(" named instanceof="); sb.append(paramDesc.fullTypeName); 1584 sb.append("}"); if (it.hasNext()) 1586 sb.append(", "); } 1588 if (position != null) 1589 offset = position.getOffset(); 1590 c.setCaretPosition(offset + 1); 1591 ctm.createTemporary(sb.toString()).insert(c); 1592 Completion.get().showToolTip(); 1593 } 1594 } 1595 } 1596 1597 public String toString() { 1598 StringBuilder sb = new StringBuilder (); 1599 for (Modifier mod : modifiers) { 1600 sb.append(mod.toString()); 1601 sb.append(' '); 1602 } 1603 sb.append(simpleName); 1604 sb.append('('); for (Iterator<ParamDesc> it = params.iterator(); it.hasNext();) { 1606 ParamDesc paramDesc = it.next(); 1607 sb.append(paramDesc.typeName); 1608 sb.append(' '); 1609 sb.append(paramDesc.name); 1610 if (it.hasNext()) { 1611 sb.append(", "); } 1613 } 1614 sb.append(')'); 1615 return sb.toString(); 1616 } 1617 } 1618 1619 private static class DefaultConstructorItem extends JavaCompletionItem { 1620 1621 private static final String CONSTRUCTOR = "org/netbeans/modules/java/editor/resources/new_constructor_16.png"; private static final String CONSTRUCTOR_COLOR = "<font color=#b28b00>"; private static ImageIcon icon; 1624 1625 private String simpleName; 1626 private boolean isAbstract; 1627 private String sortText; 1628 private String leftText; 1629 1630 private DefaultConstructorItem(TypeElement elem, int substitutionOffset) { 1631 super(substitutionOffset); 1632 this.simpleName = elem.getSimpleName().toString(); 1633 this.isAbstract = elem.getModifiers().contains(Modifier.ABSTRACT); 1634 } 1635 1636 public CharSequence getInsertPrefix() { 1637 return simpleName; 1638 } 1639 1640 public int getSortPriority() { 1641 return 650; 1642 } 1643 1644 public CharSequence getSortText() { 1645 if (sortText == null) 1646 sortText = simpleName + "#0#"; return sortText; 1648 } 1649 1650 protected String getLeftHtmlText() { 1651 if (leftText == null) 1652 leftText = CONSTRUCTOR_COLOR + simpleName + "()" + COLOR_END; return leftText; 1654 } 1655 1656 protected ImageIcon getIcon() { 1657 if (icon == null) icon = new ImageIcon (org.openide.util.Utilities.loadImage(CONSTRUCTOR)); 1658 return icon; 1659 } 1660 1661 protected void substituteText(JTextComponent c, int offset, int len, String toAdd) { 1662 offset += len; 1663 len = 0; 1664 TokenSequence<JavaTokenId> sequence = Utilities.getJavaTokenSequence(c, offset); 1665 if (sequence != null) { 1666 sequence.movePrevious(); 1667 if (sequence.token().id() == JavaTokenId.THIS || sequence.token().id() == JavaTokenId.SUPER) { 1668 isAbstract = false; 1669 if (toAdd == null) 1670 toAdd = ";"; } 1672 sequence.moveNext(); 1673 } 1674 String add = isAbstract ? "() {}" : "()"; if (toAdd != null && !add.startsWith(toAdd)) 1676 add += toAdd; 1677 BaseDocument doc = (BaseDocument)c.getDocument(); 1678 String text = ""; if (sequence == null) { 1680 text += add; 1681 add = null; 1682 } 1683 boolean added = false; 1684 while(add != null && add.length() > 0) { 1685 String tokenText = sequence.token().text().toString(); 1686 if (tokenText.startsWith(add)) { 1687 len = sequence.offset() - offset + add.length(); 1688 text += add; 1689 add = null; 1690 } else if (add.startsWith(tokenText)) { 1691 sequence.moveNext(); 1692 len = sequence.offset() - offset; 1693 text += add.substring(0, tokenText.length()); 1694 add = add.substring(tokenText.length()); 1695 added = true; 1696 } else if (sequence.token().id() == JavaTokenId.WHITESPACE && sequence.token().text().toString().indexOf('\n') < 0) { if (!sequence.moveNext()) { 1698 text += add; 1699 add = null; 1700 } 1701 } else { 1702 if (!added) 1703 text += add; 1704 add = null; 1705 } 1706 } 1707 doc.atomicLock(); 1708 try { 1709 Position position = doc.createPosition(offset); 1710 doc.remove(offset, len); 1711 doc.insertString(position.getOffset(), text, null); 1712 } catch (BadLocationException e) { 1713 } finally { 1714 doc.atomicUnlock(); 1715 } 1716 if (isAbstract && text.length() > 3) { 1717 try { 1718 JavaSource js = JavaSource.forDocument(c.getDocument()); 1719 final int off = c.getSelectionEnd() - text.length() + 4; 1720 js.runModificationTask(new CancellableTask<WorkingCopy>() { 1721 public void cancel() { 1722 } 1723 public void run(WorkingCopy copy) throws IOException { 1724 copy.toPhase(JavaSource.Phase.RESOLVED); 1725 TreePath path = copy.getTreeUtilities().pathFor(off); 1726 while (path.getLeaf() != path.getCompilationUnit()) { 1727 Tree tree = path.getLeaf(); 1728 Tree parentTree = path.getParentPath().getLeaf(); 1729 if (parentTree.getKind() == Tree.Kind.NEW_CLASS && tree.getKind() == Tree.Kind.CLASS) { 1730 GeneratorUtils.generateAllAbstractMethodImplementations(copy, path); 1731 break; 1732 } 1733 path = path.getParentPath(); 1734 } 1735 } 1736 }).commit(); 1737 } catch (IOException ex) { 1738 } 1739 } 1740 } 1741 1742 public String toString() { 1743 return simpleName + "()"; 1744 } 1745 } 1746 1747 private static class AnnotationItem extends AnnotationTypeItem { 1748 1749 private AnnotationItem(TypeElement elem, DeclaredType type, int substitutionOffset, boolean isDeprecated, boolean smartType) { 1750 super(elem, type, 0, substitutionOffset, true, isDeprecated, smartType); 1751 } 1752 1753 public CharSequence getInsertPrefix() { 1754 return "@" + super.getInsertPrefix(); } 1756 1757 protected void substituteText(final JTextComponent c, final int offset, int len, String toAdd) { 1758 final BaseDocument doc = (BaseDocument)c.getDocument(); 1759 final StringBuilder text = new StringBuilder (); 1760 if (toAdd != null && !toAdd.equals("\n")) { TokenSequence<JavaTokenId> sequence = Utilities.getJavaTokenSequence(c, offset + len); 1762 if (sequence == null) { 1763 text.append(toAdd); 1764 toAdd = null; 1765 } 1766 boolean added = false; 1767 while(toAdd != null && toAdd.length() > 0) { 1768 String tokenText = sequence.token().text().toString(); 1769 if (tokenText.startsWith(toAdd)) { 1770 len = sequence.offset() - offset + toAdd.length(); 1771 text.append(toAdd); 1772 toAdd = null; 1773 } else if (toAdd.startsWith(tokenText)) { 1774 sequence.moveNext(); 1775 len = sequence.offset() - offset; 1776 text.append(toAdd.substring(0, tokenText.length())); 1777 toAdd = toAdd.substring(tokenText.length()); 1778 added = true; 1779 } else if (sequence.token().id() == JavaTokenId.WHITESPACE && sequence.token().text().toString().indexOf('\n') < 0) { if (!sequence.moveNext()) { 1781 text.append(toAdd); 1782 toAdd = null; 1783 } 1784 } else { 1785 if (!added) 1786 text.append(toAdd); 1787 toAdd = null; 1788 } 1789 } 1790 } 1791 final int finalLen = len; 1792 JavaSource js = JavaSource.forDocument(doc); 1793 try { 1794 js.runUserActionTask(new CancellableTask<CompilationController>() { 1795 public void cancel() { 1796 } 1797 public void run(CompilationController controller) throws IOException { 1798 controller.toPhase(JavaSource.Phase.RESOLVED); 1799 TypeElement elem = elementHandle.resolve(controller); 1800 doc.atomicLock(); 1802 try { 1803 TreePath tp = controller.getTreeUtilities().pathFor(offset); 1804 text.insert(0, "@" + AutoImport.resolveImport(controller, tp, controller.getTypes().getDeclaredType(elem))); String textToReplace = doc.getText(offset, finalLen); 1806 if (textToReplace.contentEquals(text)) return; 1807 doc.remove(offset, finalLen); 1808 doc.insertString(offset, text.toString(), null); 1809 } catch (BadLocationException e) { 1810 } finally { 1812 doc.atomicUnlock(); 1813 } 1814 } 1815 }, true); 1816 } catch (IOException ioe) { 1817 } 1818 } 1819 } 1820 1821 private static class AttributeItem extends JavaCompletionItem { 1822 1823 private static final String ATTRIBUTE = "org/netbeans/modules/java/editor/resources/attribute_16.png"; private static final String ATTRIBUTE_COLOR = "<font color=#404040>"; private static ImageIcon icon; 1826 1827 private ElementHandle<ExecutableElement> elementHandle; 1828 private boolean isDeprecated; 1829 private String simpleName; 1830 private String typeName; 1831 private String defaultValue; 1832 private String leftText; 1833 private String rightText; 1834 1835 private AttributeItem(ExecutableElement elem, ExecutableType type, int substitutionOffset, boolean isDeprecated) { 1836 super(substitutionOffset); 1837 this.elementHandle = ElementHandle.create(elem); 1838 this.isDeprecated = isDeprecated; 1839 this.simpleName = elem.getSimpleName().toString(); 1840 this.typeName = Utilities.getTypeName(type.getReturnType(), false).toString(); 1841 AnnotationValue value = elem.getDefaultValue(); 1842 this.defaultValue = value != null ? value.toString() : null; 1843 } 1844 1845 public int getSortPriority() { 1846 return 100; 1847 } 1848 1849 public CharSequence getSortText() { 1850 return simpleName; 1851 } 1852 1853 public CharSequence getInsertPrefix() { 1854 return simpleName + "="; } 1856 1857 public CompletionTask createDocumentationTask() { 1858 return JavaCompletionProvider.createDocTask(elementHandle); 1859 } 1860 1861 protected ImageIcon getIcon(){ 1862 if (icon == null) icon = new ImageIcon (org.openide.util.Utilities.loadImage(ATTRIBUTE)); 1863 return icon; 1864 } 1865 1866 protected String getLeftHtmlText() { 1867 if (leftText == null) { 1868 StringBuilder sb = new StringBuilder (); 1869 sb.append(ATTRIBUTE_COLOR); 1870 if (defaultValue == null) 1871 sb.append(BOLD); 1872 if (isDeprecated) 1873 sb.append(STRIKE); 1874 sb.append(simpleName); 1875 if (isDeprecated) 1876 sb.append(STRIKE_END); 1877 if (defaultValue == null) { 1878 sb.append(BOLD_END); 1879 } else { 1880 sb.append(" = "); sb.append(defaultValue); 1882 } 1883 sb.append(COLOR_END); 1884 leftText = sb.toString(); 1885 } 1886 return leftText; 1887 } 1888 1889 protected String getRightHtmlText() { 1890 if (rightText == null) 1891 rightText = escape(typeName); 1892 return rightText; 1893 } 1894 1895 public String toString() { 1896 return simpleName; 1897 } 1898 } 1899 1900 private static class StaticMemberItem extends JavaCompletionItem { 1901 1902 private static final String FIELD_ST_PUBLIC = "org/netbeans/modules/editor/resources/completion/field_static_16.png"; private static final String FIELD_ST_PROTECTED = "org/netbeans/modules/editor/resources/completion/field_static_protected_16.png"; private static final String FIELD_ST_PACKAGE = "org/netbeans/modules/editor/resources/completion/field_static_package_private_16.png"; private static final String FIELD_COLOR = "<font color=#0000b2>"; private static final String METHOD_ST_PUBLIC = "org/netbeans/modules/editor/resources/completion/method_static_16.png"; private static final String METHOD_ST_PROTECTED = "org/netbeans/modules/editor/resources/completion/method_static_protected_16.png"; private static final String METHOD_ST_PACKAGE = "org/netbeans/modules/editor/resources/completion/method_static_package_private_16.png"; private static final String METHOD_COLOR = "<font color=#7c0000>"; private static final String PARAMETER_NAME_COLOR = "<font color=#b200b2>"; private static ImageIcon icon[][] = new ImageIcon [2][3]; 1912 1913 private TypeMirrorHandle<DeclaredType> typeHandle; 1914 private ElementHandle<Element> memberElementHandle; 1915 private boolean isDeprecated; 1916 private String typeName; 1917 private String memberName; 1918 private String memberTypeName; 1919 private Set<Modifier> modifiers; 1920 private List<ParamDesc> params; 1921 private String sortText; 1922 private String leftText; 1923 private String rightText; 1924 1925 private StaticMemberItem(DeclaredType type, Element memberElem, TypeMirror memberType, int substitutionOffset, boolean isDeprecated) { 1926 super(substitutionOffset); 1927 this.typeHandle = TypeMirrorHandle.create(type); 1928 this.memberElementHandle = ElementHandle.create(memberElem); 1929 this.isDeprecated = isDeprecated; 1930 this.typeName = Utilities.getTypeName(type, false).toString(); 1931 this.memberName = memberElem.getSimpleName().toString(); 1932 this.memberTypeName = Utilities.getTypeName(memberElem.getKind().isField() ? memberType : ((ExecutableType)memberType).getReturnType(), false).toString(); 1933 this.modifiers = memberElem.getModifiers(); 1934 if (!memberElem.getKind().isField()) { 1935 this.params = new ArrayList<ParamDesc>(); 1936 Iterator<? extends VariableElement> it = ((ExecutableElement)memberElem).getParameters().iterator(); 1937 Iterator<? extends TypeMirror> tIt = ((ExecutableType)memberType).getParameterTypes().iterator(); 1938 while(it.hasNext() && tIt.hasNext()) { 1939 TypeMirror tm = tIt.next(); 1940 this.params.add(new ParamDesc(tm.toString(), Utilities.getTypeName(tm, false, ((ExecutableElement)memberElem).isVarArgs() && !tIt.hasNext()).toString(), it.next().getSimpleName().toString())); 1941 } 1942 } 1943 } 1944 1945 public int getSortPriority() { 1946 return (params == null ? 700 : 750) - SMART_TYPE; 1947 } 1948 1949 public CharSequence getSortText() { 1950 if (sortText == null) { 1951 if (params == null) { 1952 sortText = memberName + "#" + typeName; } else { 1954 StringBuilder sortParams = new StringBuilder (); 1955 sortParams.append('('); 1956 int cnt = 0; 1957 for (Iterator<ParamDesc> it = params.iterator(); it.hasNext();) { 1958 ParamDesc paramDesc = it.next(); 1959 sortParams.append(paramDesc.typeName); 1960 if (it.hasNext()) { 1961 sortParams.append(','); 1962 } 1963 cnt++; 1964 } 1965 sortParams.append(')'); 1966 sortText = memberName + "#" + ((cnt < 10 ? "0" : "") + cnt) + "#" + sortParams.toString() + "#" + typeName; } 1968 } 1969 return sortText; 1970 } 1971 1972 public CharSequence getInsertPrefix() { 1973 return typeName + "." + memberName; } 1975 1976 public CompletionTask createDocumentationTask() { 1977 return JavaCompletionProvider.createDocTask(memberElementHandle); 1978 } 1979 1980 protected String getLeftHtmlText() { 1981 if (leftText == null) { 1982 StringBuilder lText = new StringBuilder (); 1983 lText.append(memberElementHandle.getKind().isField() ? FIELD_COLOR : METHOD_COLOR); 1984 lText.append(escape(typeName)); 1985 lText.append('.'); 1986 if (isDeprecated) 1987 lText.append(STRIKE); 1988 lText.append(memberName); 1989 if (isDeprecated) 1990 lText.append(STRIKE_END); 1991 lText.append(COLOR_END); 1992 if (params != null) { 1993 lText.append('('); 1994 for (Iterator<ParamDesc> it = params.iterator(); it.hasNext();) { 1995 ParamDesc paramDesc = it.next(); 1996 lText.append(escape(paramDesc.typeName)); 1997 lText.append(' '); lText.append(PARAMETER_NAME_COLOR); 1999 lText.append(paramDesc.name); 2000 lText.append(COLOR_END); 2001 if (it.hasNext()) { 2002 lText.append(", "); } 2004 } 2005 lText.append(')'); 2006 } 2007 leftText = lText.toString(); 2008 } 2009 return leftText; 2010 } 2011 2012 protected String getRightHtmlText() { 2013 if (rightText == null) 2014 rightText = escape(memberTypeName); 2015 return rightText; 2016 } 2017 2018 protected ImageIcon getIcon(){ 2019 int level = getProtectionLevel(modifiers); 2020 boolean isField = memberElementHandle.getKind().isField(); 2021 ImageIcon cachedIcon = icon[isField ? 0 : 1][level - 1]; 2022 if (cachedIcon != null) 2023 return cachedIcon; 2024 2025 String iconPath = null; 2026 if (isField) { 2027 switch (level) { 2028 case PACKAGE_LEVEL: 2029 iconPath = FIELD_ST_PACKAGE; 2030 break; 2031 2032 case PROTECTED_LEVEL: 2033 iconPath = FIELD_ST_PROTECTED; 2034 break; 2035 2036 case PUBLIC_LEVEL: 2037 iconPath = FIELD_ST_PUBLIC; 2038 break; 2039 } 2040 }else{ 2041 switch (level) { 2042 case PACKAGE_LEVEL: 2043 iconPath = METHOD_ST_PACKAGE; 2044 break; 2045 2046 case PROTECTED_LEVEL: 2047 iconPath = METHOD_ST_PROTECTED; 2048 break; 2049 2050 case PUBLIC_LEVEL: 2051 iconPath = METHOD_ST_PUBLIC; 2052 break; 2053 } 2054 } 2055 if (iconPath == null) 2056 return null; 2057 ImageIcon newIcon = new ImageIcon (org.openide.util.Utilities.loadImage(iconPath)); 2058 icon[isField ? 0 : 1][level - 1] = newIcon; 2059 return newIcon; 2060 } 2061 2062 protected void substituteText(final JTextComponent c, final int offset, int len, String toAdd) { 2063 final BaseDocument doc = (BaseDocument)c.getDocument(); 2064 final StringBuilder text = new StringBuilder (); 2065 if (toAdd != null && !toAdd.equals("\n")) { TokenSequence<JavaTokenId> sequence = Utilities.getJavaTokenSequence(c, offset + len); 2067 if (sequence == null) { 2068 text.append(toAdd); 2069 toAdd = null; 2070 } 2071 boolean added = false; 2072 while(toAdd != null && toAdd.length() > 0) { 2073 String tokenText = sequence.token().text().toString(); 2074 if (tokenText.startsWith(toAdd)) { 2075 len = sequence.offset() - offset + toAdd.length(); 2076 text.append(toAdd); 2077 toAdd = null; 2078 } else if (toAdd.startsWith(tokenText)) { 2079 sequence.moveNext(); 2080 len = sequence.offset() - offset; 2081 text.append(toAdd.substring(0, tokenText.length())); 2082 toAdd = toAdd.substring(tokenText.length()); 2083 added = true; 2084 } else if (sequence.token().id() == JavaTokenId.WHITESPACE && sequence.token().text().toString().indexOf('\n') < 0) { if (!sequence.moveNext()) { 2086 text.append(toAdd); 2087 toAdd = null; 2088 } 2089 } else { 2090 if (!added) 2091 text.append(toAdd); 2092 toAdd = null; 2093 } 2094 } 2095 } 2096 final int finalLen = len; 2097 JavaSource js = JavaSource.forDocument(doc); 2098 try { 2099 js.runUserActionTask(new CancellableTask<CompilationController>() { 2100 public void cancel() { 2101 } 2102 public void run(CompilationController controller) throws IOException { 2103 controller.toPhase(JavaSource.Phase.RESOLVED); 2104 DeclaredType type = typeHandle.resolve(controller); 2105 StringBuilder sb = new StringBuilder (); 2106 int cnt = 1; 2107 sb.append("${PAR#"); sb.append(cnt++); 2109 sb.append(" type=\""); sb.append(((TypeElement)type.asElement()).getQualifiedName()); 2111 sb.append("\" editable=false}"); Iterator<? extends TypeMirror> tas = type.getTypeArguments().iterator(); 2113 if (tas.hasNext()) { 2114 sb.append('<'); while (tas.hasNext()) { 2116 TypeMirror ta = tas.next(); 2117 sb.append("${PAR#"); sb.append(cnt++); 2119 if (ta.getKind() == TypeKind.TYPEVAR) { 2120 sb.append(" type=\""); ta = ((TypeVariable)ta).getUpperBound(); 2122 sb.append(Utilities.getTypeName(ta, true)); 2123 sb.append("\"}"); } else if (ta.getKind() == TypeKind.WILDCARD) { 2125 sb.append(" type=\""); TypeMirror bound = ((WildcardType)ta).getExtendsBound(); 2127 if (bound == null) 2128 bound = ((WildcardType)ta).getSuperBound(); 2129 sb.append(bound != null ? Utilities.getTypeName(bound, true) : "java.lang.Object"); sb.append("\"}"); } else if (ta.getKind() == TypeKind.ERROR) { 2132 sb.append(" default=\"\"}"); } else { 2134 sb.append(" type=\""); sb.append(Utilities.getTypeName(ta, true)); 2136 sb.append("\" editable=false}"); } 2138 if (tas.hasNext()) 2139 sb.append(", "); } 2141 sb.append('>'); } 2143 sb.append('.'); sb.append(memberName); 2145 if (params != null) { 2146 sb.append("("); for (Iterator<ParamDesc> it = params.iterator(); it.hasNext();) { 2148 ParamDesc paramDesc = it.next(); 2149 sb.append("${"); sb.append(paramDesc.name); 2151 sb.append(" named instanceof="); sb.append(paramDesc.fullTypeName); 2153 sb.append("}"); if (it.hasNext()) 2155 sb.append(", "); } 2157 sb.append(")"); } 2159 sb.append(text); 2160 if (finalLen > 0) { 2161 doc.atomicLock(); 2162 try { 2163 doc.remove(offset, finalLen); 2164 } catch (BadLocationException e) { 2165 } finally { 2167 doc.atomicUnlock(); 2168 } 2169 } 2170 CodeTemplateManager ctm = CodeTemplateManager.get(doc); 2171 if (ctm != null) { 2172 ctm.createTemporary(sb.toString()).insert(c); 2173 } 2174 } 2175 }, true); 2176 } catch (IOException ioe) { 2177 } 2178 } 2179 2180 public String toString() { 2181 StringBuilder sb = new StringBuilder (); 2182 for(Modifier mod : modifiers) { 2183 sb.append(mod.toString()); 2184 sb.append(' '); } 2186 sb.append(memberTypeName); 2187 sb.append(' '); 2188 sb.append(typeName); 2189 sb.append('.'); 2190 sb.append(memberName); 2191 if (params != null) { 2192 sb.append('('); for (Iterator<ParamDesc> it = params.iterator(); it.hasNext();) { 2194 ParamDesc paramDesc = it.next(); 2195 sb.append(paramDesc.typeName); 2196 sb.append(' '); 2197 sb.append(paramDesc.name); 2198 if (it.hasNext()) { 2199 sb.append(", "); } 2201 } 2202 sb.append(')'); 2203 } 2204 return sb.toString(); 2205 } 2206 } 2207 2208 private static class InitializeAllConstructorItem extends JavaCompletionItem { 2209 2210 private static final String CONSTRUCTOR_PUBLIC = "org/netbeans/modules/java/editor/resources/new_constructor_16.png"; private static final String CONSTRUCTOR_COLOR = "<font color=#b28b00>"; private static final String PARAMETER_NAME_COLOR = "<font color=#b200b2>"; private static ImageIcon icon; 2214 2215 private List<ElementHandle<VariableElement>> fieldHandles; 2216 private String simpleName; 2217 private List<ParamDesc> params; 2218 private String sortText; 2219 private String leftText; 2220 2221 private InitializeAllConstructorItem(Iterable <? extends VariableElement> fields, TypeElement parent, int substitutionOffset) { 2222 super(substitutionOffset); 2223 this.fieldHandles = new ArrayList<ElementHandle<VariableElement>>(); 2224 this.params = new ArrayList<ParamDesc>(); 2225 for (VariableElement ve : fields) { 2226 this.fieldHandles.add(ElementHandle.create(ve)); 2227 this.params.add(new ParamDesc(null, Utilities.getTypeName(ve.asType(), false).toString(), ve.getSimpleName().toString())); 2228 } 2229 this.simpleName = parent.getSimpleName().toString(); 2230 } 2231 2232 public int getSortPriority() { 2233 return 400; 2234 } 2235 2236 public CharSequence getSortText() { 2237 if (sortText == null) { 2238 StringBuilder sortParams = new StringBuilder (); 2239 sortParams.append('('); int cnt = 0; 2241 for (Iterator<ParamDesc> it = params.iterator(); it.hasNext();) { 2242 ParamDesc paramDesc = it.next(); 2243 sortParams.append(paramDesc.typeName); 2244 if (it.hasNext()) { 2245 sortParams.append(','); } 2247 cnt++; 2248 } 2249 sortParams.append(')'); sortText = simpleName + "#" + ((cnt < 10 ? "0" : "") + cnt) + "#" + sortParams.toString(); } 2252 return sortText; 2253 } 2254 2255 protected String getLeftHtmlText() { 2256 if (leftText == null) { 2257 StringBuilder lText = new StringBuilder (); 2258 lText.append(CONSTRUCTOR_COLOR); 2259 lText.append(simpleName); 2260 lText.append(COLOR_END); 2261 lText.append('('); for (Iterator<ParamDesc> it = params.iterator(); it.hasNext();) { 2263 ParamDesc paramDesc = it.next(); 2264 lText.append(escape(paramDesc.typeName)); 2265 lText.append(' '); lText.append(PARAMETER_NAME_COLOR); 2267 lText.append(paramDesc.name); 2268 lText.append(COLOR_END); 2269 if (it.hasNext()) { 2270 lText.append(", "); } 2272 } 2273 lText.append(')'); lText.append(" - generate"); leftText = lText.toString(); 2276 } 2277 return leftText; 2278 } 2279 2280 protected ImageIcon getIcon() { 2281 if (icon == null) 2282 icon = new ImageIcon (org.openide.util.Utilities.loadImage(CONSTRUCTOR_PUBLIC)); 2283 return icon; 2284 } 2285 2286 public CharSequence getInsertPrefix() { 2287 return simpleName; 2288 } 2289 2290 protected void substituteText(final JTextComponent c, final int offset, final int len, String toAdd) { 2291 BaseDocument doc = (BaseDocument)c.getDocument(); 2292 if (len > 0) { 2293 doc.atomicLock(); 2294 try { 2295 doc.remove(offset, len); 2296 } catch (BadLocationException e) { 2297 } finally { 2299 doc.atomicUnlock(); 2300 } 2301 } 2302 try { 2303 JavaSource js = JavaSource.forDocument(c.getDocument()); 2304 js.runModificationTask(new CancellableTask<WorkingCopy>() { 2305 public void cancel() { 2306 } 2307 public void run(WorkingCopy copy) throws IOException { 2308 copy.toPhase(JavaSource.Phase.PARSED); 2309 TreePath tp = copy.getTreeUtilities().pathFor(offset); 2310 if (tp.getLeaf().getKind() == Tree.Kind.CLASS) { 2311 ArrayList<VariableElement> fieldElements = new ArrayList<VariableElement>(); 2312 for (ElementHandle<? extends Element> handle : fieldHandles) 2313 fieldElements.add((VariableElement)handle.resolve(copy)); 2314 int idx = 0; 2315 for (Tree tree : ((ClassTree)tp.getLeaf()).getMembers()) { 2316 if (copy.getTrees().getSourcePositions().getStartPosition(tp.getCompilationUnit(), tree) < offset) 2317 idx++; 2318 else 2319 break; 2320 } 2321 GeneratorUtils.generateConstructor(copy, tp, fieldElements, null, idx); 2322 } 2323 } 2324 }).commit(); 2325 } catch (IOException ex) { 2326 } 2327 } 2328 2329 public String toString() { 2330 StringBuilder sb = new StringBuilder (); 2331 sb.append("public "); sb.append(simpleName); 2333 sb.append('('); for (Iterator<ParamDesc> it = params.iterator(); it.hasNext();) { 2335 ParamDesc paramDesc = it.next(); 2336 sb.append(paramDesc.typeName); 2337 sb.append(' '); sb.append(paramDesc.name); 2339 if (it.hasNext()) { 2340 sb.append(", "); } 2342 } 2343 sb.append(')'); sb.append(" - generate"); return sb.toString(); 2346 } 2347 2348 public boolean instantSubstitution(JTextComponent component) { 2349 return false; } 2351 } 2352 2353 private static final int PUBLIC_LEVEL = 3; 2354 private static final int PROTECTED_LEVEL = 2; 2355 private static final int PACKAGE_LEVEL = 1; 2356 private static final int PRIVATE_LEVEL = 0; 2357 2358 private static int getProtectionLevel(Set<Modifier> modifiers) { 2359 if(modifiers.contains(Modifier.PUBLIC)) 2360 return PUBLIC_LEVEL; 2361 if(modifiers.contains(Modifier.PROTECTED)) 2362 return PROTECTED_LEVEL; 2363 if(modifiers.contains(Modifier.PRIVATE)) 2364 return PRIVATE_LEVEL; 2365 return PACKAGE_LEVEL; 2366 } 2367 2368 private static String escape(String s) { 2369 if (s != null) { 2370 try { 2371 return XMLUtil.toAttributeValue(s); 2372 } catch (Exception ex) {} 2373 } 2374 return s; 2375 } 2376 2377 private static class ParamDesc { 2378 private String fullTypeName; 2379 private String typeName; 2380 private String name; 2381 2382 public ParamDesc(String fullTypeName, String typeName, String name) { 2383 this.fullTypeName = fullTypeName; 2384 this.typeName = typeName; 2385 this.name = name; 2386 } 2387 } 2388} 2389 | Popular Tags |