/*
* Copyright (c) 2012, the Dart project authors.
*
* Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.dart.tools.ui.text.dart;
import com.google.dart.engine.element.Element;
import com.google.dart.tools.core.completion.CompletionContext;
import com.google.dart.tools.core.completion.CompletionProposal;
import com.google.dart.tools.ui.DartElementImageDescriptor;
import com.google.dart.tools.ui.DartElementLabels;
import com.google.dart.tools.ui.DartPluginImages;
import com.google.dart.tools.ui.Flags;
import com.google.dart.tools.ui.Messages;
import com.google.dart.tools.ui.internal.viewsupport.DartElementImageProvider;
import com.google.dart.tools.ui.text.editor.tmp.Signature;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.StyledString;
import java.util.Arrays;
/**
* Provides labels for Dart content assist proposals. The functionality is similar to the one
* provided by {@link com.google.dart.tools.ui.DartElementLabels}, but based on signatures and
* {@link CompletionProposal}s.
*/
public class CompletionProposalLabelProvider {
private static final String VOID_INDICATOR = " void"; //$NON-NLS-1$
private static final String DYNAMIC_INDICATOR = " dynamic"; //$NON-NLS-1$
private static final char[] DYNAMIC = "dynamic".toCharArray(); //$NON-NLS-1$
/**
* The completion context.
*/
private CompletionContext fContext;
/**
* Creates a new label provider.
*/
public CompletionProposalLabelProvider() {
}
/**
* Creates and returns a decorated image descriptor for a completion proposal.
*
* @param proposal the proposal for which to create an image descriptor
* @return the created image descriptor, or <code>null</code> if no image is available
*/
@SuppressWarnings({"unused", "deprecation"})
public ImageDescriptor createImageDescriptor(CompletionProposal proposal) {
// char[] compUnit = proposal.getDeclarationTypeName();
// char[] propType = proposal.getName();
// DartProject project = proposal.getJavaProject();
//
// IJsGlobalScopeContainerInitializerExtension init = null;
// Type type = proposal.getNameLookup().findType(new String(compUnit), true,
// NameLookup.ACCEPT_ALL);
// IPackageFragment frag = type.getPackageFragment();
//
// if(compUnit!=null && propType!=null)
// init = JSDScopeUiUtil.findLibraryUiInitializer(new Path(new
// String(compUnit)),project);
// if(init!=null) {
// ImageDescriptor description = init.getImage(new Path(new
// String(compUnit)),new String(propType), project);
// if( description!=null) return description;
// }
final int flags = proposal.getFlags();
ImageDescriptor descriptor;
switch (proposal.getKind()) {
case CompletionProposal.METHOD_DECLARATION:
case CompletionProposal.METHOD_NAME_REFERENCE:
case CompletionProposal.METHOD_REF:
case CompletionProposal.ARGUMENT_LIST:
case CompletionProposal.OPTIONAL_ARGUMENT:
case CompletionProposal.NAMED_ARGUMENT:
case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
descriptor = DartElementImageProvider.getMethodImageDescriptor(false, proposal.isPrivate());
break;
case CompletionProposal.ANONYMOUS_CLASS_DECLARATION:
case CompletionProposal.TYPE_REF:
descriptor = DartElementImageProvider.getTypeImageDescriptor(proposal.isInterface(), false);
break;
case CompletionProposal.FIELD_REF:
descriptor = DartElementImageProvider.getFieldImageDescriptor(false, proposal.isPrivate());
break;
case CompletionProposal.LOCAL_VARIABLE_REF:
case CompletionProposal.VARIABLE_DECLARATION:
descriptor = DartPluginImages.DESC_OBJS_LOCAL_VARIABLE;
break;
case CompletionProposal.LIBRARY_PREFIX:
descriptor = DartPluginImages.DESC_OBJS_LIBRARY;
break;
case CompletionProposal.TYPE_IMPORT:
descriptor = DartPluginImages.DESC_OBJS_PACKAGE;
break;
case CompletionProposal.KEYWORD:
case CompletionProposal.LABEL_REF:
descriptor = null;
break;
case CompletionProposal.JAVADOC_METHOD_REF:
case CompletionProposal.JAVADOC_TYPE_REF:
case CompletionProposal.JAVADOC_FIELD_REF:
case CompletionProposal.JAVADOC_BLOCK_TAG:
case CompletionProposal.JAVADOC_INLINE_TAG:
case CompletionProposal.JAVADOC_PARAM_REF:
descriptor = DartPluginImages.DESC_OBJS_JAVADOCTAG;
break;
default:
descriptor = null;
Assert.isTrue(false);
}
if (descriptor == null) {
return null;
}
return decorateImageDescriptor(descriptor, proposal);
}
/**
* Creates the display label for a given <code>CompletionProposal</code>.
*
* @param proposal the completion proposal to create the display label for
* @return the display label for <code>proposal</code>
*/
@SuppressWarnings("deprecation")
public String createLabel(CompletionProposal proposal) {
switch (proposal.getKind()) {
case CompletionProposal.METHOD_NAME_REFERENCE:
case CompletionProposal.METHOD_REF:
case CompletionProposal.ARGUMENT_LIST:
case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
if (fContext != null && fContext.isInJavadoc()) {
return createJavadocMethodProposalLabel(proposal);
}
return createMethodProposalLabel(proposal).getString();
case CompletionProposal.METHOD_DECLARATION:
return createOverrideMethodProposalLabel(proposal);
case CompletionProposal.ANONYMOUS_CLASS_DECLARATION:
return createAnonymousTypeLabel(proposal);
case CompletionProposal.TYPE_REF:
return createTypeProposalLabel(proposal);
case CompletionProposal.JAVADOC_TYPE_REF:
return createJavadocTypeProposalLabel(proposal);
case CompletionProposal.JAVADOC_FIELD_REF:
case CompletionProposal.JAVADOC_BLOCK_TAG:
case CompletionProposal.JAVADOC_INLINE_TAG:
case CompletionProposal.JAVADOC_PARAM_REF:
return createJavadocSimpleProposalLabel(proposal);
case CompletionProposal.JAVADOC_METHOD_REF:
return createJavadocMethodProposalLabel(proposal);
case CompletionProposal.LIBRARY_PREFIX:
return createLibraryPrefixProposalLabel(proposal);
case CompletionProposal.FIELD_REF:
return createSimpleLabelWithType(proposal);
case CompletionProposal.LOCAL_VARIABLE_REF:
case CompletionProposal.VARIABLE_DECLARATION:
return createSimpleLabelWithType(proposal);
case CompletionProposal.KEYWORD:
case CompletionProposal.LABEL_REF:
case CompletionProposal.TYPE_IMPORT:
return createSimpleLabel(proposal);
default:
Assert.isTrue(false);
return null;
}
}
/**
* Creates and returns a parameter list of the given method or type proposal suitable for display.
* The list does not include parentheses. The lower bound of parameter types is returned.
* <p>
* Examples:
*
* <pre>
* "void method(int i, Strings)" -> "int i, String s"
* "? extends Number method(String s, ? super Number n)" -> "String s, Number n"
* </pre>
* </p>
*
* @param proposal the proposal to create the parameter list for. Must be of kind
* {@link CompletionProposal#METHOD_REF} or {@link CompletionProposal#TYPE_REF}.
* @return the list of comma-separated parameters suitable for display
*/
public String createParameterList(CompletionProposal proposal) {
int kind = proposal.getKind();
switch (kind) {
case CompletionProposal.METHOD_REF:
case CompletionProposal.ARGUMENT_LIST:
return appendUnboundedParameterList(new StyledString(), proposal).toString();
default:
Assert.isLegal(false);
return null; // dummy
}
}
@SuppressWarnings("deprecation")
public StyledString createStyledLabel(CompletionProposal proposal) {
// TODO(messick) rewrite to create styled labels from the beginning
switch (proposal.getKind()) {
case CompletionProposal.ARGUMENT_LIST:
return createArgumentList(proposal);
case CompletionProposal.METHOD_NAME_REFERENCE:
case CompletionProposal.METHOD_REF:
case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
if (fContext != null && fContext.isInJavadoc()) {
return new StyledString(createLabel(proposal));
}
return createMethodProposalLabel(proposal);
case CompletionProposal.FIELD_REF:
return createLabelWithType(proposal);
case CompletionProposal.LOCAL_VARIABLE_REF:
case CompletionProposal.VARIABLE_DECLARATION:
return createLabelWithType(proposal);
default:
return new StyledString(createLabel(proposal));
}
}
String createAnonymousTypeLabel(CompletionProposal proposal) {
char[] declaringTypeSignature = proposal.getDeclarationSignature();
StyledString buffer = new StyledString();
buffer.append(Signature.getSignatureSimpleName(declaringTypeSignature));
buffer.append('(');
appendUnboundedParameterList(buffer, proposal);
buffer.append(')');
buffer.append(" "); //$NON-NLS-1$
buffer.append(DartTextMessages.ResultCollector_anonymous_type);
return buffer.toString();
}
StyledString createArgumentList(CompletionProposal methodProposal) {
StyledString nameBuffer = new StyledString();
appendUnboundedParameterList(nameBuffer, methodProposal);
return nameBuffer;
}
ImageDescriptor createFieldImageDescriptor(CompletionProposal proposal) {
return decorateImageDescriptor(
DartElementImageProvider.getFieldImageDescriptor(false, proposal.isPrivate()),
proposal);
}
/**
* Creates a display label for the given method proposal. The display label consists of:
* <ul>
* <li>the method name</li>
* <li>the raw simple name of the declaring type</li>
* </ul>
* <p>
* Examples: For the <code>get(int)</code> method of a variable of type
* <code>List<? extends Number></code>, the following display name is returned
* <code>get(int) - List</code>.<br>
* For the <code>add(E)</code> method of a variable of type <code>List</code>, the following
* display name is returned: <code>add(Object) - List</code>.<br>
* </p>
*
* @param methodProposal the method proposal to display
* @return the display label for the given method proposal
*/
String createJavadocMethodProposalLabel(CompletionProposal methodProposal) {
StringBuffer nameBuffer = new StringBuffer();
// method name
nameBuffer.append(methodProposal.getCompletion());
// declaring type
nameBuffer.append(" - "); //$NON-NLS-1$
String declaringType = extractDeclaringTypeFQN(methodProposal);
declaringType = Signature.getSimpleName(declaringType);
nameBuffer.append(declaringType);
return nameBuffer.toString();
}
String createJavadocSimpleProposalLabel(CompletionProposal proposal) {
// TODO get rid of this
return createSimpleLabel(proposal);
}
String createJavadocTypeProposalLabel(char[] fullName) {
// only display innermost type name as type name, using any
// enclosing types as qualification
int qIndex = findSimpleNameStart(fullName);
StringBuffer buf = new StringBuffer("{@link "); //$NON-NLS-1$
buf.append(fullName, qIndex, fullName.length - qIndex);
buf.append('}');
if (qIndex > 0) {
buf.append(DartElementLabels.CONCAT_STRING);
buf.append(fullName, 0, qIndex - 1);
}
return buf.toString();
}
String createJavadocTypeProposalLabel(CompletionProposal typeProposal) {
char[] fullName = Signature.toCharArray(typeProposal.getSignature());
return createJavadocTypeProposalLabel(fullName);
}
StyledString createLabelWithType(CompletionProposal proposal) {
StyledString buf = new StyledString();
buf.append(proposal.getCompletion());
char[] typeName = proposal.getReturnTypeName();
if (typeName.length > 0) {
if (isDynamic(typeName)) {
buf.append(DYNAMIC_INDICATOR, StyledString.QUALIFIER_STYLER);
} else {
buf.append(Element.RIGHT_ARROW, StyledString.QUALIFIER_STYLER);
buf.append(typeName != null ? typeName : DYNAMIC, StyledString.QUALIFIER_STYLER);
}
}
if (proposal.isPotentialMatch()) {
potentialize(buf, proposal);
}
return buf;
}
// TODO(messick) Delete this unused method.
String createLabelWithTypeAndDeclaration(CompletionProposal proposal) {
char[] name = proposal.getCompletion();
if (!isThisPrefix(name)) {
name = proposal.getName();
}
StringBuffer buf = new StringBuffer();
buf.append(name);
char[] typeName = Signature.getSignatureSimpleName(proposal.getSignature());
if (typeName.length > 0 && !(Arrays.equals(Signature.ANY, typeName))) {
buf.append(" : "); //$NON-NLS-1$
buf.append(typeName != null ? typeName : DYNAMIC);
}
char[] declaration = proposal.getDeclarationSignature();
if (declaration != null) {
declaration = Signature.getSignatureSimpleName(declaration);
if (declaration.length > 0) {
buf.append(" - "); //$NON-NLS-1$
buf.append(declaration != null ? declaration : DYNAMIC);
}
}
return buf.toString();
}
ImageDescriptor createLibraryImageDescriptor(CompletionProposal proposal) {
return decorateImageDescriptor(DartPluginImages.DESC_OBJS_LIBRARY, proposal);
}
String createLibraryPrefixProposalLabel(CompletionProposal proposal) {
Assert.isTrue(proposal.getKind() == CompletionProposal.LIBRARY_PREFIX);
return String.valueOf(proposal.getDeclarationSignature());
}
ImageDescriptor createLocalImageDescriptor(CompletionProposal proposal) {
return decorateImageDescriptor(DartPluginImages.DESC_OBJS_LOCAL_VARIABLE, proposal);
}
ImageDescriptor createMethodImageDescriptor(CompletionProposal proposal) {
return decorateImageDescriptor(
DartElementImageProvider.getMethodImageDescriptor(false, proposal.isPrivate()),
proposal);
}
/**
* Creates a display label for the given method proposal. The display label consists of:
* <ul>
* <li>the method name</li>
* <li>the parameter list (see {@link #createParameterList(CompletionProposal)})</li>
* <li>the upper bound of the return type (see {@link SignatureUtil#getUpperBound(String)})</li>
* <li>the raw simple name of the declaring type</li>
* </ul>
* <p>
* Examples: For the <code>get(int)</code> method of a variable of type
* <code>List<? extends Number></code>, the following display name is returned:
* <code>get(int index) Number - List</code>.<br>
* For the <code>add(E)</code> method of a variable of type <code>List<? super Number></code>, the
* following display name is returned: <code>add(Number o) void - List</code>.<br>
* </p>
*
* @param methodProposal the method proposal to display
* @return the display label for the given method proposal
*/
StyledString createMethodProposalLabel(CompletionProposal methodProposal) {
StyledString buffer = new StyledString();
// method name
buffer.append(methodProposal.getName());
boolean hasParameters = methodProposal.getKind() != CompletionProposal.METHOD_NAME_REFERENCE;
// parameters
if (hasParameters && Character.isJavaIdentifierStart(methodProposal.getName()[0])) {
if (!methodProposal.isGetOrSet()) {
int start = buffer.length();
buffer.append('(');
appendUnboundedParameterList(buffer, methodProposal);
buffer.append(')');
buffer.setStyle(start, buffer.length() - start, StyledString.DECORATIONS_STYLER);
}
}
// return type
if (!methodProposal.isConstructor()) {
char[] returnType = createTypeDisplayName(methodProposal.getReturnTypeName());
if (!Arrays.equals(Signature.ANY, returnType)) {
if (isVoid(returnType)) {
buffer.append(VOID_INDICATOR, StyledString.QUALIFIER_STYLER);
} else if (isDynamic(returnType)) {
buffer.append(DYNAMIC_INDICATOR, StyledString.QUALIFIER_STYLER);
} else {
buffer.append(Element.RIGHT_ARROW, StyledString.QUALIFIER_STYLER);
buffer.append(returnType != null ? returnType : DYNAMIC, StyledString.QUALIFIER_STYLER);
}
}
}
if (methodProposal.isPotentialMatch()) {
potentialize(buffer, methodProposal);
}
return buffer;
}
String createOverrideMethodProposalLabel(CompletionProposal methodProposal) {
StyledString nameBuffer = new StyledString();
// method name
nameBuffer.append(methodProposal.getName());
// parameters
nameBuffer.append('(');
appendUnboundedParameterList(nameBuffer, methodProposal);
nameBuffer.append(") "); //$NON-NLS-1$
// return type
// char[] returnType = createTypeDisplayName(Signature.getReturnType(methodProposal.getSignature()));
// nameBuffer.append(returnType);
// declaring type
nameBuffer.append(" - "); //$NON-NLS-1$
String declaringType = new String(methodProposal.getDeclarationSignature());//extractDeclaringTypeFQN(methodProposal);
nameBuffer.append(Messages.format(
DartTextMessages.ResultCollector_overridingmethod,
new String(declaringType)));
return nameBuffer.toString();
}
String createSimpleLabel(CompletionProposal proposal) {
String label = String.valueOf(proposal.getCompletion());
return StringUtils.remove(label, CompletionProposal.CURSOR_MARKER);
}
String createSimpleLabelWithType(CompletionProposal proposal) {
StringBuffer buf = new StringBuffer();
buf.append(proposal.getCompletion());
char[] typeName = Signature.getSignatureSimpleName(proposal.getSignature());
if (typeName.length > 0) {
buf.append(Element.RIGHT_ARROW);
buf.append(typeName != null ? typeName : DYNAMIC);
}
return buf.toString();
}
ImageDescriptor createTypeImageDescriptor(CompletionProposal proposal) {
return decorateImageDescriptor(
DartElementImageProvider.getTypeImageDescriptor(true, false),
proposal);
}
String createTypeProposalLabel(char[] fullName) {
// only display innermost type name as type name, using any
// enclosing types as qualification
// int qIndex= findSimpleNameStart(fullName);
//
StringBuffer buf = new StringBuffer();
// buf.append(fullName, qIndex, fullName.length - qIndex);
// if (qIndex > 0) {
// buf.append(DartElementLabels.CONCAT_STRING);
// buf.append(fullName, 0, qIndex - 1);
// }
buf.append(fullName);
return buf.toString();
}
/**
* Creates a display label for a given type proposal. The display label consists of:
* <ul>
* <li>the simple type name (erased when the context is in Dart doc)</li>
* <li>the package name</li>
* </ul>
* <p>
* Examples: A proposal for the generic type <code>List<E></code>, the display label is:
* <code>List<E></code>.
* </p>
*
* @param typeProposal the method proposal to display
* @return the display label for the given type proposal
*/
String createTypeProposalLabel(CompletionProposal typeProposal) {
StringBuffer buf = new StringBuffer();
buf.append(typeProposal.getCompletion());
char[] declarationSignature = typeProposal.getDeclarationSignature();
if (declarationSignature != null && declarationSignature.length > 0) {
buf.append(DartElementLabels.CONCAT_STRING);
buf.append(declarationSignature);
}
return buf.toString();
// char[] signature;
// if (fContext != null && fContext.isInJavadoc())
// signature= Signature.getTypeErasure(typeProposal.getSignature());
// else
// signature= typeProposal.getSignature();
// char[] fullName= Signature.toCharArray(signature);
// return createTypeProposalLabel(fullName);
}
void potentialize(StyledString label, CompletionProposal proposal) {
label.setStyle(0, label.length(), StyledString.QUALIFIER_STYLER);
// declaring type
String declaringType = extractDeclaringTypeFQN(proposal);
if (!declaringType.isEmpty()) {
label.append(" - ", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
label.append(declaringType, StyledString.QUALIFIER_STYLER);
}
}
/**
* Sets the completion context.
*
* @param context the completion context
*/
void setContext(CompletionContext context) {
fContext = context;
}
/**
* Creates a display string of a parameter list (without the parentheses) for the given parameter
* types and names.
*
* @param buffer the string buffer
* @param parameterTypes the parameter types
* @param parameterNames the parameter names
* @return the display string of the parameter list defined by the passed arguments
*/
private StyledString appendParameterSignature(StyledString buffer, char[][] parameterTypes,
char[][] parameterNames, int positionalCount, boolean hasNamed, boolean hasOptional) {
if (parameterTypes == null) {
if (parameterNames != null && parameterNames.length > 0) {
for (int i = 0; i < parameterNames.length - 1; i++) {
buffer.append(parameterNames[i]);
buffer.append(',');
buffer.append(' ');
}
buffer.append(parameterNames[parameterNames.length - 1]);
}
} else {
for (int i = 0; i < parameterTypes.length; i++) {
if (i > 0) {
buffer.append(',');
buffer.append(' ');
}
if (i == positionalCount) {
if (hasNamed) { // check hasNamed first because hasOptional implies hasNamed
buffer.append('{');
} else if (hasOptional) {
buffer.append('[');
}
}
if (!Arrays.equals(Signature.ANY, parameterTypes[i])) {
buffer.append(parameterTypes[i]);
buffer.append(' ');
}
if (parameterNames != null && parameterNames[i] != null) {
buffer.append(parameterNames[i]);
}
}
if (hasNamed) {
buffer.append('}');
} else if (hasOptional) {
buffer.append(']');
}
}
return buffer;
}
/**
* Appends the parameter list to <code>buffer</code>.
*
* @param buffer the buffer to append to
* @param methodProposal the method proposal
* @return the modified <code>buffer</code>
*/
private StyledString appendUnboundedParameterList(StyledString buffer,
CompletionProposal methodProposal) {
char[][] parameterNames = methodProposal.findParameterNames(null);
char[][] parameterTypes = methodProposal.getParameterTypeNames();
int positionalCount = methodProposal.getPositionalParameterCount();
boolean hasNamed = methodProposal.hasNamedParameters();
boolean hasOptional = methodProposal.hasOptionalParameters();
// for (int i = 0; i < parameterTypes.length; i++) {
// parameterTypes[i] = createTypeDisplayName(parameterTypes[i]);
// }
return appendParameterSignature(
buffer,
parameterTypes,
parameterNames,
positionalCount,
hasNamed,
hasOptional);
}
/**
* Returns the display string for a Dart type signature.
*
* @param typeSignature the type signature to create a display name for
* @return the display name for <code>typeSignature</code>
* @throws IllegalArgumentException if <code>typeSignature</code> is not a valid signature
* @see Signature#toCharArray(char[])
* @see Signature#getSimpleName(char[])
*/
private char[] createTypeDisplayName(char[] typeSignature) throws IllegalArgumentException {
char[] displayName = Signature.getSimpleName(Signature.toCharArray(typeSignature));
// XXX see https://bugs.eclipse.org/bugs/show_bug.cgi?id=84675
boolean useShortGenerics = false;
if (useShortGenerics) {
StringBuffer buf = new StringBuffer();
buf.append(displayName);
int pos;
do {
pos = buf.indexOf("? extends "); //$NON-NLS-1$
if (pos >= 0) {
buf.replace(pos, pos + 10, "+"); //$NON-NLS-1$
} else {
pos = buf.indexOf("? super "); //$NON-NLS-1$
if (pos >= 0) {
buf.replace(pos, pos + 8, "-"); //$NON-NLS-1$
}
}
} while (pos >= 0);
return buf.toString().toCharArray();
}
return displayName;
}
// /**
// * Converts the display name for an array type into a variable arity display name.
// * <p>
// * Examples:
// * <ul>
// * <li>"int[]" -> "int..."</li>
// * <li>"Object[][]" -> "Object[]..."</li>
// * <li>"String" -> "String"</li>
// * </ul>
// * </p>
// * <p>
// * If <code>typeName</code> does not include the substring "[]", it is returned unchanged.
// * </p>
// *
// * @param typeName the type name to convert
// * @return the converted type name
// */
// private char[] convertToVararg(char[] typeName) {
// if (typeName == null) {
// return typeName;
// }
// final int len = typeName.length;
// if (len < 2) {
// return typeName;
// }
//
// if (typeName[len - 1] != ']') {
// return typeName;
// }
// if (typeName[len - 2] != '[') {
// return typeName;
// }
//
// char[] vararg = new char[len + 1];
// System.arraycopy(typeName, 0, vararg, 0, len - 2);
// vararg[len - 2] = '.';
// vararg[len - 1] = '.';
// vararg[len] = '.';
// return vararg;
// }
/**
* Returns a version of <code>descriptor</code> decorated according to the passed
* <code>modifier</code> flags.
*
* @param descriptor the image descriptor to decorate
* @param proposal the proposal
* @return an image descriptor for a method proposal
* @see Flags
*/
@SuppressWarnings("deprecation")
private ImageDescriptor decorateImageDescriptor(ImageDescriptor descriptor,
CompletionProposal proposal) {
int adornments = 0;
int flags = proposal.getFlags();
int kind = proposal.getKind();
if (kind == CompletionProposal.FIELD_REF || kind == CompletionProposal.METHOD_DECLARATION
|| kind == CompletionProposal.METHOD_DECLARATION
|| kind == CompletionProposal.METHOD_NAME_REFERENCE
|| kind == CompletionProposal.METHOD_REF) {
if (Flags.isStatic(flags)) {
adornments |= DartElementImageDescriptor.STATIC;
}
}
if (kind == CompletionProposal.TYPE_REF && Flags.isAbstract(flags)) {
adornments |= DartElementImageDescriptor.ABSTRACT;
}
if (proposal.isDeprecated()) {
adornments |= DartElementImageDescriptor.DEPRECATED;
}
return new DartElementImageDescriptor(
descriptor,
adornments,
DartElementImageProvider.SMALL_SIZE);
}
/**
* Extracts the fully qualified name of the declaring type of a method reference.
*
* @param methodProposal a proposed method
* @return the qualified name of the declaring type
*/
private String extractDeclaringTypeFQN(CompletionProposal methodProposal) {
char[] declaringTypeSignature = methodProposal.getDeclarationSignature();
if (declaringTypeSignature == null) {
return "Object"; //$NON-NLS-1$
}
return String.valueOf(declaringTypeSignature);
}
private int findSimpleNameStart(char[] array) {
int lastDot = 0;
for (int i = 0, len = array.length; i < len; i++) {
char ch = array[i];
if (ch == '<') {
return lastDot;
} else if (ch == '.') {
lastDot = i + 1;
}
}
return lastDot;
}
private boolean isDynamic(char[] name) {
return name != null && name.length == 9 && name[0] == '<' && name[1] == 'd' && name[2] == 'y'
&& name[3] == 'n' && name[4] == 'a' && name[5] == 'm' && name[6] == 'i' && name[7] == 'c'
&& name[8] == '>';
}
/**
* Returns whether the given string starts with "this.".
*
* @param string
* @return <code>true</code> if the given string starts with "this."
*/
private boolean isThisPrefix(char[] string) {
if (string == null || string.length < 5) {
return false;
}
return string[0] == 't' && string[1] == 'h' && string[2] == 'i' && string[3] == 's'
&& string[4] == '.';
}
private boolean isVoid(char[] name) {
return name != null && name.length == 4 && name[0] == 'v' && name[1] == 'o' && name[2] == 'i'
&& name[3] == 'd';
}
}