Copyright (c) 2004, 2018 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation Andreas Magnusson - contribution for bug 151500
/******************************************************************************* * Copyright (c) 2004, 2018 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation * Andreas Magnusson <andreas.ch.magnusson@gmail.com>- contribution for bug 151500 *******************************************************************************/
package org.eclipse.jdt.internal.codeassist; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jdt.core.CompletionContext; import org.eclipse.jdt.core.CompletionFlags; import org.eclipse.jdt.core.CompletionProposal; import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.IAccessRule; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.env.IBinaryMethod; import org.eclipse.jdt.internal.compiler.env.IBinaryType; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; import org.eclipse.jdt.internal.core.BinaryType; import org.eclipse.jdt.internal.core.JavaElement; import org.eclipse.jdt.internal.core.JavaModelManager; import org.eclipse.jdt.internal.core.NameLookup; import org.eclipse.jdt.internal.core.NamedMember; import org.eclipse.jdt.internal.core.SourceMapper;
Internal completion proposal
Since:3.1
/** * Internal completion proposal * @since 3.1 */
public class InternalCompletionProposal extends CompletionProposal { private static Object NO_ATTACHED_SOURCE = new Object(); protected CompletionEngine completionEngine; protected NameLookup nameLookup; protected char[] declarationPackageName; protected char[] declarationTypeName; protected char[] moduleName; protected char[] packageName; protected char[] typeName; protected char[][] parameterPackageNames; protected char[][] parameterTypeNames; protected char[] originalSignature; private boolean hasNoParameterNamesFromIndex = false; private boolean updateCompletion = false; protected int accessibility = IAccessRule.K_ACCESSIBLE; protected boolean isConstructor = false;
Kind of completion request.
/** * Kind of completion request. */
private int completionKind;
Offset in original buffer where ICodeAssist.codeComplete() was requested.
/** * Offset in original buffer where ICodeAssist.codeComplete() was * requested. */
private int completionLocation;
Start position (inclusive) of source range in original buffer containing the relevant token defaults to empty subrange at [0,0).
/** * Start position (inclusive) of source range in original buffer * containing the relevant token * defaults to empty subrange at [0,0). */
private int tokenStart = 0;
End position (exclusive) of source range in original buffer containing the relevant token; defaults to empty subrange at [0,0).
/** * End position (exclusive) of source range in original buffer * containing the relevant token; * defaults to empty subrange at [0,0). */
private int tokenEnd = 0;
Completion string; defaults to empty string.
/** * Completion string; defaults to empty string. */
private char[] completion = CharOperation.NO_CHAR;
Start position (inclusive) of source range in original buffer to be replaced by completion string; defaults to empty subrange at [0,0).
/** * Start position (inclusive) of source range in original buffer * to be replaced by completion string; * defaults to empty subrange at [0,0). */
private int replaceStart = 0;
End position (exclusive) of source range in original buffer to be replaced by completion string; defaults to empty subrange at [0,0).
/** * End position (exclusive) of source range in original buffer * to be replaced by completion string; * defaults to empty subrange at [0,0). */
private int replaceEnd = 0;
Relevance rating; positive; higher means better; defaults to minimum rating.
/** * Relevance rating; positive; higher means better; * defaults to minimum rating. */
private int relevance = 1;
Signature of the relevant package or type declaration in the context, or null if none. Defaults to null.
/** * Signature of the relevant package or type declaration * in the context, or <code>null</code> if none. * Defaults to null. */
private char[] declarationSignature = null;
Unique key of the relevant package or type declaration in the context, or null if none. Defaults to null.
/** * Unique key of the relevant package or type declaration * in the context, or <code>null</code> if none. * Defaults to null. */
private char[] declarationKey = null;
Simple name of the method, field, member, or variable relevant in the context, or null if none. Defaults to null.
/** * Simple name of the method, field, * member, or variable relevant in the context, or * <code>null</code> if none. * Defaults to null. */
private char[] name = null;
Binding of the method or constructor being proposed, or null if none. Defaults to null.
/** * Binding of the method or constructor being proposed, or * <code>null</code> if none. * Defaults to null. */
private Binding binding = null;
Signature of the method, field type, member type, relevant in the context, or null if none. Defaults to null.
/** * Signature of the method, field type, member type, * relevant in the context, or <code>null</code> if none. * Defaults to null. */
private char[] signature = null;
Unique of the method, field type, member type, relevant in the context, or null if none. Defaults to null.
/** * Unique of the method, field type, member type, * relevant in the context, or <code>null</code> if none. * Defaults to null. */
private char[] key = null;
Array of required completion proposals, or null if none. The proposal can not be applied if the required proposals aren't applied. Defaults to null.
/** * Array of required completion proposals, or <code>null</code> if none. * The proposal can not be applied if the required proposals aren't applied. * Defaults to <code>null</code>. */
private CompletionProposal[] requiredProposals;
Modifier flags relevant in the context, or Flags.AccDefault if none. Defaults to Flags.AccDefault.
/** * Modifier flags relevant in the context, or * <code>Flags.AccDefault</code> if none. * Defaults to <code>Flags.AccDefault</code>. */
private int flags = Flags.AccDefault;
Completion flags relevant in the context, or CompletionFlags.Default if none. Defaults to CompletionFlags.Default.
/** * Completion flags relevant in the context, or * <code>CompletionFlags.Default</code> if none. * Defaults to <code>CompletionFlags.Default</code>. */
private int additionalFlags = CompletionFlags.Default;
Parameter names (for method completions), or null if none. Lazily computed. Defaults to null.
/** * Parameter names (for method completions), or * <code>null</code> if none. Lazily computed. * Defaults to <code>null</code>. */
private char[][] parameterNames = null;
Indicates whether parameter names have been computed.
/** * Indicates whether parameter names have been computed. */
private boolean parameterNamesComputed = false; protected char[][] findConstructorParameterNames(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] paramTypeNames){ if(paramTypeNames == null || declaringTypeName == null) return null; char[][] parameters = null; int length = paramTypeNames.length; char[] tName = CharOperation.concat(declaringTypePackageName,declaringTypeName,'.'); Object cachedType = this.completionEngine.typeCache.get(tName); IType type = null; if(cachedType != null) { if(cachedType != NO_ATTACHED_SOURCE && cachedType instanceof BinaryType) { type = (BinaryType)cachedType; } } else { // TODO (david) shouldn't it be NameLookup.ACCEPT_ALL ? NameLookup.Answer answer = this.nameLookup.findType(new String(declaringTypeName), new String(declaringTypePackageName), false, NameLookup.ACCEPT_CLASSES & NameLookup.ACCEPT_INTERFACES, true/* consider secondary types */, false/* do NOT wait for indexes */, false/*don't check restrictions*/, null); type = answer == null ? null : answer.type; if(type instanceof BinaryType){ this.completionEngine.typeCache.put(tName, type); } else { type = null; } } if(type != null) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=316937 // BinaryType#getMethod() creates a new instance of BinaryMethod, which is a dummy. // Instead we have to use IType#findMethods() to get a handle to the method of our interest. try { IMethod method = findMethod(type, selector, paramTypeNames); if (this.hasNoParameterNamesFromIndex) { IPackageFragmentRoot packageFragmentRoot = (IPackageFragmentRoot)type.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); if (packageFragmentRoot.isArchive() || this.completionEngine.openedBinaryTypes < getOpenedBinaryTypesThreshold()) { SourceMapper mapper = ((JavaElement)method).getSourceMapper(); if (mapper != null) { char[][] paramNames = mapper.getMethodParameterNames(method); // map source and try to find parameter names if(paramNames == null) { if (!packageFragmentRoot.isArchive()) this.completionEngine.openedBinaryTypes++; IBinaryType info = (IBinaryType) ((BinaryType) type).getElementInfo(); char[] source = mapper.findSource(type, info); if (source != null){ mapper.mapSource((NamedMember) type, source, info); } paramNames = mapper.getMethodParameterNames(method); } if(paramNames != null) { parameters = paramNames; } } } } else { IBinaryMethod info = (IBinaryMethod) ((JavaElement)method).getElementInfo(); char[][] argumentNames = info.getArgumentNames(); if (argumentNames != null && argumentNames.length == length) { parameters = argumentNames; return parameters; } parameters = new char[length][]; String[] params = method.getParameterNames(); for(int i = 0; i< length ; i++){ parameters[i] = params[i].toCharArray(); } } } catch(JavaModelException e){ parameters = null; } } // default parameters name if(parameters == null) { parameters = CompletionEngine.createDefaultParameterNames(length); } return parameters; } protected char[][] findMethodParameterNames(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] paramTypeNames){ if(paramTypeNames == null || declaringTypeName == null) return null; char[][] parameters = null; int length = paramTypeNames.length; char[] tName = CharOperation.concat(declaringTypePackageName,declaringTypeName,'.'); Object cachedType = this.completionEngine.typeCache.get(tName); IType type = null; if(cachedType != null) { if(cachedType != NO_ATTACHED_SOURCE && cachedType instanceof BinaryType) { type = (BinaryType)cachedType; } } else { // TODO (david) shouldn't it be NameLookup.ACCEPT_ALL ? NameLookup.Answer answer = this.nameLookup.findType(new String(declaringTypeName), new String(declaringTypePackageName), false, NameLookup.ACCEPT_CLASSES & NameLookup.ACCEPT_INTERFACES, true/* consider secondary types */, false/* do NOT wait for indexes */, false/*don't check restrictions*/, null); type = answer == null ? null : answer.type; if(type instanceof BinaryType){ this.completionEngine.typeCache.put(tName, type); } else { type = null; } } if(type != null) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=316937 // BinaryType#getMethod() creates a new instance of BinaryMethod, which is a dummy. // Instead we have to use IType#findMethods() to get a handle to the method of our interest. try{ IMethod method = findMethod(type, selector, paramTypeNames); parameters = new char[length][]; String[] params = method.getParameterNames(); for(int i = 0; i< length ; i++){ parameters[i] = params[i].toCharArray(); } } catch(JavaModelException e){ parameters = null; } } // default parameters name if(parameters == null) { parameters = CompletionEngine.createDefaultParameterNames(length); } return parameters; } private IMethod findMethod(IType type, char[] selector, char[][] paramTypeNames) throws JavaModelException { IMethod method = null; int startingIndex = 0; String[] args; IType enclosingType = type.getDeclaringType(); // If the method is a constructor of a non-static inner type, add the enclosing type as an // additional parameter to the constructor if (enclosingType != null && CharOperation.equals(type.getElementName().toCharArray(), selector) && !Flags.isStatic(type.getFlags())) { args = new String[paramTypeNames.length+1]; startingIndex = 1; args[0] = Signature.createTypeSignature(enclosingType.getFullyQualifiedName(), true); } else { args = new String[paramTypeNames.length]; } int length = args.length; for(int i = startingIndex; i< length ; i++){ args[i] = new String(paramTypeNames[i-startingIndex]); } method = type.getMethod(new String(selector), args); IMethod[] methods = type.findMethods(method); if (methods != null && methods.length > 0) { method = methods[0]; } return method; } protected char[] getDeclarationPackageName() { return this.declarationPackageName; } protected char[] getDeclarationTypeName() { return this.declarationTypeName; } private int getOpenedBinaryTypesThreshold() { return JavaModelManager.getJavaModelManager().getOpenableCacheSize() / 10; } protected char[] getModuleName() { return this.moduleName; } protected char[] getPackageName() { return this.packageName; } protected char[] getTypeName() { return this.typeName; } protected char[][] getParameterPackageNames() { return this.parameterPackageNames; } protected char[][] getParameterTypeNames() { return this.parameterTypeNames; } protected void setDeclarationPackageName(char[] declarationPackageName) { this.declarationPackageName = declarationPackageName; } protected void setDeclarationTypeName(char[] declarationTypeName) { this.declarationTypeName = declarationTypeName; } protected void setModuleName(char[] moduleName) { this.moduleName = moduleName; } protected void setPackageName(char[] packageName) { this.packageName = packageName; } protected void setTypeName(char[] typeName) { this.typeName = typeName; } protected void setParameterPackageNames(char[][] parameterPackageNames) { this.parameterPackageNames = parameterPackageNames; } protected void setParameterTypeNames(char[][] parameterTypeNames) { this.parameterTypeNames = parameterTypeNames; } protected void setAccessibility(int kind) { this.accessibility = kind; } protected void setIsContructor(boolean isConstructor) { this.isConstructor = isConstructor; } public void setOriginalSignature(char[] originalSignature) { this.originalSignature = originalSignature; }
Creates a basic completion proposal. All instance field have plausible default values unless otherwise noted.

Note that the constructors for this class are internal to the Java model implementation. Clients cannot directly create CompletionProposal objects.

Params:
  • kind – one of the kind constants declared on this class
  • completionLocation – original offset of code completion request
/** * Creates a basic completion proposal. All instance * field have plausible default values unless otherwise noted. * <p> * Note that the constructors for this class are internal to the * Java model implementation. Clients cannot directly create * CompletionProposal objects. * </p> * * @param kind one of the kind constants declared on this class * @param completionLocation original offset of code completion request */
public InternalCompletionProposal(int kind, int completionLocation) { if ((kind < FIRST_KIND) || (kind > LAST_KIND)) { throw new IllegalArgumentException(); } if (this.completion == null || completionLocation < 0) { // Work around for bug 132558 (https://bugs.eclipse.org/bugs/show_bug.cgi?id=132558). // completionLocation can be -1 if the completion occur at the start of a file or // the start of a code snippet but this API isn't design to support negative position. if(this.completion == null || completionLocation != -1) { throw new IllegalArgumentException(); } completionLocation = 0; } this.completionKind = kind; this.completionLocation = completionLocation; } @Override public int getAdditionalFlags() { return this.additionalFlags; } @Override public void setAdditionalFlags(int additionalFlags) { this.additionalFlags = additionalFlags; } @Override public int getKind() { return this.completionKind; } // TODO (david) https://bugs.eclipse.org/bugs/show_bug.cgi?id=132558 @Override public int getCompletionLocation() { return this.completionLocation; } @Override public int getTokenStart() { return this.tokenStart; } @Override public int getTokenEnd() { return this.tokenEnd; } @Override public void setTokenRange(int startIndex, int endIndex) { if (startIndex < 0 || endIndex < startIndex) { throw new IllegalArgumentException(); } this.tokenStart = startIndex; this.tokenEnd = endIndex; } @Override public char[] getCompletion() { if(this.completionKind == METHOD_DECLARATION) { findParameterNames(null); if(this.updateCompletion) { this.updateCompletion = false; if(this.parameterNames != null) { int length = this.parameterNames.length; StringBuffer completionBuffer = new StringBuffer(this.completion.length); int start = 0; int end = CharOperation.indexOf('%', this.completion); completionBuffer.append(this.completion, start, end - start); for(int i = 0 ; i < length ; i++){ completionBuffer.append(this.parameterNames[i]); start = end + 1; end = CharOperation.indexOf('%', this.completion, start); if(end > -1){ completionBuffer.append(this.completion, start, end - start); } else { completionBuffer.append(this.completion, start, this.completion.length - start); } } int nameLength = completionBuffer.length(); this.completion = new char[nameLength]; completionBuffer.getChars(0, nameLength, this.completion, 0); } } } return this.completion; } @Override public void setCompletion(char[] completion) { this.completion = completion; } @Override public int getReplaceStart() { return this.replaceStart; } @Override public int getReplaceEnd() { return this.replaceEnd; } @Override public void setReplaceRange(int startIndex, int endIndex) { if (startIndex < 0 || endIndex < startIndex) { throw new IllegalArgumentException(); } this.replaceStart = startIndex; this.replaceEnd = endIndex; } @Override public int getRelevance() { return this.relevance; } @Override public void setRelevance(int rating) { if (rating <= 0) { throw new IllegalArgumentException(); } this.relevance = rating; } @Override public char[] getDeclarationSignature() { return this.declarationSignature; } @Override public char[] getDeclarationKey() { return this.declarationKey; } @Override public void setDeclarationSignature(char[] signature) { this.declarationSignature = signature; } @Override public void setDeclarationKey(char[] key) { this.declarationKey = key; } @Override public char[] getName() { return this.name; } @Override public void setName(char[] name) { this.name = name; }
Returns a binding of the method or field corresponding to this proposal or null if none.

The binding may be available for the following kinds of completion proposals:

  • ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION - MethodBinding of the constructor being proposed
  • CONSTRUCTOR_INVOCATION - MethodBinding of the constructor being proposed
  • FIELD_REF - FieldBinding of the field being proposed
  • FIELD_REF_WITH_CASTED_RECEIVER - FieldBinding of the field being proposed
  • JAVADOC_FIELD_REF - FieldBinding of the field being proposed
  • JAVADOC_METHOD_REF - MethodBinding of the method or constructor being proposed
  • METHOD_DECLARATION - MethodBinding of the method or constructor being proposed
  • METHOD_NAME_REFERENCE - MethodBinding of the method or constructor being proposed
  • METHOD_REF - MethodBinding of the method or constructor being proposed
  • METHOD_REF_WITH_CASTED_RECEIVER - MethodBinding of the method or constructor being proposed
For other kinds of completion proposals, this method returns null.

Returns:the binding corresponding to this proposal (if available), or null if none
/** * Returns a binding of the method or field corresponding to this proposal or <code>null</code> if none. * <p> * The binding <em>may</em> be available for the following kinds of completion proposals: * <ul> * <li><code>ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION</code> - {@link MethodBinding} * of the constructor being proposed</li> * <li><code>CONSTRUCTOR_INVOCATION</code> - {@link MethodBinding} * of the constructor being proposed</li> * <li><code>FIELD_REF</code> - {@link FieldBinding} * of the field being proposed</li> * <li><code>FIELD_REF_WITH_CASTED_RECEIVER</code> - {@link FieldBinding} * of the field being proposed</li> * <li><code>JAVADOC_FIELD_REF</code> - {@link FieldBinding} * of the field being proposed</li> * <li><code>JAVADOC_METHOD_REF</code> - {@link MethodBinding} * of the method or constructor being proposed</li> * <li><code>METHOD_DECLARATION</code> - {@link MethodBinding} * of the method or constructor being proposed</li> * <li><code>METHOD_NAME_REFERENCE</code> - {@link MethodBinding} * of the method or constructor being proposed</li> * <li><code>METHOD_REF</code> - {@link MethodBinding} * of the method or constructor being proposed</li> * <li><code>METHOD_REF_WITH_CASTED_RECEIVER</code> - {@link MethodBinding} * of the method or constructor being proposed</li> * </ul> * For other kinds of completion proposals, this method returns <code>null</code>. * </p> * * @return the binding corresponding to this proposal (if available), or <code>null</code> if none */
public Binding getBinding() { return this.binding; } public void setBinding(Binding binding) { this.binding = binding; } @Override public char[] getSignature() { return this.signature; } @Override public char[] getKey() { return this.key; } // /** // * Returns the package name of the relevant // * declaration in the context, or <code>null</code> if none. // * <p> // * This field is available for the following kinds of // * completion proposals: // * <ul> // * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - the dot-based package name // * of the type that is being subclassed or implemented</li> // * <li><code>FIELD_REF</code> - the dot-based package name // * of the type that declares the field that is referenced</li> // * <li><code>METHOD_REF</code> - the dot-based package name // * of the type that declares the method that is referenced</li> // * <li><code>METHOD_DECLARATION</code> - the dot-based package name // * of the type that declares the method that is being // * implemented or overridden</li> // * </ul> // * For kinds of completion proposals, this method returns // * <code>null</code>. Clients must not modify the array // * returned. // * </p> // * // * @return the dot-based package name, or // * <code>null</code> if none // * @see #getDeclarationSignature() // * @see #getSignature() // * // * @since 3.1 // */ // public char[] getDeclarationPackageName() { // return this.declarationPackageName; // } // // /** // * Returns the type name of the relevant // * declaration in the context without the package fragment, // * or <code>null</code> if none. // * <p> // * This field is available for the following kinds of // * completion proposals: // * <ul> // * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - the dot-based type name // * of the type that is being subclassed or implemented</li> // * <li><code>FIELD_REF</code> - the dot-based type name // * of the type that declares the field that is referenced // * or an anonymous type instantiation ("new X(){}") if it is an anonymous type</li> // * <li><code>METHOD_REF</code> - the dot-based type name // * of the type that declares the method that is referenced // * or an anonymous type instantiation ("new X(){}") if it is an anonymous type</li> // * <li><code>METHOD_DECLARATION</code> - the dot-based type name // * of the type that declares the method that is being // * implemented or overridden</li> // * </ul> // * For kinds of completion proposals, this method returns // * <code>null</code>. Clients must not modify the array // * returned. // * </p> // * // * @return the dot-based package name, or // * <code>null</code> if none // * @see #getDeclarationSignature() // * @see #getSignature() // * // * @since 3.1 // */ // public char[] getDeclarationTypeName() { // return this.declarationTypeName; // } // // /** // * Returns the package name of the method or type // * relevant in the context, or <code>null</code> if none. // * <p> // * This field is available for the following kinds of // * completion proposals: // * <ul> // * <li><code>FIELD_REF</code> - the dot-based package name // * of the referenced field's type</li> // * <li><code>LOCAL_VARIABLE_REF</code> - the dot-based package name // * of the referenced local variable's type</li> // * <li><code>METHOD_REF</code> - the dot-based package name // * of the return type of the method that is referenced</li> // * <li><code>METHOD_DECLARATION</code> - the dot-based package name // * of the return type of the method that is being implemented // * or overridden</li> // * <li><code>PACKAGE_REF</code> - the dot-based package name // * of the package that is referenced</li> // * <li><code>TYPE_REF</code> - the dot-based package name // * of the type that is referenced</li> // * <li><code>VARIABLE_DECLARATION</code> - the dot-based package name // * of the type of the variable being declared</li> // * </ul> // * For kinds of completion proposals, this method returns // * <code>null</code>. Clients must not modify the array // * returned. // * </p> // * // * @return the package name, or <code>null</code> if none // * // * @see #getDeclarationSignature() // * @see #getSignature() // * // * @since 3.1 // */ // public char[] getPackageName() { // return this.packageName; // } // // /** // * Returns the type name without the package fragment of the method or type // * relevant in the context, or <code>null</code> if none. // * <p> // * This field is available for the following kinds of // * completion proposals: // * <ul> // * <li><code>FIELD_REF</code> - the dot-based type name // * of the referenced field's type</li> // * <li><code>LOCAL_VARIABLE_REF</code> - the dot-based type name // * of the referenced local variable's type</li> // * <li><code>METHOD_REF</code> - the dot-based type name // * of the return type of the method that is referenced</li> // * <li><code>METHOD_DECLARATION</code> - the dot-based type name // * of the return type of the method that is being implemented // * or overridden</li> // * <li><code>TYPE_REF</code> - the dot-based type name // * of the type that is referenced</li> // * <li><code>VARIABLE_DECLARATION</code> - the dot-based package name // * of the type of the variable being declared</li> // * </ul> // * For kinds of completion proposals, this method returns // * <code>null</code>. Clients must not modify the array // * returned. // * </p> // * // * @return the package name, or <code>null</code> if none // * // * @see #getDeclarationSignature() // * @see #getSignature() // * // * @since 3.1 // */ // public char[] getTypeName() { // return this.typeName; // } // // /** // * Returns the parameter package names of the method // * relevant in the context, or <code>null</code> if none. // * <p> // * This field is available for the following kinds of // * completion proposals: // * <ul> // * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - parameter package names // * of the constructor that is being invoked</li> // * <li><code>METHOD_REF</code> - parameter package names // * of the method that is referenced</li> // * <li><code>METHOD_DECLARATION</code> - parameter package names // * of the method that is being implemented or overridden</li> // * </ul> // * For kinds of completion proposals, this method returns // * <code>null</code>. Clients must not modify the array // * returned. // * </p> // * // * @return the package name, or <code>null</code> if none // * // * @see #getDeclarationSignature() // * @see #getSignature() // * // * @since 3.1 // */ // public char[][] getParameterPackageNames() { // return this.parameterPackageNames; // } // // /** // * Returns the parameter type names without the package fragment of // * the method relevant in the context, or <code>null</code> if none. // * <p> // * This field is available for the following kinds of // * completion proposals: // * <ul> // * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - parameter type names // * of the constructor that is being invoked</li> // * <li><code>METHOD_REF</code> - parameter type names // * of the method that is referenced</li> // * <li><code>METHOD_DECLARATION</code> - parameter type names // * of the method that is being implemented or overridden</li> // * </ul> // * For kinds of completion proposals, this method returns // * <code>null</code>. Clients must not modify the array // * returned. // * </p> // * // * @return the package name, or <code>null</code> if none // * // * @see #getDeclarationSignature() // * @see #getSignature() // * // * @since 3.1 // */ // public char[][] getParameterTypeNames() { // return this.parameterTypeNames; // } @Override public void setSignature(char[] signature) { this.signature = signature; } @Override public void setKey(char[] key) { this.key = key; } @Override public int getFlags() { return this.flags; } @Override public void setFlags(int flags) { this.flags = flags; } public void setHasNoParameterNamesFromIndex(boolean hasNoParameterNamesFromIndex) { this.hasNoParameterNamesFromIndex = hasNoParameterNamesFromIndex; } @Override public CompletionProposal[] getRequiredProposals() { return this.requiredProposals; } @Override public void setRequiredProposals(CompletionProposal[] proposals) { this.requiredProposals = proposals; } @Override public char[][] findParameterNames(IProgressMonitor monitor) { if (!this.parameterNamesComputed) { this.parameterNamesComputed = true; switch(this.completionKind) { case ANONYMOUS_CLASS_DECLARATION: try { this.parameterNames = findMethodParameterNames( this.declarationPackageName, this.declarationTypeName, CharOperation.lastSegment(this.declarationTypeName, '.'), Signature.getParameterTypes(this.originalSignature == null ? this.signature : this.originalSignature)); } catch(IllegalArgumentException e) { // protection for invalid signature if(this.parameterTypeNames != null) { this.parameterNames = CompletionEngine.createDefaultParameterNames(this.parameterTypeNames.length); } else { this.parameterNames = null; } } break; case ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION: try { this.parameterNames = findConstructorParameterNames( this.declarationPackageName, this.declarationTypeName, CharOperation.lastSegment(this.declarationTypeName, '.'), Signature.getParameterTypes(this.originalSignature == null ? this.signature : this.originalSignature)); } catch(IllegalArgumentException e) { // protection for invalid signature if(this.parameterTypeNames != null) { this.parameterNames = CompletionEngine.createDefaultParameterNames(this.parameterTypeNames.length); } else { this.parameterNames = null; } } break; case METHOD_REF: case METHOD_REF_WITH_CASTED_RECEIVER: try { this.parameterNames = findMethodParameterNames( this.declarationPackageName, this.declarationTypeName, this.name, Signature.getParameterTypes(this.originalSignature == null ? this.signature : this.originalSignature)); } catch(IllegalArgumentException e) { // protection for invalid signature if(this.parameterTypeNames != null) { this.parameterNames = CompletionEngine.createDefaultParameterNames(this.parameterTypeNames.length); } else { this.parameterNames = null; } } break; case CONSTRUCTOR_INVOCATION: try { this.parameterNames = findConstructorParameterNames( this.declarationPackageName, this.declarationTypeName, this.name, Signature.getParameterTypes(this.originalSignature == null ? this.signature : this.originalSignature)); } catch(IllegalArgumentException e) { // protection for invalid signature if(this.parameterTypeNames != null) { this.parameterNames = CompletionEngine.createDefaultParameterNames(this.parameterTypeNames.length); } else { this.parameterNames = null; } } break; case METHOD_DECLARATION: try { this.parameterNames = findMethodParameterNames( this.declarationPackageName, this.declarationTypeName, this.name, Signature.getParameterTypes(this.originalSignature == null ? this.signature : this.originalSignature)); } catch(IllegalArgumentException e) { // protection for invalid signature if(this.parameterTypeNames != null) { this.parameterNames = CompletionEngine.createDefaultParameterNames(this.parameterTypeNames.length); } else { this.parameterNames = null; } } if(this.parameterNames != null) { this.updateCompletion = true; } break; } } return this.parameterNames; } @Override public void setParameterNames(char[][] parameterNames) { this.parameterNames = parameterNames; this.parameterNamesComputed = true; } @Override public int getAccessibility() { return this.accessibility; } @Override public boolean isConstructor() { return this.isConstructor; } private int receiverStart; private int receiverEnd; private char[] receiverSignature; @Override public char[] getReceiverSignature() { return this.receiverSignature; } @Override public int getReceiverStart() { return this.receiverStart; } @Override public int getReceiverEnd() { return this.receiverEnd; } @Override public void setReceiverSignature(char[] signature) { this.receiverSignature = signature; } @Override public void setReceiverRange(int startIndex, int endIndex) { this.receiverStart = startIndex; this.receiverEnd = endIndex; } @Override public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append('['); switch(this.completionKind) { case CompletionProposal.ANONYMOUS_CLASS_DECLARATION : buffer.append("ANONYMOUS_CLASS_DECLARATION"); //$NON-NLS-1$ break; case CompletionProposal.FIELD_REF : buffer.append("FIELD_REF"); //$NON-NLS-1$ break; case CompletionProposal.KEYWORD : buffer.append("KEYWORD"); //$NON-NLS-1$ break; case CompletionProposal.LABEL_REF : buffer.append("LABEL_REF"); //$NON-NLS-1$ break; case CompletionProposal.LOCAL_VARIABLE_REF : buffer.append("LOCAL_VARIABLE_REF"); //$NON-NLS-1$ break; case CompletionProposal.METHOD_DECLARATION : buffer.append("METHOD_DECLARATION"); //$NON-NLS-1$ if(this.isConstructor) { buffer.append("<CONSTRUCTOR>"); //$NON-NLS-1$ } break; case CompletionProposal.METHOD_REF : buffer.append("METHOD_REF"); //$NON-NLS-1$ if(this.isConstructor) { buffer.append("<CONSTRUCTOR>"); //$NON-NLS-1$ } break; case CompletionProposal.MODULE_DECLARATION : buffer.append("MODULE_DECLARATION"); //$NON-NLS-1$ break; case CompletionProposal.MODULE_REF : buffer.append("MODULE_REF"); //$NON-NLS-1$ break; case CompletionProposal.PACKAGE_REF : buffer.append("PACKAGE_REF"); //$NON-NLS-1$ break; case CompletionProposal.TYPE_REF : buffer.append("TYPE_REF"); //$NON-NLS-1$ break; case CompletionProposal.VARIABLE_DECLARATION : buffer.append("VARIABLE_DECLARATION"); //$NON-NLS-1$ break; case CompletionProposal.POTENTIAL_METHOD_DECLARATION : buffer.append("POTENTIAL_METHOD_DECLARATION"); //$NON-NLS-1$ break; case CompletionProposal.METHOD_NAME_REFERENCE : buffer.append("METHOD_NAME_REFERENCE"); //$NON-NLS-1$ break; case CompletionProposal.ANNOTATION_ATTRIBUTE_REF : buffer.append("ANNOTATION_ATTRIBUTE_REF"); //$NON-NLS-1$ break; case CompletionProposal.JAVADOC_BLOCK_TAG : buffer.append("JAVADOC_BLOCK_TAG"); //$NON-NLS-1$ break; case CompletionProposal.JAVADOC_INLINE_TAG : buffer.append("JAVADOC_INLINE_TAG"); //$NON-NLS-1$ break; case CompletionProposal.JAVADOC_FIELD_REF: buffer.append("JAVADOC_FIELD_REF"); //$NON-NLS-1$ break; case CompletionProposal.JAVADOC_METHOD_REF : buffer.append("JAVADOC_METHOD_REF"); //$NON-NLS-1$ break; case CompletionProposal.JAVADOC_TYPE_REF : buffer.append("JAVADOC_TYPE_REF"); //$NON-NLS-1$ break; case CompletionProposal.JAVADOC_PARAM_REF : buffer.append("JAVADOC_PARAM_REF"); //$NON-NLS-1$ break; case CompletionProposal.JAVADOC_VALUE_REF : buffer.append("JAVADOC_VALUE_REF"); //$NON-NLS-1$ break; case CompletionProposal.FIELD_IMPORT : buffer.append("FIELD_IMPORT"); //$NON-NLS-1$ break; case CompletionProposal.METHOD_IMPORT : buffer.append("METHOD_IMPORT"); //$NON-NLS-1$ break; case CompletionProposal.TYPE_IMPORT : buffer.append("TYPE_IMPORT"); //$NON-NLS-1$ break; case CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER : buffer.append("METHOD_REF_WITH_CASTED_RECEIVER"); //$NON-NLS-1$ break; case CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER : buffer.append("FIELD_REF_WITH_CASTED_RECEIVER"); //$NON-NLS-1$ break; case CompletionProposal.CONSTRUCTOR_INVOCATION : buffer.append("CONSTRUCTOR_INVOCATION"); //$NON-NLS-1$ break; case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION : buffer.append("ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION"); //$NON-NLS-1$ break; default : buffer.append("PROPOSAL"); //$NON-NLS-1$ break; } buffer.append("]{completion:"); //$NON-NLS-1$ if (this.completion != null) buffer.append(this.completion); buffer.append(", declSign:"); //$NON-NLS-1$ if (this.declarationSignature != null) buffer.append(this.declarationSignature); buffer.append(", sign:"); //$NON-NLS-1$ if (this.signature != null) buffer.append(this.signature); buffer.append(", declKey:"); //$NON-NLS-1$ if (this.declarationKey != null) buffer.append(this.declarationKey); buffer.append(", key:"); //$NON-NLS-1$ if (this.key != null) buffer.append(this.key); buffer.append(", name:"); //$NON-NLS-1$ if (this.name != null) buffer.append(this.name); buffer.append(", replace:["); //$NON-NLS-1$ buffer.append(this.replaceStart); buffer.append(','); buffer.append(this.replaceEnd); buffer.append("], token:["); //$NON-NLS-1$ buffer.append(this.tokenStart); buffer.append(','); buffer.append(this.tokenEnd); buffer.append("], relevance:"); //$NON-NLS-1$ buffer.append(this.relevance); buffer.append('}'); return buffer.toString(); } @Override public boolean canUseDiamond(CompletionContext coreContext) { if (this.getKind() != CONSTRUCTOR_INVOCATION) return false; if (coreContext instanceof InternalCompletionContext) { InternalCompletionContext internalCompletionContext = (InternalCompletionContext) coreContext; if (internalCompletionContext.extendedContext == null) return false; char[] name1 = this.declarationPackageName; char[] name2 = this.declarationTypeName; char[] declarationType = CharOperation.concat(name1, name2, '.'); // fully qualified name // even if the type arguments used in the method have been substituted, // extract the original type arguments only, since thats what we want to compare with the class // type variables (Substitution might have happened when the constructor is coming from another // CU and not the current one). char[] sign = (this.originalSignature != null)? this.originalSignature : getSignature(); if (!(sign == null || sign.length < 2)) { sign = Signature.removeCapture(sign); } char[][] types= Signature.getParameterTypes(sign); String[] paramTypeNames= new String[types.length]; for (int i= 0; i < types.length; i++) { paramTypeNames[i]= new String(Signature.toCharArray(types[i])); } return internalCompletionContext.extendedContext.canUseDiamond(paramTypeNames,declarationType); } else { return false; } } }