001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.ui.text.java;
011:
012: import java.util.ArrayList;
013: import java.util.HashSet;
014: import java.util.List;
015: import java.util.Set;
016:
017: import org.eclipse.core.runtime.Assert;
018: import org.eclipse.core.runtime.CoreException;
019: import org.eclipse.core.runtime.IStatus;
020: import org.eclipse.core.runtime.Platform;
021: import org.eclipse.core.runtime.Status;
022:
023: import org.eclipse.swt.graphics.Image;
024:
025: import org.eclipse.jface.resource.ImageDescriptor;
026:
027: import org.eclipse.jface.text.contentassist.IContextInformation;
028:
029: import org.eclipse.jdt.core.CompletionContext;
030: import org.eclipse.jdt.core.CompletionProposal;
031: import org.eclipse.jdt.core.CompletionRequestor;
032: import org.eclipse.jdt.core.ICompilationUnit;
033: import org.eclipse.jdt.core.IJavaElement;
034: import org.eclipse.jdt.core.IJavaProject;
035: import org.eclipse.jdt.core.IType;
036: import org.eclipse.jdt.core.Signature;
037: import org.eclipse.jdt.core.compiler.IProblem;
038:
039: import org.eclipse.jdt.internal.corext.util.TypeFilter;
040:
041: import org.eclipse.jdt.internal.ui.JavaPlugin;
042: import org.eclipse.jdt.internal.ui.text.java.AnonymousTypeCompletionProposal;
043: import org.eclipse.jdt.internal.ui.text.java.AnonymousTypeProposalInfo;
044: import org.eclipse.jdt.internal.ui.text.java.FieldProposalInfo;
045: import org.eclipse.jdt.internal.ui.text.java.GetterSetterCompletionProposal;
046: import org.eclipse.jdt.internal.ui.text.java.JavaCompletionProposal;
047: import org.eclipse.jdt.internal.ui.text.java.JavaMethodCompletionProposal;
048: import org.eclipse.jdt.internal.ui.text.java.LazyJavaCompletionProposal;
049: import org.eclipse.jdt.internal.ui.text.java.LazyJavaTypeCompletionProposal;
050: import org.eclipse.jdt.internal.ui.text.java.MethodDeclarationCompletionProposal;
051: import org.eclipse.jdt.internal.ui.text.java.MethodProposalInfo;
052: import org.eclipse.jdt.internal.ui.text.java.OverrideCompletionProposal;
053: import org.eclipse.jdt.internal.ui.text.java.ProposalContextInformation;
054: import org.eclipse.jdt.internal.ui.text.javadoc.JavadocInlineTagCompletionProposal;
055: import org.eclipse.jdt.internal.ui.text.javadoc.JavadocLinkTypeCompletionProposal;
056: import org.eclipse.jdt.internal.ui.viewsupport.ImageDescriptorRegistry;
057:
058: /**
059: * Java UI implementation of <code>CompletionRequestor</code>. Produces
060: * {@link IJavaCompletionProposal}s from the proposal descriptors received via
061: * the <code>CompletionRequestor</code> interface.
062: * <p>
063: * The lifecycle of a <code>CompletionProposalCollector</code> instance is very
064: * simple:
065: * <pre>
066: * ICompilationUnit unit= ...
067: * int offset= ...
068: *
069: * CompletionProposalCollector collector= new CompletionProposalCollector(unit);
070: * unit.codeComplete(offset, collector);
071: * IJavaCompletionProposal[] proposals= collector.getJavaCompletionProposals();
072: * String errorMessage= collector.getErrorMessage();
073: *
074: * // display / process proposals
075: * </pre>
076: * Note that after a code completion operation, the collector will store any
077: * received proposals, which may require a considerable amount of memory, so the
078: * collector should not be kept as a reference after a completion operation.
079: * </p>
080: * <p>
081: * Clients may instantiate or subclass.
082: * </p>
083: * @since 3.1
084: */
085: public class CompletionProposalCollector extends CompletionRequestor {
086:
087: /** Tells whether this class is in debug mode. */
088: private static final boolean DEBUG = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jdt.ui/debug/ResultCollector")); //$NON-NLS-1$//$NON-NLS-2$
089:
090: /** Triggers for method proposals without parameters. Do not modify. */
091: protected final static char[] METHOD_TRIGGERS = new char[] { ';',
092: ',', '.', '\t', '[', ' ' };
093: /** Triggers for method proposals. Do not modify. */
094: protected final static char[] METHOD_WITH_ARGUMENTS_TRIGGERS = new char[] {
095: '(', '-', ' ' };
096: /** Triggers for types. Do not modify. */
097: protected final static char[] TYPE_TRIGGERS = new char[] { '.',
098: '\t', '[', '(', ' ' };
099: /** Triggers for variables. Do not modify. */
100: protected final static char[] VAR_TRIGGER = new char[] { '\t', ' ',
101: '=', ';', '.' };
102:
103: private final CompletionProposalLabelProvider fLabelProvider = new CompletionProposalLabelProvider();
104: private final ImageDescriptorRegistry fRegistry = JavaPlugin
105: .getImageDescriptorRegistry();
106:
107: private final List fJavaProposals = new ArrayList();
108: private final List fKeywords = new ArrayList();
109: private final Set fSuggestedMethodNames = new HashSet();
110:
111: private final ICompilationUnit fCompilationUnit;
112: private final IJavaProject fJavaProject;
113: private int fUserReplacementLength;
114:
115: private CompletionContext fContext;
116: private IProblem fLastProblem;
117:
118: /* performance instrumentation */
119: private long fStartTime;
120: private long fUITime;
121:
122: /**
123: * The UI invocation context or <code>null</code>.
124: *
125: * @since 3.2
126: */
127: private JavaContentAssistInvocationContext fInvocationContext;
128:
129: /**
130: * Creates a new instance ready to collect proposals. If the passed
131: * <code>ICompilationUnit</code> is not contained in an
132: * {@link IJavaProject}, no javadoc will be available as
133: * {@link org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo() additional info}
134: * on the created proposals.
135: *
136: * @param cu the compilation unit that the result collector will operate on
137: */
138: public CompletionProposalCollector(ICompilationUnit cu) {
139: this (cu.getJavaProject(), cu);
140: }
141:
142: /**
143: * Creates a new instance ready to collect proposals. Note that proposals
144: * for anonymous types and method declarations are not created when using
145: * this constructor, as those need to know the compilation unit that they
146: * are created on. Use
147: * {@link CompletionProposalCollector#CompletionProposalCollector(ICompilationUnit)}
148: * instead to get all proposals.
149: * <p>
150: * If the passed Java project is <code>null</code>, no javadoc will be
151: * available as
152: * {@link org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo() additional info}
153: * on the created (e.g. method and type) proposals.
154: * </p>
155: * @param project the project that the result collector will operate on, or
156: * <code>null</code>
157: */
158: public CompletionProposalCollector(IJavaProject project) {
159: this (project, null);
160: }
161:
162: private CompletionProposalCollector(IJavaProject project,
163: ICompilationUnit cu) {
164: fJavaProject = project;
165: fCompilationUnit = cu;
166:
167: fUserReplacementLength = -1;
168: }
169:
170: /**
171: * Sets the invocation context.
172: * <p>
173: * Subclasses may extend.
174: * </p>
175: *
176: * @param context the invocation context
177: * @see #getInvocationContext()
178: * @since 3.2
179: */
180: public void setInvocationContext(
181: JavaContentAssistInvocationContext context) {
182: Assert.isNotNull(context);
183: fInvocationContext = context;
184: context.setCollector(this );
185: }
186:
187: /**
188: * Returns the invocation context. If none has been set via
189: * {@link #setInvocationContext(JavaContentAssistInvocationContext)}, a new one is created.
190: *
191: * @return invocationContext the invocation context
192: * @since 3.2
193: */
194: protected final JavaContentAssistInvocationContext getInvocationContext() {
195: if (fInvocationContext == null)
196: setInvocationContext(new JavaContentAssistInvocationContext(
197: getCompilationUnit()));
198: return fInvocationContext;
199: }
200:
201: /**
202: * {@inheritDoc}
203: * <p>
204: * Subclasses may replace, but usually should not need to. Consider
205: * replacing
206: * {@linkplain #createJavaCompletionProposal(CompletionProposal) createJavaCompletionProposal}
207: * instead.
208: * </p>
209: */
210: public void accept(CompletionProposal proposal) {
211: long start = DEBUG ? System.currentTimeMillis() : 0;
212: try {
213: if (isFiltered(proposal))
214: return;
215:
216: if (proposal.getKind() == CompletionProposal.POTENTIAL_METHOD_DECLARATION) {
217: acceptPotentialMethodDeclaration(proposal);
218: } else {
219: IJavaCompletionProposal javaProposal = createJavaCompletionProposal(proposal);
220: if (javaProposal != null) {
221: fJavaProposals.add(javaProposal);
222: if (proposal.getKind() == CompletionProposal.KEYWORD)
223: fKeywords.add(javaProposal);
224: }
225: }
226: } catch (IllegalArgumentException e) {
227: // all signature processing method may throw IAEs
228: // https://bugs.eclipse.org/bugs/show_bug.cgi?id=84657
229: // don't abort, but log and show all the valid proposals
230: JavaPlugin
231: .log(new Status(
232: IStatus.ERROR,
233: JavaPlugin.getPluginId(),
234: IStatus.OK,
235: "Exception when processing proposal for: " + String.valueOf(proposal.getCompletion()), e)); //$NON-NLS-1$
236: }
237:
238: if (DEBUG)
239: fUITime += System.currentTimeMillis() - start;
240: }
241:
242: /**
243: * {@inheritDoc}
244: * <p>
245: * Subclasses may extend, but usually should not need to.
246: * </p>
247: * @see #getContext()
248: */
249: public void acceptContext(CompletionContext context) {
250: fContext = context;
251: fLabelProvider.setContext(context);
252: }
253:
254: /**
255: * {@inheritDoc}
256: *
257: * Subclasses may extend, but must call the super implementation.
258: */
259: public void beginReporting() {
260: if (DEBUG) {
261: fStartTime = System.currentTimeMillis();
262: fUITime = 0;
263: }
264:
265: fLastProblem = null;
266: fJavaProposals.clear();
267: fKeywords.clear();
268: fSuggestedMethodNames.clear();
269: }
270:
271: /**
272: * {@inheritDoc}
273: *
274: * Subclasses may extend, but must call the super implementation.
275: */
276: public void completionFailure(IProblem problem) {
277: fLastProblem = problem;
278: }
279:
280: /**
281: * {@inheritDoc}
282: *
283: * Subclasses may extend, but must call the super implementation.
284: */
285: public void endReporting() {
286: if (DEBUG) {
287: long total = System.currentTimeMillis() - fStartTime;
288: System.err
289: .println("Core Collector (core):\t" + (total - fUITime)); //$NON-NLS-1$
290: System.err.println("Core Collector (ui):\t" + fUITime); //$NON-NLS-1$
291: }
292: }
293:
294: /**
295: * Returns an error message about any error that may have occurred during
296: * code completion, or the empty string if none.
297: * <p>
298: * Subclasses may replace or extend.
299: * </p>
300: * @return an error message or the empty string
301: */
302: public String getErrorMessage() {
303: if (fLastProblem != null)
304: return fLastProblem.getMessage();
305: return ""; //$NON-NLS-1$
306: }
307:
308: /**
309: * Returns the unsorted list of received proposals.
310: *
311: * @return the unsorted list of received proposals
312: */
313: public final IJavaCompletionProposal[] getJavaCompletionProposals() {
314: return (IJavaCompletionProposal[]) fJavaProposals
315: .toArray(new IJavaCompletionProposal[fJavaProposals
316: .size()]);
317: }
318:
319: /**
320: * Returns the unsorted list of received keyword proposals.
321: *
322: * @return the unsorted list of received keyword proposals
323: */
324: public final IJavaCompletionProposal[] getKeywordCompletionProposals() {
325: return (JavaCompletionProposal[]) fKeywords
326: .toArray(new JavaCompletionProposal[fKeywords.size()]);
327: }
328:
329: /**
330: * If the replacement length is set, it overrides the length returned from
331: * the content assist infrastructure. Use this setting if code assist is
332: * called with a none empty selection.
333: *
334: * @param length the new replacement length, relative to the code assist
335: * offset. Must be equal to or greater than zero.
336: */
337: public final void setReplacementLength(int length) {
338: Assert.isLegal(length >= 0);
339: fUserReplacementLength = length;
340: }
341:
342: /**
343: * Computes the relevance for a given <code>CompletionProposal</code>.
344: * <p>
345: * Subclasses may replace, but usually should not need to.
346: * </p>
347: * @param proposal the proposal to compute the relevance for
348: * @return the relevance for <code>proposal</code>
349: */
350: protected int computeRelevance(CompletionProposal proposal) {
351: final int baseRelevance = proposal.getRelevance() * 16;
352: switch (proposal.getKind()) {
353: case CompletionProposal.PACKAGE_REF:
354: return baseRelevance + 0;
355: case CompletionProposal.LABEL_REF:
356: return baseRelevance + 1;
357: case CompletionProposal.KEYWORD:
358: return baseRelevance + 2;
359: case CompletionProposal.TYPE_REF:
360: case CompletionProposal.ANONYMOUS_CLASS_DECLARATION:
361: return baseRelevance + 3;
362: case CompletionProposal.METHOD_REF:
363: case CompletionProposal.METHOD_NAME_REFERENCE:
364: case CompletionProposal.METHOD_DECLARATION:
365: case CompletionProposal.ANNOTATION_ATTRIBUTE_REF:
366: return baseRelevance + 4;
367: case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
368: return baseRelevance + 4 /* + 99 */;
369: case CompletionProposal.FIELD_REF:
370: return baseRelevance + 5;
371: case CompletionProposal.LOCAL_VARIABLE_REF:
372: case CompletionProposal.VARIABLE_DECLARATION:
373: return baseRelevance + 6;
374: default:
375: return baseRelevance;
376: }
377: }
378:
379: /**
380: * Creates a new java completion proposal from a core proposal. This may
381: * involve computing the display label and setting up some context.
382: * <p>
383: * This method is called for every proposal that will be displayed to the
384: * user, which may be hundreds. Implementations should therefore defer as
385: * much work as possible: Labels should be computed lazily to leverage
386: * virtual table usage, and any information only needed when
387: * <em>applying</em> a proposal should not be computed yet.
388: * </p>
389: * <p>
390: * Implementations may return <code>null</code> if a proposal should not
391: * be included in the list presented to the user.
392: * </p>
393: * <p>
394: * Subclasses may extend or replace this method.
395: * </p>
396: *
397: * @param proposal the core completion proposal to create a UI proposal for
398: * @return the created java completion proposal, or <code>null</code> if
399: * no proposal should be displayed
400: */
401: protected IJavaCompletionProposal createJavaCompletionProposal(
402: CompletionProposal proposal) {
403: switch (proposal.getKind()) {
404: case CompletionProposal.KEYWORD:
405: return createKeywordProposal(proposal);
406: case CompletionProposal.PACKAGE_REF:
407: return createPackageProposal(proposal);
408: case CompletionProposal.TYPE_REF:
409: return createTypeProposal(proposal);
410: case CompletionProposal.JAVADOC_TYPE_REF:
411: return createJavadocLinkTypeProposal(proposal);
412: case CompletionProposal.FIELD_REF:
413: case CompletionProposal.JAVADOC_FIELD_REF:
414: case CompletionProposal.JAVADOC_VALUE_REF:
415: return createFieldProposal(proposal);
416: case CompletionProposal.METHOD_REF:
417: case CompletionProposal.METHOD_NAME_REFERENCE:
418: case CompletionProposal.JAVADOC_METHOD_REF:
419: return createMethodReferenceProposal(proposal);
420: case CompletionProposal.METHOD_DECLARATION:
421: return createMethodDeclarationProposal(proposal);
422: case CompletionProposal.ANONYMOUS_CLASS_DECLARATION:
423: return createAnonymousTypeProposal(proposal);
424: case CompletionProposal.LABEL_REF:
425: return createLabelProposal(proposal);
426: case CompletionProposal.LOCAL_VARIABLE_REF:
427: case CompletionProposal.VARIABLE_DECLARATION:
428: return createLocalVariableProposal(proposal);
429: case CompletionProposal.ANNOTATION_ATTRIBUTE_REF:
430: return createAnnotationAttributeReferenceProposal(proposal);
431: case CompletionProposal.JAVADOC_BLOCK_TAG:
432: case CompletionProposal.JAVADOC_PARAM_REF:
433: return createJavadocSimpleProposal(proposal);
434: case CompletionProposal.JAVADOC_INLINE_TAG:
435: return createJavadocInlineTagProposal(proposal);
436: case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
437: default:
438: return null;
439: }
440: }
441:
442: /**
443: * Creates the context information for a given method reference proposal.
444: * The passed proposal must be of kind {@link CompletionProposal#METHOD_REF}.
445: *
446: * @param methodProposal the method proposal for which to create context information
447: * @return the context information for <code>methodProposal</code>
448: */
449: protected final IContextInformation createMethodContextInformation(
450: CompletionProposal methodProposal) {
451: Assert
452: .isTrue(methodProposal.getKind() == CompletionProposal.METHOD_REF);
453: return new ProposalContextInformation(methodProposal);
454: }
455:
456: /**
457: * Returns the compilation unit that the receiver operates on, or
458: * <code>null</code> if the <code>IJavaProject</code> constructor was
459: * used to create the receiver.
460: *
461: * @return the compilation unit that the receiver operates on, or
462: * <code>null</code>
463: */
464: protected final ICompilationUnit getCompilationUnit() {
465: return fCompilationUnit;
466: }
467:
468: /**
469: * Returns the <code>CompletionContext</code> for this completion operation.
470:
471: * @return the <code>CompletionContext</code> for this completion operation
472: * @see CompletionRequestor#acceptContext(CompletionContext)
473: */
474: protected final CompletionContext getContext() {
475: return fContext;
476: }
477:
478: /**
479: * Returns a cached image for the given descriptor.
480: *
481: * @param descriptor the image descriptor to get an image for, may be
482: * <code>null</code>
483: * @return the image corresponding to <code>descriptor</code>
484: */
485: protected final Image getImage(ImageDescriptor descriptor) {
486: return (descriptor == null) ? null : fRegistry.get(descriptor);
487: }
488:
489: /**
490: * Returns the proposal label provider used by the receiver.
491: *
492: * @return the proposal label provider used by the receiver
493: */
494: protected final CompletionProposalLabelProvider getLabelProvider() {
495: return fLabelProvider;
496: }
497:
498: /**
499: * Returns the replacement length of a given completion proposal. The
500: * replacement length is usually the difference between the return values of
501: * <code>proposal.getReplaceEnd</code> and
502: * <code>proposal.getReplaceStart</code>, but this behavior may be
503: * overridden by calling {@link #setReplacementLength(int)}.
504: *
505: * @param proposal the completion proposal to get the replacement length for
506: * @return the replacement length for <code>proposal</code>
507: */
508: protected final int getLength(CompletionProposal proposal) {
509: int start = proposal.getReplaceStart();
510: int end = proposal.getReplaceEnd();
511: int length;
512: if (fUserReplacementLength == -1) {
513: length = end - start;
514: } else {
515: length = fUserReplacementLength;
516: // extend length to begin at start
517: int behindCompletion = proposal.getCompletionLocation() + 1;
518: if (start < behindCompletion) {
519: length += behindCompletion - start;
520: }
521: }
522: return length;
523: }
524:
525: /**
526: * Returns <code>true</code> if <code>proposal</code> is filtered, e.g.
527: * should not be proposed to the user, <code>false</code> if it is valid.
528: * <p>
529: * Subclasses may extends this method. The default implementation filters
530: * proposals set to be ignored via
531: * {@linkplain CompletionRequestor#setIgnored(int, boolean) setIgnored} and
532: * types set to be ignored in the preferences.
533: * </p>
534: *
535: * @param proposal the proposal to filter
536: * @return <code>true</code> to filter <code>proposal</code>,
537: * <code>false</code> to let it pass
538: */
539: protected boolean isFiltered(CompletionProposal proposal) {
540: if (isIgnored(proposal.getKind()))
541: return true;
542: char[] declaringType = getDeclaringType(proposal);
543: return declaringType != null
544: && TypeFilter.isFiltered(declaringType);
545: }
546:
547: /**
548: * Returns the type signature of the declaring type of a
549: * <code>CompletionProposal</code>, or <code>null</code> for proposals
550: * that do not have a declaring type. The return value is <em>not</em>
551: * <code>null</code> for proposals of the following kinds:
552: * <ul>
553: * <li>METHOD_DECLARATION</li>
554: * <li>METHOD_NAME_REFERENCE</li>
555: * <li>METHOD_REF</li>
556: * <li>ANNOTATION_ATTRIBUTE_REF</li>
557: * <li>POTENTIAL_METHOD_DECLARATION</li>
558: * <li>ANONYMOUS_CLASS_DECLARATION</li>
559: * <li>FIELD_REF</li>
560: * <li>PACKAGE_REF (returns the package, but no type)</li>
561: * <li>TYPE_REF</li>
562: * </ul>
563: *
564: * @param proposal the completion proposal to get the declaring type for
565: * @return the type signature of the declaring type, or <code>null</code> if there is none
566: * @see Signature#toCharArray(char[])
567: */
568: protected final char[] getDeclaringType(CompletionProposal proposal) {
569: switch (proposal.getKind()) {
570: case CompletionProposal.METHOD_DECLARATION:
571: case CompletionProposal.METHOD_NAME_REFERENCE:
572: case CompletionProposal.JAVADOC_METHOD_REF:
573: case CompletionProposal.METHOD_REF:
574: case CompletionProposal.ANNOTATION_ATTRIBUTE_REF:
575: case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
576: case CompletionProposal.ANONYMOUS_CLASS_DECLARATION:
577: case CompletionProposal.FIELD_REF:
578: case CompletionProposal.JAVADOC_FIELD_REF:
579: case CompletionProposal.JAVADOC_VALUE_REF:
580: char[] declaration = proposal.getDeclarationSignature();
581: // special methods may not have a declaring type: methods defined on arrays etc.
582: // Currently known: class literals don't have a declaring type - use Object
583: if (declaration == null)
584: return "java.lang.Object".toCharArray(); //$NON-NLS-1$
585: return Signature.toCharArray(declaration);
586: case CompletionProposal.PACKAGE_REF:
587: return proposal.getDeclarationSignature();
588: case CompletionProposal.JAVADOC_TYPE_REF:
589: case CompletionProposal.TYPE_REF:
590: return Signature.toCharArray(proposal.getSignature());
591: case CompletionProposal.LOCAL_VARIABLE_REF:
592: case CompletionProposal.VARIABLE_DECLARATION:
593: case CompletionProposal.KEYWORD:
594: case CompletionProposal.LABEL_REF:
595: case CompletionProposal.JAVADOC_BLOCK_TAG:
596: case CompletionProposal.JAVADOC_INLINE_TAG:
597: case CompletionProposal.JAVADOC_PARAM_REF:
598: return null;
599: default:
600: Assert.isTrue(false);
601: return null;
602: }
603: }
604:
605: private void acceptPotentialMethodDeclaration(
606: CompletionProposal proposal) {
607: if (fCompilationUnit == null)
608: return;
609:
610: String prefix = String.valueOf(proposal.getName());
611: int completionStart = proposal.getReplaceStart();
612: int completionEnd = proposal.getReplaceEnd();
613: int relevance = computeRelevance(proposal);
614:
615: try {
616: IJavaElement element = fCompilationUnit
617: .getElementAt(proposal.getCompletionLocation() + 1);
618: if (element != null) {
619: IType type = (IType) element
620: .getAncestor(IJavaElement.TYPE);
621: if (type != null) {
622: GetterSetterCompletionProposal.evaluateProposals(
623: type, prefix, completionStart,
624: completionEnd - completionStart,
625: relevance + 1, fSuggestedMethodNames,
626: fJavaProposals);
627: MethodDeclarationCompletionProposal
628: .evaluateProposals(type, prefix,
629: completionStart, completionEnd
630: - completionStart,
631: relevance, fSuggestedMethodNames,
632: fJavaProposals);
633: }
634: }
635: } catch (CoreException e) {
636: JavaPlugin.log(e);
637: }
638: }
639:
640: private IJavaCompletionProposal createAnnotationAttributeReferenceProposal(
641: CompletionProposal proposal) {
642: String displayString = fLabelProvider
643: .createLabelWithTypeAndDeclaration(proposal);
644: ImageDescriptor descriptor = fLabelProvider
645: .createMethodImageDescriptor(proposal);
646: String completion = String.valueOf(proposal.getCompletion());
647: return new JavaCompletionProposal(completion, proposal
648: .getReplaceStart(), getLength(proposal),
649: getImage(descriptor), displayString,
650: computeRelevance(proposal));
651: }
652:
653: private IJavaCompletionProposal createAnonymousTypeProposal(
654: CompletionProposal proposal) {
655: if (fCompilationUnit == null || fJavaProject == null)
656: return null;
657:
658: String completion = String.valueOf(proposal.getCompletion());
659: int start = proposal.getReplaceStart();
660: int length = getLength(proposal);
661: int relevance = computeRelevance(proposal);
662:
663: String label = fLabelProvider
664: .createAnonymousTypeLabel(proposal);
665:
666: JavaCompletionProposal javaProposal = new AnonymousTypeCompletionProposal(
667: fJavaProject, fCompilationUnit, start, length,
668: completion, label, String.valueOf(proposal
669: .getDeclarationSignature()), relevance);
670: javaProposal.setProposalInfo(new AnonymousTypeProposalInfo(
671: fJavaProject, proposal));
672: return javaProposal;
673: }
674:
675: private IJavaCompletionProposal createFieldProposal(
676: CompletionProposal proposal) {
677: String completion = String.valueOf(proposal.getCompletion());
678: int start = proposal.getReplaceStart();
679: int length = getLength(proposal);
680: String label = fLabelProvider.createLabel(proposal);
681: Image image = getImage(fLabelProvider
682: .createFieldImageDescriptor(proposal));
683: int relevance = computeRelevance(proposal);
684:
685: JavaCompletionProposal javaProposal = new JavaCompletionProposal(
686: completion, start, length, image, label, relevance,
687: getContext().isInJavadoc(), getInvocationContext());
688: if (fJavaProject != null)
689: javaProposal.setProposalInfo(new FieldProposalInfo(
690: fJavaProject, proposal));
691:
692: javaProposal.setTriggerCharacters(VAR_TRIGGER);
693:
694: return javaProposal;
695: }
696:
697: private IJavaCompletionProposal createJavadocSimpleProposal(
698: CompletionProposal javadocProposal) {
699: // TODO do better with javadoc proposals
700: // String completion= String.valueOf(proposal.getCompletion());
701: // int start= proposal.getReplaceStart();
702: // int length= getLength(proposal);
703: // String label= fLabelProvider.createSimpleLabel(proposal);
704: // Image image= getImage(fLabelProvider.createImageDescriptor(proposal));
705: // int relevance= computeRelevance(proposal);
706: //
707: // JavaCompletionProposal javaProposal= new JavaCompletionProposal(completion, start, length, image, label, relevance);
708: // if (fJavaProject != null)
709: // javaProposal.setProposalInfo(new FieldProposalInfo(fJavaProject, proposal));
710: //
711: // javaProposal.setTriggerCharacters(VAR_TRIGGER);
712: //
713: // return javaProposal;
714: LazyJavaCompletionProposal proposal = new LazyJavaCompletionProposal(
715: javadocProposal, getInvocationContext());
716: // adaptLength(proposal, javadocProposal);
717: return proposal;
718: }
719:
720: private IJavaCompletionProposal createJavadocInlineTagProposal(
721: CompletionProposal javadocProposal) {
722: LazyJavaCompletionProposal proposal = new JavadocInlineTagCompletionProposal(
723: javadocProposal, getInvocationContext());
724: adaptLength(proposal, javadocProposal);
725: return proposal;
726: }
727:
728: private IJavaCompletionProposal createKeywordProposal(
729: CompletionProposal proposal) {
730: String completion = String.valueOf(proposal.getCompletion());
731: int start = proposal.getReplaceStart();
732: int length = getLength(proposal);
733: String label = fLabelProvider.createSimpleLabel(proposal);
734: int relevance = computeRelevance(proposal);
735: return new JavaCompletionProposal(completion, start, length,
736: null, label, relevance);
737: }
738:
739: private IJavaCompletionProposal createLabelProposal(
740: CompletionProposal proposal) {
741: String completion = String.valueOf(proposal.getCompletion());
742: int start = proposal.getReplaceStart();
743: int length = getLength(proposal);
744: String label = fLabelProvider.createSimpleLabel(proposal);
745: int relevance = computeRelevance(proposal);
746:
747: return new JavaCompletionProposal(completion, start, length,
748: null, label, relevance);
749: }
750:
751: private IJavaCompletionProposal createLocalVariableProposal(
752: CompletionProposal proposal) {
753: String completion = String.valueOf(proposal.getCompletion());
754: int start = proposal.getReplaceStart();
755: int length = getLength(proposal);
756: Image image = getImage(fLabelProvider
757: .createLocalImageDescriptor(proposal));
758: String label = fLabelProvider
759: .createSimpleLabelWithType(proposal);
760: int relevance = computeRelevance(proposal);
761:
762: final JavaCompletionProposal javaProposal = new JavaCompletionProposal(
763: completion, start, length, image, label, relevance);
764: javaProposal.setTriggerCharacters(VAR_TRIGGER);
765: return javaProposal;
766: }
767:
768: private IJavaCompletionProposal createMethodDeclarationProposal(
769: CompletionProposal proposal) {
770: if (fCompilationUnit == null || fJavaProject == null)
771: return null;
772:
773: String name = String.valueOf(proposal.getName());
774: String[] paramTypes = Signature.getParameterTypes(String
775: .valueOf(proposal.getSignature()));
776: for (int index = 0; index < paramTypes.length; index++)
777: paramTypes[index] = Signature.toString(paramTypes[index]);
778: int start = proposal.getReplaceStart();
779: int length = getLength(proposal);
780:
781: String label = fLabelProvider
782: .createOverrideMethodProposalLabel(proposal);
783:
784: JavaCompletionProposal javaProposal = new OverrideCompletionProposal(
785: fJavaProject, fCompilationUnit, name, paramTypes,
786: start, length, label, String.valueOf(proposal
787: .getCompletion()));
788: javaProposal.setImage(getImage(fLabelProvider
789: .createMethodImageDescriptor(proposal)));
790: javaProposal.setProposalInfo(new MethodProposalInfo(
791: fJavaProject, proposal));
792: javaProposal.setRelevance(computeRelevance(proposal));
793:
794: fSuggestedMethodNames.add(new String(name));
795: return javaProposal;
796: }
797:
798: private IJavaCompletionProposal createMethodReferenceProposal(
799: CompletionProposal methodProposal) {
800: LazyJavaCompletionProposal proposal = new JavaMethodCompletionProposal(
801: methodProposal, getInvocationContext());
802: adaptLength(proposal, methodProposal);
803: return proposal;
804: }
805:
806: private void adaptLength(LazyJavaCompletionProposal proposal,
807: CompletionProposal coreProposal) {
808: if (fUserReplacementLength != -1) {
809: proposal.setReplacementLength(getLength(coreProposal));
810: }
811: }
812:
813: private IJavaCompletionProposal createPackageProposal(
814: CompletionProposal proposal) {
815: String completion = String.valueOf(proposal.getCompletion());
816: int start = proposal.getReplaceStart();
817: int length = getLength(proposal);
818: String label = fLabelProvider.createSimpleLabel(proposal);
819: Image image = getImage(fLabelProvider
820: .createPackageImageDescriptor(proposal));
821: int relevance = computeRelevance(proposal);
822:
823: return new JavaCompletionProposal(completion, start, length,
824: image, label, relevance);
825: }
826:
827: private IJavaCompletionProposal createTypeProposal(
828: CompletionProposal typeProposal) {
829: LazyJavaCompletionProposal proposal = new LazyJavaTypeCompletionProposal(
830: typeProposal, getInvocationContext());
831: adaptLength(proposal, typeProposal);
832: return proposal;
833: }
834:
835: private IJavaCompletionProposal createJavadocLinkTypeProposal(
836: CompletionProposal typeProposal) {
837: LazyJavaCompletionProposal proposal = new JavadocLinkTypeCompletionProposal(
838: typeProposal, getInvocationContext());
839: adaptLength(proposal, typeProposal);
840: return proposal;
841: }
842: }
|