1 11 package org.eclipse.jdt.ui.text.java; 12 13 14 import java.util.ArrayList ; 15 import java.util.HashSet ; 16 import java.util.List ; 17 import java.util.Set ; 18 19 import org.eclipse.core.runtime.Assert; 20 import org.eclipse.core.runtime.CoreException; 21 import org.eclipse.core.runtime.IStatus; 22 import org.eclipse.core.runtime.Platform; 23 import org.eclipse.core.runtime.Status; 24 25 import org.eclipse.swt.graphics.Image; 26 27 import org.eclipse.jface.resource.ImageDescriptor; 28 29 import org.eclipse.jface.text.contentassist.IContextInformation; 30 31 import org.eclipse.jdt.core.CompletionContext; 32 import org.eclipse.jdt.core.CompletionProposal; 33 import org.eclipse.jdt.core.CompletionRequestor; 34 import org.eclipse.jdt.core.ICompilationUnit; 35 import org.eclipse.jdt.core.IJavaElement; 36 import org.eclipse.jdt.core.IJavaProject; 37 import org.eclipse.jdt.core.IType; 38 import org.eclipse.jdt.core.Signature; 39 import org.eclipse.jdt.core.compiler.IProblem; 40 41 import org.eclipse.jdt.internal.corext.util.TypeFilter; 42 43 44 import org.eclipse.jdt.internal.ui.JavaPlugin; 45 import org.eclipse.jdt.internal.ui.text.java.AnonymousTypeCompletionProposal; 46 import org.eclipse.jdt.internal.ui.text.java.AnonymousTypeProposalInfo; 47 import org.eclipse.jdt.internal.ui.text.java.FieldProposalInfo; 48 import org.eclipse.jdt.internal.ui.text.java.GetterSetterCompletionProposal; 49 import org.eclipse.jdt.internal.ui.text.java.JavaCompletionProposal; 50 import org.eclipse.jdt.internal.ui.text.java.JavaMethodCompletionProposal; 51 import org.eclipse.jdt.internal.ui.text.java.LazyJavaCompletionProposal; 52 import org.eclipse.jdt.internal.ui.text.java.LazyJavaTypeCompletionProposal; 53 import org.eclipse.jdt.internal.ui.text.java.MethodDeclarationCompletionProposal; 54 import org.eclipse.jdt.internal.ui.text.java.MethodProposalInfo; 55 import org.eclipse.jdt.internal.ui.text.java.OverrideCompletionProposal; 56 import org.eclipse.jdt.internal.ui.text.java.ProposalContextInformation; 57 import org.eclipse.jdt.internal.ui.text.javadoc.JavadocInlineTagCompletionProposal; 58 import org.eclipse.jdt.internal.ui.text.javadoc.JavadocLinkTypeCompletionProposal; 59 import org.eclipse.jdt.internal.ui.viewsupport.ImageDescriptorRegistry; 60 61 88 public class CompletionProposalCollector extends CompletionRequestor { 89 90 91 private static final boolean DEBUG= "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jdt.ui/debug/ResultCollector")); 93 94 protected final static char[] METHOD_TRIGGERS= new char[] { ';', ',', '.', '\t', '[', ' ' }; 95 96 protected final static char[] METHOD_WITH_ARGUMENTS_TRIGGERS= new char[] { '(', '-', ' ' }; 97 98 protected final static char[] TYPE_TRIGGERS= new char[] { '.', '\t', '[', '(', ' ' }; 99 100 protected final static char[] VAR_TRIGGER= new char[] { '\t', ' ', '=', ';', '.' }; 101 102 private final CompletionProposalLabelProvider fLabelProvider= new CompletionProposalLabelProvider(); 103 private final ImageDescriptorRegistry fRegistry= JavaPlugin.getImageDescriptorRegistry(); 104 105 private final List fJavaProposals= new ArrayList (); 106 private final List fKeywords= new ArrayList (); 107 private final Set fSuggestedMethodNames= new HashSet (); 108 109 private final ICompilationUnit fCompilationUnit; 110 private final IJavaProject fJavaProject; 111 private int fUserReplacementLength; 112 113 private CompletionContext fContext; 114 private IProblem fLastProblem; 115 116 117 private long fStartTime; 118 private long fUITime; 119 120 125 private JavaContentAssistInvocationContext fInvocationContext; 126 127 136 public CompletionProposalCollector(ICompilationUnit cu) { 137 this(cu.getJavaProject(), cu); 138 } 139 140 156 public CompletionProposalCollector(IJavaProject project) { 157 this(project, null); 158 } 159 160 private CompletionProposalCollector(IJavaProject project, ICompilationUnit cu) { 161 fJavaProject= project; 162 fCompilationUnit= cu; 163 164 fUserReplacementLength= -1; 165 } 166 167 177 public void setInvocationContext(JavaContentAssistInvocationContext context) { 178 Assert.isNotNull(context); 179 fInvocationContext= context; 180 context.setCollector(this); 181 } 182 183 190 protected final JavaContentAssistInvocationContext getInvocationContext() { 191 if (fInvocationContext == null) 192 setInvocationContext(new JavaContentAssistInvocationContext(getCompilationUnit())); 193 return fInvocationContext; 194 } 195 196 205 public void accept(CompletionProposal proposal) { 206 long start= DEBUG ? System.currentTimeMillis() : 0; 207 try { 208 if (isFiltered(proposal)) 209 return; 210 211 if (proposal.getKind() == CompletionProposal.POTENTIAL_METHOD_DECLARATION) { 212 acceptPotentialMethodDeclaration(proposal); 213 } else { 214 IJavaCompletionProposal javaProposal= createJavaCompletionProposal(proposal); 215 if (javaProposal != null) { 216 fJavaProposals.add(javaProposal); 217 if (proposal.getKind() == CompletionProposal.KEYWORD) 218 fKeywords.add(javaProposal); 219 } 220 } 221 } catch (IllegalArgumentException e) { 222 JavaPlugin.log(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.OK, "Exception when processing proposal for: " + String.valueOf(proposal.getCompletion()), e)); } 227 228 if (DEBUG) fUITime += System.currentTimeMillis() - start; 229 } 230 231 238 public void acceptContext(CompletionContext context) { 239 fContext= context; 240 fLabelProvider.setContext(context); 241 } 242 243 248 public void beginReporting() { 249 if (DEBUG) { 250 fStartTime= System.currentTimeMillis(); 251 fUITime= 0; 252 } 253 254 fLastProblem= null; 255 fJavaProposals.clear(); 256 fKeywords.clear(); 257 fSuggestedMethodNames.clear(); 258 } 259 260 265 public void completionFailure(IProblem problem) { 266 fLastProblem= problem; 267 } 268 269 274 public void endReporting() { 275 if (DEBUG) { 276 long total= System.currentTimeMillis() - fStartTime; 277 System.err.println("Core Collector (core):\t" + (total - fUITime)); System.err.println("Core Collector (ui):\t" + fUITime); } 280 } 281 282 290 public String getErrorMessage() { 291 if (fLastProblem != null) 292 return fLastProblem.getMessage(); 293 return ""; } 295 296 301 public final IJavaCompletionProposal[] getJavaCompletionProposals() { 302 return (IJavaCompletionProposal[]) fJavaProposals.toArray(new IJavaCompletionProposal[fJavaProposals.size()]); 303 } 304 305 310 public final IJavaCompletionProposal[] getKeywordCompletionProposals() { 311 return (JavaCompletionProposal[]) fKeywords.toArray(new JavaCompletionProposal[fKeywords.size()]); 312 } 313 314 322 public final void setReplacementLength(int length) { 323 Assert.isLegal(length >= 0); 324 fUserReplacementLength= length; 325 } 326 327 335 protected int computeRelevance(CompletionProposal proposal) { 336 final int baseRelevance= proposal.getRelevance() * 16; 337 switch (proposal.getKind()) { 338 case CompletionProposal.PACKAGE_REF: 339 return baseRelevance + 0; 340 case CompletionProposal.LABEL_REF: 341 return baseRelevance + 1; 342 case CompletionProposal.KEYWORD: 343 return baseRelevance + 2; 344 case CompletionProposal.TYPE_REF: 345 case CompletionProposal.ANONYMOUS_CLASS_DECLARATION: 346 return baseRelevance + 3; 347 case CompletionProposal.METHOD_REF: 348 case CompletionProposal.METHOD_NAME_REFERENCE: 349 case CompletionProposal.METHOD_DECLARATION: 350 case CompletionProposal.ANNOTATION_ATTRIBUTE_REF: 351 return baseRelevance + 4; 352 case CompletionProposal.POTENTIAL_METHOD_DECLARATION: 353 return baseRelevance + 4 ; 354 case CompletionProposal.FIELD_REF: 355 return baseRelevance + 5; 356 case CompletionProposal.LOCAL_VARIABLE_REF: 357 case CompletionProposal.VARIABLE_DECLARATION: 358 return baseRelevance + 6; 359 default: 360 return baseRelevance; 361 } 362 } 363 364 386 protected IJavaCompletionProposal createJavaCompletionProposal(CompletionProposal proposal) { 387 switch (proposal.getKind()) { 388 case CompletionProposal.KEYWORD: 389 return createKeywordProposal(proposal); 390 case CompletionProposal.PACKAGE_REF: 391 return createPackageProposal(proposal); 392 case CompletionProposal.TYPE_REF: 393 return createTypeProposal(proposal); 394 case CompletionProposal.JAVADOC_TYPE_REF: 395 return createJavadocLinkTypeProposal(proposal); 396 case CompletionProposal.FIELD_REF: 397 case CompletionProposal.JAVADOC_FIELD_REF: 398 case CompletionProposal.JAVADOC_VALUE_REF: 399 return createFieldProposal(proposal); 400 case CompletionProposal.METHOD_REF: 401 case CompletionProposal.METHOD_NAME_REFERENCE: 402 case CompletionProposal.JAVADOC_METHOD_REF: 403 return createMethodReferenceProposal(proposal); 404 case CompletionProposal.METHOD_DECLARATION: 405 return createMethodDeclarationProposal(proposal); 406 case CompletionProposal.ANONYMOUS_CLASS_DECLARATION: 407 return createAnonymousTypeProposal(proposal); 408 case CompletionProposal.LABEL_REF: 409 return createLabelProposal(proposal); 410 case CompletionProposal.LOCAL_VARIABLE_REF: 411 case CompletionProposal.VARIABLE_DECLARATION: 412 return createLocalVariableProposal(proposal); 413 case CompletionProposal.ANNOTATION_ATTRIBUTE_REF: 414 return createAnnotationAttributeReferenceProposal(proposal); 415 case CompletionProposal.JAVADOC_BLOCK_TAG: 416 case CompletionProposal.JAVADOC_PARAM_REF: 417 return createJavadocSimpleProposal(proposal); 418 case CompletionProposal.JAVADOC_INLINE_TAG: 419 return createJavadocInlineTagProposal(proposal); 420 case CompletionProposal.POTENTIAL_METHOD_DECLARATION: 421 default: 422 return null; 423 } 424 } 425 426 433 protected final IContextInformation createMethodContextInformation(CompletionProposal methodProposal) { 434 Assert.isTrue(methodProposal.getKind() == CompletionProposal.METHOD_REF); 435 return new ProposalContextInformation(methodProposal); 436 } 437 438 446 protected final ICompilationUnit getCompilationUnit() { 447 return fCompilationUnit; 448 } 449 450 456 protected final CompletionContext getContext() { 457 return fContext; 458 } 459 460 467 protected final Image getImage(ImageDescriptor descriptor) { 468 return (descriptor == null) ? null : fRegistry.get(descriptor); 469 } 470 471 476 protected final CompletionProposalLabelProvider getLabelProvider() { 477 return fLabelProvider; 478 } 479 480 490 protected final int getLength(CompletionProposal proposal) { 491 int start= proposal.getReplaceStart(); 492 int end= proposal.getReplaceEnd(); 493 int length; 494 if (fUserReplacementLength == -1) { 495 length= end - start; 496 } else { 497 length= fUserReplacementLength; 498 int behindCompletion= proposal.getCompletionLocation() + 1; 500 if (start < behindCompletion) { 501 length+= behindCompletion - start; 502 } 503 } 504 return length; 505 } 506 507 521 protected boolean isFiltered(CompletionProposal proposal) { 522 if (isIgnored(proposal.getKind())) 523 return true; 524 char[] declaringType= getDeclaringType(proposal); 525 return declaringType!= null && TypeFilter.isFiltered(declaringType); 526 } 527 528 549 protected final char[] getDeclaringType(CompletionProposal proposal) { 550 switch (proposal.getKind()) { 551 case CompletionProposal.METHOD_DECLARATION: 552 case CompletionProposal.METHOD_NAME_REFERENCE: 553 case CompletionProposal.JAVADOC_METHOD_REF: 554 case CompletionProposal.METHOD_REF: 555 case CompletionProposal.ANNOTATION_ATTRIBUTE_REF: 556 case CompletionProposal.POTENTIAL_METHOD_DECLARATION: 557 case CompletionProposal.ANONYMOUS_CLASS_DECLARATION: 558 case CompletionProposal.FIELD_REF: 559 case CompletionProposal.JAVADOC_FIELD_REF: 560 case CompletionProposal.JAVADOC_VALUE_REF: 561 char[] declaration= proposal.getDeclarationSignature(); 562 if (declaration == null) 565 return "java.lang.Object".toCharArray(); return Signature.toCharArray(declaration); 567 case CompletionProposal.PACKAGE_REF: 568 return proposal.getDeclarationSignature(); 569 case CompletionProposal.JAVADOC_TYPE_REF: 570 case CompletionProposal.TYPE_REF: 571 return Signature.toCharArray(proposal.getSignature()); 572 case CompletionProposal.LOCAL_VARIABLE_REF: 573 case CompletionProposal.VARIABLE_DECLARATION: 574 case CompletionProposal.KEYWORD: 575 case CompletionProposal.LABEL_REF: 576 case CompletionProposal.JAVADOC_BLOCK_TAG: 577 case CompletionProposal.JAVADOC_INLINE_TAG: 578 case CompletionProposal.JAVADOC_PARAM_REF: 579 return null; 580 default: 581 Assert.isTrue(false); 582 return null; 583 } 584 } 585 586 private void acceptPotentialMethodDeclaration(CompletionProposal proposal) { 587 if (fCompilationUnit == null) 588 return; 589 590 String prefix= String.valueOf(proposal.getName()); 591 int completionStart= proposal.getReplaceStart(); 592 int completionEnd= proposal.getReplaceEnd(); 593 int relevance= computeRelevance(proposal); 594 595 try { 596 IJavaElement element= fCompilationUnit.getElementAt(proposal.getCompletionLocation() + 1); 597 if (element != null) { 598 IType type= (IType) element.getAncestor(IJavaElement.TYPE); 599 if (type != null) { 600 GetterSetterCompletionProposal.evaluateProposals(type, prefix, completionStart, completionEnd - completionStart, relevance + 1, fSuggestedMethodNames, fJavaProposals); 601 MethodDeclarationCompletionProposal.evaluateProposals(type, prefix, completionStart, completionEnd - completionStart, relevance, fSuggestedMethodNames, fJavaProposals); 602 } 603 } 604 } catch (CoreException e) { 605 JavaPlugin.log(e); 606 } 607 } 608 609 private IJavaCompletionProposal createAnnotationAttributeReferenceProposal(CompletionProposal proposal) { 610 String displayString= fLabelProvider.createLabelWithTypeAndDeclaration(proposal); 611 ImageDescriptor descriptor= fLabelProvider.createMethodImageDescriptor(proposal); 612 String completion= String.valueOf(proposal.getCompletion()); 613 return new JavaCompletionProposal(completion, proposal.getReplaceStart(), getLength(proposal), getImage(descriptor), displayString, computeRelevance(proposal)); 614 } 615 616 private IJavaCompletionProposal createAnonymousTypeProposal(CompletionProposal proposal) { 617 if (fCompilationUnit == null || fJavaProject == null) 618 return null; 619 620 String completion= String.valueOf(proposal.getCompletion()); 621 int start= proposal.getReplaceStart(); 622 int length= getLength(proposal); 623 int relevance= computeRelevance(proposal); 624 625 String label= fLabelProvider.createAnonymousTypeLabel(proposal); 626 627 JavaCompletionProposal javaProposal= new AnonymousTypeCompletionProposal(fJavaProject, fCompilationUnit, start, length, completion, label, String.valueOf(proposal.getDeclarationSignature()), relevance); 628 javaProposal.setProposalInfo(new AnonymousTypeProposalInfo(fJavaProject, proposal)); 629 return javaProposal; 630 } 631 632 private IJavaCompletionProposal createFieldProposal(CompletionProposal proposal) { 633 String completion= String.valueOf(proposal.getCompletion()); 634 int start= proposal.getReplaceStart(); 635 int length= getLength(proposal); 636 String label= fLabelProvider.createLabel(proposal); 637 Image image= getImage(fLabelProvider.createFieldImageDescriptor(proposal)); 638 int relevance= computeRelevance(proposal); 639 640 JavaCompletionProposal javaProposal= new JavaCompletionProposal(completion, start, length, image, label, relevance, getContext().isInJavadoc(), getInvocationContext()); 641 if (fJavaProject != null) 642 javaProposal.setProposalInfo(new FieldProposalInfo(fJavaProject, proposal)); 643 644 javaProposal.setTriggerCharacters(VAR_TRIGGER); 645 646 return javaProposal; 647 } 648 649 private IJavaCompletionProposal createJavadocSimpleProposal(CompletionProposal javadocProposal) { 650 LazyJavaCompletionProposal proposal = new LazyJavaCompletionProposal(javadocProposal, getInvocationContext()); 666 return proposal; 668 } 669 670 private IJavaCompletionProposal createJavadocInlineTagProposal(CompletionProposal javadocProposal) { 671 LazyJavaCompletionProposal proposal= new JavadocInlineTagCompletionProposal(javadocProposal, getInvocationContext()); 672 adaptLength(proposal, javadocProposal); 673 return proposal; 674 } 675 676 private IJavaCompletionProposal createKeywordProposal(CompletionProposal proposal) { 677 String completion= String.valueOf(proposal.getCompletion()); 678 int start= proposal.getReplaceStart(); 679 int length= getLength(proposal); 680 String label= fLabelProvider.createSimpleLabel(proposal); 681 int relevance= computeRelevance(proposal); 682 return new JavaCompletionProposal(completion, start, length, null, label, relevance); 683 } 684 685 private IJavaCompletionProposal createLabelProposal(CompletionProposal proposal) { 686 String completion= String.valueOf(proposal.getCompletion()); 687 int start= proposal.getReplaceStart(); 688 int length= getLength(proposal); 689 String label= fLabelProvider.createSimpleLabel(proposal); 690 int relevance= computeRelevance(proposal); 691 692 return new JavaCompletionProposal(completion, start, length, null, label, relevance); 693 } 694 695 private IJavaCompletionProposal createLocalVariableProposal(CompletionProposal proposal) { 696 String completion= String.valueOf(proposal.getCompletion()); 697 int start= proposal.getReplaceStart(); 698 int length= getLength(proposal); 699 Image image= getImage(fLabelProvider.createLocalImageDescriptor(proposal)); 700 String label= fLabelProvider.createSimpleLabelWithType(proposal); 701 int relevance= computeRelevance(proposal); 702 703 final JavaCompletionProposal javaProposal= new JavaCompletionProposal(completion, start, length, image, label, relevance); 704 javaProposal.setTriggerCharacters(VAR_TRIGGER); 705 return javaProposal; 706 } 707 708 private IJavaCompletionProposal createMethodDeclarationProposal(CompletionProposal proposal) { 709 if (fCompilationUnit == null || fJavaProject == null) 710 return null; 711 712 String name= String.valueOf(proposal.getName()); 713 String [] paramTypes= Signature.getParameterTypes(String.valueOf(proposal.getSignature())); 714 for (int index= 0; index < paramTypes.length; index++) 715 paramTypes[index]= Signature.toString(paramTypes[index]); 716 int start= proposal.getReplaceStart(); 717 int length= getLength(proposal); 718 719 String label= fLabelProvider.createOverrideMethodProposalLabel(proposal); 720 721 JavaCompletionProposal javaProposal= new OverrideCompletionProposal(fJavaProject, fCompilationUnit, name, paramTypes, start, length, label, String.valueOf(proposal.getCompletion())); 722 javaProposal.setImage(getImage(fLabelProvider.createMethodImageDescriptor(proposal))); 723 javaProposal.setProposalInfo(new MethodProposalInfo(fJavaProject, proposal)); 724 javaProposal.setRelevance(computeRelevance(proposal)); 725 726 fSuggestedMethodNames.add(new String (name)); 727 return javaProposal; 728 } 729 730 private IJavaCompletionProposal createMethodReferenceProposal(CompletionProposal methodProposal) { 731 LazyJavaCompletionProposal proposal= new JavaMethodCompletionProposal(methodProposal, getInvocationContext()); 732 adaptLength(proposal, methodProposal); 733 return proposal; 734 } 735 736 private void adaptLength(LazyJavaCompletionProposal proposal, CompletionProposal coreProposal) { 737 if (fUserReplacementLength != -1) { 738 proposal.setReplacementLength(getLength(coreProposal)); 739 } 740 } 741 742 private IJavaCompletionProposal createPackageProposal(CompletionProposal proposal) { 743 String completion= String.valueOf(proposal.getCompletion()); 744 int start= proposal.getReplaceStart(); 745 int length= getLength(proposal); 746 String label= fLabelProvider.createSimpleLabel(proposal); 747 Image image= getImage(fLabelProvider.createPackageImageDescriptor(proposal)); 748 int relevance= computeRelevance(proposal); 749 750 return new JavaCompletionProposal(completion, start, length, image, label, relevance); 751 } 752 753 private IJavaCompletionProposal createTypeProposal(CompletionProposal typeProposal) { 754 LazyJavaCompletionProposal proposal= new LazyJavaTypeCompletionProposal(typeProposal, getInvocationContext()); 755 adaptLength(proposal, typeProposal); 756 return proposal; 757 } 758 759 private IJavaCompletionProposal createJavadocLinkTypeProposal(CompletionProposal typeProposal) { 760 LazyJavaCompletionProposal proposal= new JavadocLinkTypeCompletionProposal(typeProposal, getInvocationContext()); 761 adaptLength(proposal, typeProposal); 762 return proposal; 763 } 764 } 765 | Popular Tags |