Fix missing extension method parameters names during code completion

This commit is contained in:
Rawi01 committed 2020-04-04 22:51:43 +02:00
1 parent f035e9177f
commit 7242b70270
1 file changed
+71 -4
@@ -26,7 +26,11 @@ import static org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.AccV
import java.util.Arrays;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.CompletionProposal;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.codeassist.CompletionEngine;
import org.eclipse.jdt.internal.codeassist.InternalCompletionProposal;
@@ -36,20 +40,29 @@ import org.eclipse.jdt.internal.codeassist.complete.CompletionOnSingleNameRefere
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.core.NameLookup;
public class ExtensionMethodCompletionProposal extends InternalCompletionProposal {
private char[] fullSignature;
private char[][] parameterNames;
public ExtensionMethodCompletionProposal(final int replacementOffset) {
super(CompletionProposal.METHOD_REF, replacementOffset - 1);
}
public void setMethodBinding(final MethodBinding method, final ASTNode node) {
// Add proposal parameter names, sometimes its empty...
if (method.parameterNames != null && method.parameterNames.length > 0) {
setParameterNames(Arrays.copyOfRange(method.parameterNames, 1, method.parameterNames.length));
} else {
// Copy signature for parameter name resolution, this is more reliable but slower
fullSignature = CompletionEngine.getSignature(method);
}
MethodBinding original = method.original();
TypeBinding[] parameters = Arrays.copyOf(method.parameters, method.parameters.length);
method.parameters = Arrays.copyOfRange(method.parameters, 1, method.parameters.length);
// Add proposal parameter names, sometimes its still empty...
if (method.parameterNames != null && method.parameterNames.length > 0) {
setParameterNames(Arrays.copyOfRange(method.parameterNames, 1, method.parameterNames.length));
}
TypeBinding[] originalParameters = null;
if (original != method) {
originalParameters = Arrays.copyOf(method.original().parameters, method.original().parameters.length);
@@ -105,4 +118,58 @@ public class ExtensionMethodCompletionProposal extends InternalCompletionProposa
method.original().parameters = originalParameters;
}
}
@Override
public char[][] findParameterNames(IProgressMonitor monitor) {
if (parameterNames != null) {
return parameterNames;
}
NameLookup.Answer answer = this.nameLookup.findType(
new String(this.declarationTypeName),
new String(this.declarationPackageName),
false,
NameLookup.ACCEPT_CLASSES & NameLookup.ACCEPT_INTERFACES,
true/* consider secondary types */,
false/* do NOT wait for indexes */,
false/*don't check restrictions*/,
null);
if (answer != null && answer.type != null) {
char[][] parameterTypes = Signature.getParameterTypes(fullSignature);
String[] args = new String[parameterTypes.length];
for (int i = 0; i < parameterTypes.length; i++) {
args[i] = new String(parameterTypes[i]);
}
IMethod method = answer.type.getMethod(new String(this.getName()), args);
IMethod[] methods = answer.type.findMethods(method);
if (methods != null && methods.length > 0) {
method = methods[0];
}
if (method != null) {
try {
String[] parameterNames = method.getParameterNames();
char[][] parameterNamesAsChar = new char[parameterNames.length - 1][];
for (int i = 0; i < parameterNamesAsChar.length; i++) {
parameterNamesAsChar[i] = parameterNames[i + 1].toCharArray();
}
setParameterNames(parameterNamesAsChar);
} catch (JavaModelException e) {
// Nope
}
}
}
// Seems like we failed, fallback
if (parameterNames == null) {
parameterNames = super.findParameterNames(monitor);
}
return parameterNames;
}
@Override
public void setParameterNames(char[][] parameterNames) {
this.parameterNames = parameterNames;
super.setParameterNames(parameterNames);
}
}