Skip to content

Commit

Permalink
Improve support for completing constructor args
Browse files Browse the repository at this point in the history
  • Loading branch information
mickaelistria committed Jan 29, 2025
1 parent c52dfb2 commit 994c755
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.MethodRef;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
import org.eclipse.jdt.core.dom.ModuleDeclaration;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NameQualifiedType;
Expand Down Expand Up @@ -127,6 +126,7 @@
import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.SearchEngine;
Expand Down Expand Up @@ -1033,9 +1033,22 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
suggestDefaultCompletions = false;
}
}
if (context instanceof ClassInstanceCreation) {
if (this.expectedTypes.getExpectedTypes() != null && !this.expectedTypes.getExpectedTypes().isEmpty() && !this.expectedTypes.getExpectedTypes().get(0).isRecovered()) {
completeConstructor(this.expectedTypes.getExpectedTypes().get(0), context, this.javaProject);
if (context instanceof ClassInstanceCreation newObj) {
var newType = newObj.getType();
var binding = newType.resolveBinding();
if (this.offset > newType.getStartPosition() + newType.getLength() &&
binding != null &&
newObj.getType().resolveBinding().isEnum()) {
return; // don't complete illegal enum constructor
}
var visibleConstructors = Arrays.stream(binding.getDeclaredMethods())
.filter(IMethodBinding::isConstructor)
.filter(this::isVisible)
.toList();
if (visibleConstructors.size() == 1 && this.expectedTypes.getExpectedTypes() != null && !this.expectedTypes.getExpectedTypes().isEmpty() && !this.expectedTypes.getExpectedTypes().get(0).isRecovered()) {
completeConstructor(this.expectedTypes.getExpectedTypes().get(0), context, this.modelUnit.getJavaProject());
} else if (visibleConstructors.size() > 0) {
visibleConstructors.stream().map(this::toProposal).forEach(this.requestor::accept);
} else {
if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF) && !this.requestor.isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION)) {
String packageName = "";//$NON-NLS-1$
Expand Down Expand Up @@ -2320,6 +2333,12 @@ private CompletionProposal toProposal(IBinding binding, String completion) {
} else {
kind = CompletionProposal.METHOD_REF;
}
if (this.toComplete instanceof ClassInstanceCreation newObj && newObj.getType() != null && this.offset > newObj.getType().getStartPosition() + newObj.getType().getLength()) {
// actually completing open arg list
completion = ""; //$NON-NLS-1$
} else {
completion += "()"; //$NON-NLS-1$
}
} else if (binding instanceof IVariableBinding variableBinding) {
if (variableBinding.isField()) {
kind = CompletionProposal.FIELD_REF;
Expand All @@ -2330,9 +2349,6 @@ private CompletionProposal toProposal(IBinding binding, String completion) {

DOMInternalCompletionProposal res = createProposal(kind);
res.setName(binding.getName().toCharArray());
if (kind == CompletionProposal.METHOD_REF) {
completion += "()"; //$NON-NLS-1$
}
res.setCompletion(completion.toCharArray());
res.setFlags(binding.getModifiers());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,22 @@ private void computeExpectedTypes(){
return;
}
if (parent2 instanceof ClassInstanceCreation newObj && this.offset > newObj.getType().getStartPosition() + newObj.getType().getLength()) {
// TODO find params
int argIndexWip = 0;
var args = (List<Expression>)newObj.arguments();
for (argIndexWip = 0; argIndexWip < args.size(); argIndexWip++) {
var arg = args.get(argIndexWip);
if (this.offset < arg.getStartPosition() || this.offset > arg.getStartPosition() + arg.getLength()) {
break;
}
}
int argIndex = Math.max(0, argIndexWip - 1);
var binding = newObj.getType().resolveBinding();
Arrays.stream(binding.getDeclaredMethods())
.filter(IMethodBinding::isConstructor)
.map(IMethodBinding::getParameterTypes)
.filter(params -> params.length > argIndex)
.map(params -> params[argIndex])
.forEach(this.expectedTypes::add);
break;
}
if (parent2 instanceof CastExpression cast && this.offset > cast.getType().getStartPosition() + cast.getType().getLength()) {
Expand Down Expand Up @@ -237,12 +252,16 @@ private void computeExpectedTypes(){
}
}
} else if(parent instanceof ClassInstanceCreation allocationExpression) {
ITypeBinding binding = allocationExpression.resolveTypeBinding();
if(binding != null) {
computeExpectedTypesForAllocationExpression(
binding,
allocationExpression.arguments(),
allocationExpression);
if (this.offset <= allocationExpression.getType().getStartPosition() + allocationExpression.getType().getLength()) {
ITypeBinding binding = allocationExpression.resolveTypeBinding();
if(binding != null) {
computeExpectedTypesForAllocationExpression(
binding,
allocationExpression.arguments(),
allocationExpression);
}
} else {
//int itemIndexAtOffset =z
}
} else if(parent instanceof InstanceofExpression e) {
ITypeBinding binding = e.getLeftOperand().resolveTypeBinding();
Expand Down

0 comments on commit 994c755

Please sign in to comment.