001: /*******************************************************************************
002: * Copyright (c) 2005, 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 org.eclipse.core.runtime.Assert;
013:
014: import org.eclipse.jface.resource.ImageDescriptor;
015:
016: import org.eclipse.jdt.core.CompletionContext;
017: import org.eclipse.jdt.core.CompletionProposal;
018: import org.eclipse.jdt.core.Flags;
019: import org.eclipse.jdt.core.Signature;
020:
021: import org.eclipse.jdt.internal.corext.template.java.SignatureUtil;
022: import org.eclipse.jdt.internal.corext.util.Messages;
023:
024: import org.eclipse.jdt.ui.JavaElementImageDescriptor;
025: import org.eclipse.jdt.ui.JavaElementLabels;
026:
027: import org.eclipse.jdt.internal.ui.JavaPluginImages;
028: import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;
029:
030: /**
031: * Provides labels for java content assist proposals. The functionality is
032: * similar to the one provided by {@link org.eclipse.jdt.ui.JavaElementLabels},
033: * but based on signatures and {@link CompletionProposal}s.
034: *
035: * @see Signature
036: * @since 3.1
037: */
038: public class CompletionProposalLabelProvider {
039:
040: /**
041: * The completion context.
042: *
043: * @since 3.2
044: */
045: private CompletionContext fContext;
046:
047: /**
048: * Creates a new label provider.
049: */
050: public CompletionProposalLabelProvider() {
051: }
052:
053: /**
054: * Creates and returns a parameter list of the given method or type proposal
055: * suitable for display. The list does not include parentheses. The lower
056: * bound of parameter types is returned.
057: * <p>
058: * Examples:
059: * <pre>
060: * "void method(int i, Strings)" -> "int i, String s"
061: * "? extends Number method(java.lang.String s, ? super Number n)" -> "String s, Number n"
062: * </pre>
063: * </p>
064: *
065: * @param proposal the proposal to create the parameter list
066: * for. Must be of kind {@link CompletionProposal#METHOD_REF} or
067: * {@link CompletionProposal#TYPE_REF}.
068: * @return the list of comma-separated parameters suitable for display
069: */
070: public String createParameterList(CompletionProposal proposal) {
071: int kind = proposal.getKind();
072: switch (kind) {
073: case CompletionProposal.METHOD_REF:
074: return appendUnboundedParameterList(new StringBuffer(),
075: proposal).toString();
076: case CompletionProposal.TYPE_REF:
077: return appendTypeParameterList(new StringBuffer(), proposal)
078: .toString();
079: case CompletionProposal.ANONYMOUS_CLASS_DECLARATION:
080: return appendUnboundedParameterList(new StringBuffer(),
081: proposal).toString();
082: default:
083: Assert.isLegal(false);
084: return null; // dummy
085: }
086: }
087:
088: /**
089: * Appends the parameter list to <code>buffer</code>.
090: *
091: * @param buffer the buffer to append to
092: * @param methodProposal the method proposal
093: * @return the modified <code>buffer</code>
094: */
095: private StringBuffer appendUnboundedParameterList(
096: StringBuffer buffer, CompletionProposal methodProposal) {
097: // TODO remove once https://bugs.eclipse.org/bugs/show_bug.cgi?id=85293
098: // gets fixed.
099: char[] signature = SignatureUtil.fix83600(methodProposal
100: .getSignature());
101: char[][] parameterNames = methodProposal
102: .findParameterNames(null);
103: char[][] parameterTypes = Signature
104: .getParameterTypes(signature);
105:
106: for (int i = 0; i < parameterTypes.length; i++)
107: parameterTypes[i] = createTypeDisplayName(SignatureUtil
108: .getLowerBound(parameterTypes[i]));
109:
110: if (Flags.isVarargs(methodProposal.getFlags())) {
111: int index = parameterTypes.length - 1;
112: parameterTypes[index] = convertToVararg(parameterTypes[index]);
113: }
114: return appendParameterSignature(buffer, parameterTypes,
115: parameterNames);
116: }
117:
118: /**
119: * Appends the type parameter list to <code>buffer</code>.
120: *
121: * @param buffer the buffer to append to
122: * @param typeProposal the type proposal
123: * @return the modified <code>buffer</code>
124: * @since 3.2
125: */
126: private StringBuffer appendTypeParameterList(StringBuffer buffer,
127: CompletionProposal typeProposal) {
128: // TODO remove once https://bugs.eclipse.org/bugs/show_bug.cgi?id=85293
129: // gets fixed.
130: char[] signature = SignatureUtil.fix83600(typeProposal
131: .getSignature());
132: char[][] typeParameters = Signature.getTypeArguments(signature);
133: for (int i = 0; i < typeParameters.length; i++) {
134: char[] param = typeParameters[i];
135: typeParameters[i] = Signature.toCharArray(param);
136: }
137: return appendParameterSignature(buffer, typeParameters, null);
138: }
139:
140: /**
141: * Converts the display name for an array type into a variable arity display name.
142: * <p>
143: * Examples:
144: * <ul>
145: * <li> "int[]" -> "int..."</li>
146: * <li> "Object[][]" -> "Object[]..."</li>
147: * <li> "String" -> "String"</li>
148: * </ul>
149: * </p>
150: * <p>
151: * If <code>typeName</code> does not include the substring "[]", it is returned unchanged.
152: * </p>
153: *
154: * @param typeName the type name to convert
155: * @return the converted type name
156: * @since 3.2
157: */
158: private char[] convertToVararg(char[] typeName) {
159: if (typeName == null)
160: return typeName;
161: final int len = typeName.length;
162: if (len < 2)
163: return typeName;
164:
165: if (typeName[len - 1] != ']')
166: return typeName;
167: if (typeName[len - 2] != '[')
168: return typeName;
169:
170: char[] vararg = new char[len + 1];
171: System.arraycopy(typeName, 0, vararg, 0, len - 2);
172: vararg[len - 2] = '.';
173: vararg[len - 1] = '.';
174: vararg[len] = '.';
175: return vararg;
176: }
177:
178: /**
179: * Returns the display string for a java type signature.
180: *
181: * @param typeSignature the type signature to create a display name for
182: * @return the display name for <code>typeSignature</code>
183: * @throws IllegalArgumentException if <code>typeSignature</code> is not a
184: * valid signature
185: * @see Signature#toCharArray(char[])
186: * @see Signature#getSimpleName(char[])
187: */
188: private char[] createTypeDisplayName(char[] typeSignature)
189: throws IllegalArgumentException {
190: char[] displayName = Signature.getSimpleName(Signature
191: .toCharArray(typeSignature));
192:
193: // XXX see https://bugs.eclipse.org/bugs/show_bug.cgi?id=84675
194: boolean useShortGenerics = false;
195: if (useShortGenerics) {
196: StringBuffer buf = new StringBuffer();
197: buf.append(displayName);
198: int pos;
199: do {
200: pos = buf.indexOf("? extends "); //$NON-NLS-1$
201: if (pos >= 0) {
202: buf.replace(pos, pos + 10, "+"); //$NON-NLS-1$
203: } else {
204: pos = buf.indexOf("? super "); //$NON-NLS-1$
205: if (pos >= 0)
206: buf.replace(pos, pos + 8, "-"); //$NON-NLS-1$
207: }
208: } while (pos >= 0);
209: return buf.toString().toCharArray();
210: }
211: return displayName;
212: }
213:
214: /**
215: * Creates a display string of a parameter list (without the parentheses)
216: * for the given parameter types and names.
217: *
218: * @param buffer the string buffer
219: * @param parameterTypes the parameter types
220: * @param parameterNames the parameter names
221: * @return the display string of the parameter list defined by the passed arguments
222: */
223: private final StringBuffer appendParameterSignature(
224: StringBuffer buffer, char[][] parameterTypes,
225: char[][] parameterNames) {
226: if (parameterTypes != null) {
227: for (int i = 0; i < parameterTypes.length; i++) {
228: if (i > 0) {
229: buffer.append(',');
230: buffer.append(' ');
231: }
232: buffer.append(parameterTypes[i]);
233: if (parameterNames != null && parameterNames[i] != null) {
234: buffer.append(' ');
235: buffer.append(parameterNames[i]);
236: }
237: }
238: }
239: return buffer;
240: }
241:
242: /**
243: * Creates a display label for the given method proposal. The display label
244: * consists of:
245: * <ul>
246: * <li>the method name</li>
247: * <li>the parameter list (see {@link #createParameterList(CompletionProposal)})</li>
248: * <li>the upper bound of the return type (see {@link SignatureUtil#getUpperBound(String)})</li>
249: * <li>the raw simple name of the declaring type</li>
250: * </ul>
251: * <p>
252: * Examples:
253: * For the <code>get(int)</code> method of a variable of type <code>List<? extends Number></code>, the following
254: * display name is returned: <code>get(int index) Number - List</code>.<br>
255: * For the <code>add(E)</code> method of a variable of type <code>List<? super Number></code>, the following
256: * display name is returned: <code>add(Number o) void - List</code>.<br>
257: * </p>
258: *
259: * @param methodProposal the method proposal to display
260: * @return the display label for the given method proposal
261: */
262: String createMethodProposalLabel(CompletionProposal methodProposal) {
263: StringBuffer nameBuffer = new StringBuffer();
264:
265: // method name
266: nameBuffer.append(methodProposal.getName());
267:
268: // parameters
269: nameBuffer.append('(');
270: appendUnboundedParameterList(nameBuffer, methodProposal);
271: nameBuffer.append(')');
272:
273: // return type
274: if (!methodProposal.isConstructor()) {
275: // TODO remove SignatureUtil.fix83600 call when bugs are fixed
276: char[] returnType = createTypeDisplayName(SignatureUtil
277: .getUpperBound(Signature
278: .getReturnType(SignatureUtil
279: .fix83600(methodProposal
280: .getSignature()))));
281: nameBuffer.append(" "); //$NON-NLS-1$
282: nameBuffer.append(returnType);
283: }
284:
285: // declaring type
286: nameBuffer.append(" - "); //$NON-NLS-1$
287: String declaringType = extractDeclaringTypeFQN(methodProposal);
288: declaringType = Signature.getSimpleName(declaringType);
289: nameBuffer.append(declaringType);
290:
291: return nameBuffer.toString();
292: }
293:
294: /**
295: * Creates a display label for the given method proposal. The display label consists of:
296: * <ul>
297: * <li>the method name</li>
298: * <li>the raw simple name of the declaring type</li>
299: * </ul>
300: * <p>
301: * Examples: For the <code>get(int)</code> method of a variable of type
302: * <code>List<? extends Number></code>, the following display name is returned <code>get(int) - List</code>.<br>
303: * For the <code>add(E)</code> method of a variable of type <code>List</code>, the
304: * following display name is returned:
305: * <code>add(Object) - List</code>.<br>
306: * </p>
307: *
308: * @param methodProposal the method proposal to display
309: * @return the display label for the given method proposal
310: * @since 3.2
311: */
312: String createJavadocMethodProposalLabel(
313: CompletionProposal methodProposal) {
314: StringBuffer nameBuffer = new StringBuffer();
315:
316: // method name
317: nameBuffer.append(methodProposal.getCompletion());
318:
319: // declaring type
320: nameBuffer.append(" - "); //$NON-NLS-1$
321: String declaringType = extractDeclaringTypeFQN(methodProposal);
322: declaringType = Signature.getSimpleName(declaringType);
323: nameBuffer.append(declaringType);
324:
325: return nameBuffer.toString();
326: }
327:
328: String createOverrideMethodProposalLabel(
329: CompletionProposal methodProposal) {
330: StringBuffer nameBuffer = new StringBuffer();
331:
332: // method name
333: nameBuffer.append(methodProposal.getName());
334:
335: // parameters
336: nameBuffer.append('(');
337: appendUnboundedParameterList(nameBuffer, methodProposal);
338: nameBuffer.append(") "); //$NON-NLS-1$
339:
340: // return type
341: // TODO remove SignatureUtil.fix83600 call when bugs are fixed
342: char[] returnType = createTypeDisplayName(SignatureUtil
343: .getUpperBound(Signature.getReturnType(SignatureUtil
344: .fix83600(methodProposal.getSignature()))));
345: nameBuffer.append(returnType);
346:
347: // declaring type
348: nameBuffer.append(" - "); //$NON-NLS-1$
349:
350: String declaringType = extractDeclaringTypeFQN(methodProposal);
351: declaringType = Signature.getSimpleName(declaringType);
352: nameBuffer.append(Messages.format(
353: JavaTextMessages.ResultCollector_overridingmethod,
354: new String(declaringType)));
355:
356: return nameBuffer.toString();
357: }
358:
359: /**
360: * Extracts the fully qualified name of the declaring type of a method
361: * reference.
362: *
363: * @param methodProposal a proposed method
364: * @return the qualified name of the declaring type
365: */
366: private String extractDeclaringTypeFQN(
367: CompletionProposal methodProposal) {
368: char[] declaringTypeSignature = methodProposal
369: .getDeclarationSignature();
370: // special methods may not have a declaring type: methods defined on arrays etc.
371: // TODO remove when bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=84690 gets fixed
372: if (declaringTypeSignature == null)
373: return "java.lang.Object"; //$NON-NLS-1$
374: return SignatureUtil.stripSignatureToFQN(String
375: .valueOf(declaringTypeSignature));
376: }
377:
378: /**
379: * Creates a display label for a given type proposal. The display label
380: * consists of:
381: * <ul>
382: * <li>the simple type name (erased when the context is in javadoc)</li>
383: * <li>the package name</li>
384: * </ul>
385: * <p>
386: * Examples:
387: * A proposal for the generic type <code>java.util.List<E></code>, the display label
388: * is: <code>List<E> - java.util</code>.
389: * </p>
390: *
391: * @param typeProposal the method proposal to display
392: * @return the display label for the given type proposal
393: */
394: String createTypeProposalLabel(CompletionProposal typeProposal) {
395: char[] signature;
396: if (fContext != null && fContext.isInJavadoc())
397: signature = Signature.getTypeErasure(typeProposal
398: .getSignature());
399: else
400: signature = typeProposal.getSignature();
401: char[] fullName = Signature.toCharArray(signature);
402: return createTypeProposalLabel(fullName);
403: }
404:
405: String createJavadocTypeProposalLabel(
406: CompletionProposal typeProposal) {
407: char[] fullName = Signature.toCharArray(typeProposal
408: .getSignature());
409: return createJavadocTypeProposalLabel(fullName);
410: }
411:
412: String createJavadocSimpleProposalLabel(CompletionProposal proposal) {
413: // TODO get rid of this
414: return createSimpleLabel(proposal);
415: }
416:
417: String createTypeProposalLabel(char[] fullName) {
418: // only display innermost type name as type name, using any
419: // enclosing types as qualification
420: int qIndex = findSimpleNameStart(fullName);
421:
422: StringBuffer buf = new StringBuffer();
423: buf.append(fullName, qIndex, fullName.length - qIndex);
424: if (qIndex > 0) {
425: buf.append(JavaElementLabels.CONCAT_STRING);
426: buf.append(fullName, 0, qIndex - 1);
427: }
428: return buf.toString();
429: }
430:
431: String createJavadocTypeProposalLabel(char[] fullName) {
432: // only display innermost type name as type name, using any
433: // enclosing types as qualification
434: int qIndex = findSimpleNameStart(fullName);
435:
436: StringBuffer buf = new StringBuffer("{@link "); //$NON-NLS-1$
437: buf.append(fullName, qIndex, fullName.length - qIndex);
438: buf.append('}');
439: if (qIndex > 0) {
440: buf.append(JavaElementLabels.CONCAT_STRING);
441: buf.append(fullName, 0, qIndex - 1);
442: }
443: return buf.toString();
444: }
445:
446: private int findSimpleNameStart(char[] array) {
447: int lastDot = 0;
448: for (int i = 0, len = array.length; i < len; i++) {
449: char ch = array[i];
450: if (ch == '<') {
451: return lastDot;
452: } else if (ch == '.') {
453: lastDot = i + 1;
454: }
455: }
456: return lastDot;
457: }
458:
459: String createSimpleLabelWithType(CompletionProposal proposal) {
460: StringBuffer buf = new StringBuffer();
461: buf.append(proposal.getCompletion());
462: char[] typeName = Signature.getSignatureSimpleName(proposal
463: .getSignature());
464: if (typeName.length > 0) {
465: buf.append(" "); //$NON-NLS-1$
466: buf.append(typeName);
467: }
468: return buf.toString();
469: }
470:
471: /**
472: * Returns whether the given string starts with "this.".
473: *
474: * @param string
475: * @return <code>true</code> if the given string starts with "this."
476: * @since 3.3
477: */
478: private boolean isThisPrefix(char[] string) {
479: if (string == null || string.length < 5)
480: return false;
481: return string[0] == 't' && string[1] == 'h' && string[2] == 'i'
482: && string[3] == 's' && string[4] == '.';
483: }
484:
485: String createLabelWithTypeAndDeclaration(CompletionProposal proposal) {
486: char[] name = proposal.getCompletion();
487: if (!isThisPrefix(name))
488: name = proposal.getName();
489:
490: StringBuffer buf = new StringBuffer();
491: buf.append(name);
492: char[] typeName = Signature.getSignatureSimpleName(proposal
493: .getSignature());
494: if (typeName.length > 0) {
495: buf.append(" "); //$NON-NLS-1$
496: buf.append(typeName);
497: }
498: char[] declaration = proposal.getDeclarationSignature();
499: if (declaration != null) {
500: declaration = Signature.getSignatureSimpleName(declaration);
501: if (declaration.length > 0) {
502: buf.append(" - "); //$NON-NLS-1$
503: buf.append(declaration);
504: }
505: }
506:
507: return buf.toString();
508: }
509:
510: String createPackageProposalLabel(CompletionProposal proposal) {
511: Assert
512: .isTrue(proposal.getKind() == CompletionProposal.PACKAGE_REF);
513: return String.valueOf(proposal.getDeclarationSignature());
514: }
515:
516: String createSimpleLabel(CompletionProposal proposal) {
517: return String.valueOf(proposal.getCompletion());
518: }
519:
520: String createAnonymousTypeLabel(CompletionProposal proposal) {
521: char[] declaringTypeSignature = proposal
522: .getDeclarationSignature();
523:
524: StringBuffer buffer = new StringBuffer();
525: buffer.append(Signature
526: .getSignatureSimpleName(declaringTypeSignature));
527: buffer.append('(');
528: appendUnboundedParameterList(buffer, proposal);
529: buffer.append(')');
530: buffer.append(" "); //$NON-NLS-1$
531: buffer.append(JavaTextMessages.ResultCollector_anonymous_type);
532:
533: return buffer.toString();
534: }
535:
536: /**
537: * Creates the display label for a given <code>CompletionProposal</code>.
538: *
539: * @param proposal the completion proposal to create the display label for
540: * @return the display label for <code>proposal</code>
541: */
542: public String createLabel(CompletionProposal proposal) {
543: switch (proposal.getKind()) {
544: case CompletionProposal.METHOD_NAME_REFERENCE:
545: case CompletionProposal.METHOD_REF:
546: case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
547: if (fContext != null && fContext.isInJavadoc())
548: return createJavadocMethodProposalLabel(proposal);
549: return createMethodProposalLabel(proposal);
550: case CompletionProposal.METHOD_DECLARATION:
551: return createOverrideMethodProposalLabel(proposal);
552: case CompletionProposal.ANONYMOUS_CLASS_DECLARATION:
553: return createAnonymousTypeLabel(proposal);
554: case CompletionProposal.TYPE_REF:
555: return createTypeProposalLabel(proposal);
556: case CompletionProposal.JAVADOC_TYPE_REF:
557: return createJavadocTypeProposalLabel(proposal);
558: case CompletionProposal.JAVADOC_FIELD_REF:
559: case CompletionProposal.JAVADOC_VALUE_REF:
560: case CompletionProposal.JAVADOC_BLOCK_TAG:
561: case CompletionProposal.JAVADOC_INLINE_TAG:
562: case CompletionProposal.JAVADOC_PARAM_REF:
563: return createJavadocSimpleProposalLabel(proposal);
564: case CompletionProposal.JAVADOC_METHOD_REF:
565: return createJavadocMethodProposalLabel(proposal);
566: case CompletionProposal.PACKAGE_REF:
567: return createPackageProposalLabel(proposal);
568: case CompletionProposal.ANNOTATION_ATTRIBUTE_REF:
569: case CompletionProposal.FIELD_REF:
570: return createLabelWithTypeAndDeclaration(proposal);
571: case CompletionProposal.LOCAL_VARIABLE_REF:
572: case CompletionProposal.VARIABLE_DECLARATION:
573: return createSimpleLabelWithType(proposal);
574: case CompletionProposal.KEYWORD:
575: case CompletionProposal.LABEL_REF:
576: return createSimpleLabel(proposal);
577: default:
578: Assert.isTrue(false);
579: return null;
580: }
581: }
582:
583: /**
584: * Creates and returns a decorated image descriptor for a completion proposal.
585: *
586: * @param proposal the proposal for which to create an image descriptor
587: * @return the created image descriptor, or <code>null</code> if no image is available
588: */
589: public ImageDescriptor createImageDescriptor(
590: CompletionProposal proposal) {
591: final int flags = proposal.getFlags();
592:
593: ImageDescriptor descriptor;
594: switch (proposal.getKind()) {
595: case CompletionProposal.METHOD_DECLARATION:
596: case CompletionProposal.METHOD_NAME_REFERENCE:
597: case CompletionProposal.METHOD_REF:
598: case CompletionProposal.ANNOTATION_ATTRIBUTE_REF:
599: case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
600: case CompletionProposal.ANONYMOUS_CLASS_DECLARATION:
601: descriptor = JavaElementImageProvider
602: .getMethodImageDescriptor(false, flags);
603: break;
604: case CompletionProposal.TYPE_REF:
605: switch (Signature.getTypeSignatureKind(proposal
606: .getSignature())) {
607: case Signature.CLASS_TYPE_SIGNATURE:
608: descriptor = JavaElementImageProvider
609: .getTypeImageDescriptor(false, false, flags,
610: false);
611: break;
612: case Signature.TYPE_VARIABLE_SIGNATURE:
613: descriptor = JavaPluginImages.DESC_OBJS_TYPEVARIABLE;
614: break;
615: default:
616: descriptor = null;
617: }
618: break;
619: case CompletionProposal.FIELD_REF:
620: descriptor = JavaElementImageProvider
621: .getFieldImageDescriptor(false, flags);
622: break;
623: case CompletionProposal.LOCAL_VARIABLE_REF:
624: case CompletionProposal.VARIABLE_DECLARATION:
625: descriptor = JavaPluginImages.DESC_OBJS_LOCAL_VARIABLE;
626: break;
627: case CompletionProposal.PACKAGE_REF:
628: descriptor = JavaPluginImages.DESC_OBJS_PACKAGE;
629: break;
630: case CompletionProposal.KEYWORD:
631: case CompletionProposal.LABEL_REF:
632: descriptor = null;
633: break;
634: case CompletionProposal.JAVADOC_METHOD_REF:
635: case CompletionProposal.JAVADOC_TYPE_REF:
636: case CompletionProposal.JAVADOC_FIELD_REF:
637: case CompletionProposal.JAVADOC_VALUE_REF:
638: case CompletionProposal.JAVADOC_BLOCK_TAG:
639: case CompletionProposal.JAVADOC_INLINE_TAG:
640: case CompletionProposal.JAVADOC_PARAM_REF:
641: descriptor = JavaPluginImages.DESC_OBJS_JAVADOCTAG;
642: break;
643: default:
644: descriptor = null;
645: Assert.isTrue(false);
646: }
647:
648: if (descriptor == null)
649: return null;
650: return decorateImageDescriptor(descriptor, proposal);
651: }
652:
653: ImageDescriptor createMethodImageDescriptor(
654: CompletionProposal proposal) {
655: final int flags = proposal.getFlags();
656: return decorateImageDescriptor(JavaElementImageProvider
657: .getMethodImageDescriptor(false, flags), proposal);
658: }
659:
660: ImageDescriptor createTypeImageDescriptor(
661: CompletionProposal proposal) {
662: final int flags = proposal.getFlags();
663: boolean isInterfaceOrAnnotation = Flags.isInterface(flags)
664: || Flags.isAnnotation(flags);
665: return decorateImageDescriptor(
666: JavaElementImageProvider
667: .getTypeImageDescriptor(
668: true /* in order to get all visibility decorations */,
669: isInterfaceOrAnnotation, flags, false),
670: proposal);
671: }
672:
673: ImageDescriptor createFieldImageDescriptor(
674: CompletionProposal proposal) {
675: final int flags = proposal.getFlags();
676: return decorateImageDescriptor(JavaElementImageProvider
677: .getFieldImageDescriptor(false, flags), proposal);
678: }
679:
680: ImageDescriptor createLocalImageDescriptor(
681: CompletionProposal proposal) {
682: return decorateImageDescriptor(
683: JavaPluginImages.DESC_OBJS_LOCAL_VARIABLE, proposal);
684: }
685:
686: ImageDescriptor createPackageImageDescriptor(
687: CompletionProposal proposal) {
688: return decorateImageDescriptor(
689: JavaPluginImages.DESC_OBJS_PACKAGE, proposal);
690: }
691:
692: /**
693: * Returns a version of <code>descriptor</code> decorated according to
694: * the passed <code>modifier</code> flags.
695: *
696: * @param descriptor the image descriptor to decorate
697: * @param proposal the proposal
698: * @return an image descriptor for a method proposal
699: * @see Flags
700: */
701: private ImageDescriptor decorateImageDescriptor(
702: ImageDescriptor descriptor, CompletionProposal proposal) {
703: int adornments = 0;
704: int flags = proposal.getFlags();
705: int kind = proposal.getKind();
706:
707: if (Flags.isDeprecated(flags))
708: adornments |= JavaElementImageDescriptor.DEPRECATED;
709:
710: if (kind == CompletionProposal.FIELD_REF
711: || kind == CompletionProposal.METHOD_DECLARATION
712: || kind == CompletionProposal.METHOD_DECLARATION
713: || kind == CompletionProposal.METHOD_NAME_REFERENCE
714: || kind == CompletionProposal.METHOD_REF)
715: if (Flags.isStatic(flags))
716: adornments |= JavaElementImageDescriptor.STATIC;
717:
718: if (kind == CompletionProposal.METHOD_DECLARATION
719: || kind == CompletionProposal.METHOD_DECLARATION
720: || kind == CompletionProposal.METHOD_NAME_REFERENCE
721: || kind == CompletionProposal.METHOD_REF)
722: if (Flags.isSynchronized(flags))
723: adornments |= JavaElementImageDescriptor.SYNCHRONIZED;
724:
725: if (kind == CompletionProposal.TYPE_REF
726: && Flags.isAbstract(flags) && !Flags.isInterface(flags))
727: adornments |= JavaElementImageDescriptor.ABSTRACT;
728:
729: if (kind == CompletionProposal.FIELD_REF) {
730: if (Flags.isTransient(flags))
731: adornments |= JavaElementImageDescriptor.TRANSIENT;
732: if (Flags.isVolatile(flags))
733: adornments |= JavaElementImageDescriptor.VOLATILE;
734: }
735:
736: return new JavaElementImageDescriptor(descriptor, adornments,
737: JavaElementImageProvider.SMALL_SIZE);
738: }
739:
740: /**
741: * Sets the completion context.
742: *
743: * @param context the completion context
744: * @since 3.2
745: */
746: void setContext(CompletionContext context) {
747: fContext = context;
748: }
749:
750: }
|