Skip to content

Commit

Permalink
Resolve MethodBinding$LambdaMethod to LambdaMethod java element
Browse files Browse the repository at this point in the history
  • Loading branch information
mickaelistria authored and akurtakov committed Mar 27, 2024
1 parent 2206fc5 commit aa8844b
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.internal.core.LambdaExpression;
import org.eclipse.jdt.internal.core.LambdaMethod;

Expand Down Expand Up @@ -3126,4 +3131,47 @@ public void testBug546563() throws Exception {
elements
);
}

// Inspired from ReslveTests18.test0027
public void test0027_BindingForLambdaMethod() throws JavaModelException {
this.wc = getWorkingCopy(
"/Resolve/src/X.java",
"""
interface I {
I doit(I xyz);
}
public class X {
public static void main(String[] args) {
I i = (pqr) -> {
return (xyz) -> {
return (abc) -> abc;
};
};
}
}
""");

String str = this.wc.getSource();
String selection = "abc";
int start = str.lastIndexOf(selection);
int length = selection.length();

ASTParser parser = ASTParser.newParser(AST.getJLSLatest());
parser.setSource(this.wc);
parser.setProject(this.wc.getJavaProject());
parser.setWorkingCopyOwner(this.wc.getOwner());
parser.setCompilerOptions(this.wc.getOptions(true));
parser.setResolveBindings(true);
parser.setBindingsRecovery(true);
parser.setStatementsRecovery(true);
CompilationUnit dom = (CompilationUnit)parser.createAST(null);
Name variable = (Name)new NodeFinder(dom, start, length).getCoveredNode();
IJavaElement javaElement = variable.resolveBinding().getJavaElement();

assertElementsEqual(
"Unexpected elements",
"abc [in doit(I) [in <lambda #1> [in doit(I) [in <lambda #1> [in doit(I) [in <lambda #1> [in main(String[]) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]]]]]]]",
new IJavaElement[] { javaElement }
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
import org.eclipse.jdt.internal.core.JavaElement;
import org.eclipse.jdt.internal.core.LambdaExpression;
import org.eclipse.jdt.internal.core.LambdaFactory;
import org.eclipse.jdt.internal.core.util.Util;

/**
Expand Down Expand Up @@ -305,7 +307,7 @@ public IJavaElement getJavaElement() {
return element.resolved(this.binding);
}

private JavaElement getUnresolvedJavaElement() {
protected JavaElement getUnresolvedJavaElement() {
if (JavaCore.getPlugin() == null) {
return null;
}
Expand Down Expand Up @@ -603,6 +605,32 @@ public IVariableBinding[] getSyntheticOuterLocals() {
public void setSyntheticOuterLocals(IVariableBinding[] syntheticOuterLocalVariables) {
this.syntheticOuterLocalVariables = syntheticOuterLocalVariables;
}

@Override
protected JavaElement getUnresolvedJavaElement() {
if (JavaCore.getPlugin() == null) {
return null;
}
if (!(this.resolver instanceof DefaultBindingResolver)) return null;

DefaultBindingResolver defaultBindingResolver = (DefaultBindingResolver) this.resolver;
if (!defaultBindingResolver.fromJavaProject) return null;
ASTNode domNode = (ASTNode)defaultBindingResolver.bindingsToAstNodes.get(this);
// resolving all parent lambdas is necessary for proper resolution
// as it populates newAstToOldAst.
ASTNode current = domNode;
while (current != null) {
if (current instanceof org.eclipse.jdt.core.dom.LambdaExpression domLambda) {
defaultBindingResolver.resolveMethod(domLambda);
}
current = current.getParent();
}
if (defaultBindingResolver.newAstToOldAst.get(domNode) instanceof org.eclipse.jdt.internal.compiler.ast.LambdaExpression lambdaExpression) {
LambdaExpression expr = LambdaFactory.createLambdaExpression((JavaElement)getDeclaringMember().getJavaElement(), lambdaExpression);
return LambdaFactory.createLambdaMethod(expr, lambdaExpression);
}
return super.getUnresolvedJavaElement();
}
}

@Override
Expand Down

0 comments on commit aa8844b

Please sign in to comment.