Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSrikanth Sankaran2013-10-04 08:57:35 +0000
committerM N Palat2013-10-04 08:57:35 +0000
commitf5937020c6b957eed03745f57cfee671f23dd9b8 (patch)
tree3e7011610ad9b99a2b89eaab92f61ad23898d3d5
parent9485b94fdcfe614c14bea8b532c58213d01bbc20 (diff)
downloadeclipse.jdt.core-f5937020c6b957eed03745f57cfee671f23dd9b8.tar.gz
eclipse.jdt.core-f5937020c6b957eed03745f57cfee671f23dd9b8.tar.xz
eclipse.jdt.core-f5937020c6b957eed03745f57cfee671f23dd9b8.zip
Fix for Bug 417017 - [1.8] Incorrect parameters in resolved method
binding for LambdaExpression
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java194
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java8
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java12
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java7
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java8
5 files changed, 223 insertions, 6 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
index 807876636a..73afc7cec7 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
@@ -2645,6 +2645,200 @@ public class ASTConverter18Test extends ConverterTestSetup {
typeBinding = type.resolveBinding();
assertFalse("A Functional interface", typeBinding.isFunctionalInterface());
}
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=417017
+ *
+ * @throws JavaModelException
+ */
+ public void test417017a() throws JavaModelException {
+ this.workingCopy = getWorkingCopy("/Converter18/src/test417017/X.java",
+ true/* resolve */);
+ String contents = "package test417017;"
+ + "interface I {\n"
+ + " int foo(int x);\n"
+ + "}\n"
+ + "public class X {\n"
+ + " void fun(int a) {\n"
+ +" I i1 = x1-> x1;\n"
+ +" I i2 = xxx-> {\n"
+ +" i1.foo(a);\n"
+ +" return xxx;\n"
+ +" };\n"
+ +" }\n"
+ +"}\n";
+ CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy);
+ TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 1);
+ MethodDeclaration methodDeclaration = typedeclaration.getMethods()[0];
+ VariableDeclarationFragment vdf= (VariableDeclarationFragment) ((VariableDeclarationStatement) methodDeclaration.getBody().statements().get(1)).fragments().get(0);
+ LambdaExpression lambda= (LambdaExpression) vdf.getInitializer();
+ List parameters = lambda.parameters();
+ assertTrue("Incorrect Number of parameters", parameters.size() == 1);
+ ITypeBinding[] parameterTypes= lambda.resolveMethodBinding().getParameterTypes();
+ assertTrue("Incorrect Number of parameter type", parameterTypes.length == 1);
+ assertEquals("Incorrect parameter type", "int", parameterTypes[0].toString());
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=417017
+ *
+ * @throws JavaModelException
+ */
+ public void test417017b() throws JavaModelException {
+ this.workingCopy = getWorkingCopy("/Converter18/src/test417017/X.java",
+ true/* resolve */);
+ String contents = "package test417017;" +
+ "interface I1 {\n" +
+ " int foo(int a);\n" +
+ "}\n" +
+ "\n" +
+ "interface I2 {\n" +
+ " public default int foo() {\n" +
+ " I1 i1 = (a) -> {\n" +
+ " return a;\n" +
+ " };\n" +
+ " //return 0;\n" + // Error on purpose
+ " }\n" +
+ "}\n" ;
+ CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy, false);
+ TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 1);
+ MethodDeclaration methodDeclaration = typedeclaration.getMethods()[0];
+ VariableDeclarationFragment vdf= (VariableDeclarationFragment) ((VariableDeclarationStatement) methodDeclaration.getBody().statements().get(0)).fragments().get(0);
+ LambdaExpression lambda= (LambdaExpression) vdf.getInitializer();
+ List parameters = lambda.parameters();
+ assertTrue("Incorrect Number of parameters", parameters.size() == 1);
+ ITypeBinding[] parameterTypes= lambda.resolveMethodBinding().getParameterTypes();
+ assertTrue("Incorrect Number of parameter type", parameterTypes.length == 1);
+ assertEquals("Incorrect parameter type", "int", parameterTypes[0].toString());
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=417017
+ *
+ * @throws JavaModelException
+ */
+ public void test417017c() throws JavaModelException {
+ this.workingCopy = getWorkingCopy("/Converter18/src/test417017/X.java",
+ true/* resolve */);
+ String contents = "package test417017;" +
+ "interface I1 {\n" +
+ " int foo(int a);\n" +
+ "}\n" +
+ "\n" +
+ "interface I2 {\n" +
+ " public default int foo() {\n" +
+ " I1 i1 = (float a) -> {\n" +
+ " return a;\n" +
+ " };\n" +
+ " //return 0;\n" + // Error on purpose
+ " }\n" +
+ "}\n" ;
+ CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy, false);
+ TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 1);
+ MethodDeclaration methodDeclaration = typedeclaration.getMethods()[0];
+ VariableDeclarationFragment vdf= (VariableDeclarationFragment) ((VariableDeclarationStatement) methodDeclaration.getBody().statements().get(0)).fragments().get(0);
+ LambdaExpression lambda= (LambdaExpression) vdf.getInitializer();
+ List parameters = lambda.parameters();
+ assertTrue("Incorrect Number of parameters", parameters.size() == 1);
+ ITypeBinding[] parameterTypes= lambda.resolveMethodBinding().getParameterTypes();
+ assertTrue("Incorrect Number of parameter type", parameterTypes.length == 1);
+ assertEquals("Incorrect parameter type", "float", parameterTypes[0].toString());
+ }
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=417017
+ *
+ * @throws JavaModelException
+ */
+ public void test417017d() throws JavaModelException {
+ this.workingCopy = getWorkingCopy("/Converter18/src/test399794/X.java",
+ true/* resolve */);
+ String contents = "package test399794;" +
+ "interface I {\n" +
+ " void foo(X x);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " void foo(X x) {\n" +
+ " }\n" +
+ " I i = this::foo;\n" +
+ "}\n";
+
+ CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy);
+ TypeDeclaration typeDeclaration = (TypeDeclaration) getASTNode(cu, 1);
+ FieldDeclaration field = typeDeclaration.getFields()[0];
+
+ VariableDeclarationFragment fragment = (VariableDeclarationFragment) field.fragments().get(0);
+ Expression expression = fragment.getInitializer();
+ ExpressionMethodReference methodReference = (ExpressionMethodReference) expression;
+ IMethodBinding methodBinding = methodReference.resolveMethodBinding();
+ assertNotNull(methodBinding);
+ ITypeBinding [] parameterTypes = methodBinding.getParameterTypes();
+ assertTrue("Incorrect Number of parameter type", parameterTypes.length == 1);
+ assertEquals("Incorrect parameter type", "X", parameterTypes[0].getName());
+ }
+
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=417017
+ *
+ * @throws JavaModelException
+ */
+ public void test417017e() throws JavaModelException {
+ this.workingCopy = getWorkingCopy("/Converter18/src/test399794/X.java",
+ true/* resolve */);
+ String contents = "package test399794;" +
+ "interface I {\n" +
+ " int [] foo(int x);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " I i = int []::new;\n" +
+ "}\n";
+
+ CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy);
+ TypeDeclaration typeDeclaration = (TypeDeclaration) getASTNode(cu, 1);
+ FieldDeclaration field = typeDeclaration.getFields()[0];
+
+ VariableDeclarationFragment fragment = (VariableDeclarationFragment) field.fragments().get(0);
+ Expression expression = fragment.getInitializer();
+ CreationReference creationReference = (CreationReference) expression;
+ IMethodBinding methodBinding = creationReference.resolveMethodBinding();
+ assertNotNull(methodBinding);
+ assertEquals("Wrong name", "lambda$0", methodBinding.getName());
+ ITypeBinding [] parameterTypes = methodBinding.getParameterTypes();
+ assertTrue("Incorrect Number of parameter type", parameterTypes.length == 1);
+ assertEquals("Incorrect parameter type", "int", parameterTypes[0].getName());
+ }
+
+ /**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=417017
+ *
+ * @throws JavaModelException
+ */
+ public void test417017f() throws JavaModelException {
+ this.workingCopy = getWorkingCopy("/Converter18/src/test399794/X.java",
+ true/* resolve */);
+ String contents = "package test399794;" +
+ "interface I {\n" +
+ " void foo(X x);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " private void foo(X x) {\n" +
+ " }\n" +
+ " class Y {\n" +
+ " I i = X.this::foo;\n" +
+ " }\n" +
+ "}\n";
+
+ CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy);
+ TypeDeclaration typeDeclaration = (TypeDeclaration) getASTNode(cu, 1);
+ typeDeclaration = typeDeclaration.getTypes()[0];
+ FieldDeclaration field = typeDeclaration.getFields()[0];
+
+ VariableDeclarationFragment fragment = (VariableDeclarationFragment) field.fragments().get(0);
+ Expression expression = fragment.getInitializer();
+ ExpressionMethodReference reference = (ExpressionMethodReference) expression;
+ IMethodBinding methodBinding = reference.resolveMethodBinding();
+ assertNotNull(methodBinding);
+ assertEquals("Wrong name", "foo", methodBinding.getName());
+ ITypeBinding [] parameterTypes = methodBinding.getParameterTypes();
+ assertTrue("Incorrect Number of parameter type", parameterTypes.length == 1);
+ assertEquals("Incorrect parameter type", "X", parameterTypes[0].getName());
+ }
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=413942
// also refer https://bugs.eclipse.org/bugs/show_bug.cgi?id=413569
public void testBug413942() throws JavaModelException {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
index 4e6475292b..b2e589d566 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
@@ -38,7 +38,8 @@ public abstract class FunctionalExpression extends Expression {
TypeBinding expectedType;
public MethodBinding descriptor;
- public MethodBinding binding;
+ public MethodBinding binding; // Code generation binding. May include synthetics. See getMethodBinding()
+ protected MethodBinding actualMethodBinding; // void of synthetics.
boolean ignoreFurtherInvestigation;
protected ExpressionContext expressionContext = VANILLA_CONTEXT;
protected SimpleLookupTable resultExpressions;
@@ -51,7 +52,10 @@ public abstract class FunctionalExpression extends Expression {
public FunctionalExpression(CompilationResult compilationResult) {
this.compilationResult = compilationResult;
}
-
+ // Return the actual (non-code generation) method binding that is void of synthetics.
+ public MethodBinding getMethodBinding() {
+ return null;
+ }
public void setExpectedType(TypeBinding expectedType) {
this.expectedType = this.ellipsisArgument ? ((ArrayBinding) expectedType).elementsType() : expectedType;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
index fcbd1d0bce..ffe9add2a6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
@@ -49,6 +49,7 @@ import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
@@ -783,6 +784,17 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
return this.outerLocalVariables[i];
return null;
}
+
+ // Return the actual method binding devoid of synthetics.
+ public MethodBinding getMethodBinding() {
+ if (this.actualMethodBinding == null) {
+ this.actualMethodBinding = new MethodBinding(this.binding.modifiers, this.binding.selector, this.binding.returnType,
+ this.binding instanceof SyntheticMethodBinding ? this.descriptor.parameters : this.binding.parameters, // retain any faults in parameter list.
+ this.binding.thrownExceptions, this.binding.declaringClass);
+ this.actualMethodBinding.tagBits = this.binding.tagBits;
+ }
+ return this.actualMethodBinding;
+ }
}
class IncongruentLambdaException extends RuntimeException {
private static final long serialVersionUID = 4145723509219836114L;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
index 6dc9e6be58..b80d1b8bc5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
@@ -81,6 +81,7 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
}
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+ this.actualMethodBinding = this.binding; // grab before synthetics come into play.
SourceTypeBinding sourceType = currentScope.enclosingSourceType();
if (this.receiverType.isArrayType()) {
if (isConstructorReference()) {
@@ -637,4 +638,10 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
tSam = t.getSingleAbstractMethod(this.enclosingScope);
return resultExpression.tIsMoreSpecific(tSam.returnType, sSam.returnType);
}
+
+ public org.eclipse.jdt.internal.compiler.lookup.MethodBinding getMethodBinding() {
+ if (this.actualMethodBinding == null) // array new/clone, no real binding.
+ this.actualMethodBinding = this.binding;
+ return this.actualMethodBinding;
+ }
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
index e1e37e880e..062758cd3e 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
@@ -883,7 +883,7 @@ class DefaultBindingResolver extends BindingResolver {
Object oldNode = this.newAstToOldAst.get(lambda);
if (oldNode instanceof org.eclipse.jdt.internal.compiler.ast.LambdaExpression) {
org.eclipse.jdt.internal.compiler.ast.LambdaExpression lambdaExpression = (org.eclipse.jdt.internal.compiler.ast.LambdaExpression) oldNode;
- IMethodBinding methodBinding = getMethodBinding(lambdaExpression.binding);
+ IMethodBinding methodBinding = getMethodBinding(lambdaExpression.getMethodBinding());
if (methodBinding == null) {
return null;
}
@@ -934,7 +934,7 @@ class DefaultBindingResolver extends BindingResolver {
Object oldNode = this.newAstToOldAst.get(methodReference);
if (oldNode instanceof org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) {
org.eclipse.jdt.internal.compiler.ast.ReferenceExpression referenceExpression = (org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) oldNode;
- IMethodBinding methodBinding = getMethodBinding(referenceExpression.binding);
+ IMethodBinding methodBinding = getMethodBinding(referenceExpression.getMethodBinding());
if (methodBinding == null) {
return null;
}
@@ -1166,7 +1166,7 @@ class DefaultBindingResolver extends BindingResolver {
return method.getReturnType();
} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) {
org.eclipse.jdt.internal.compiler.ast.ReferenceExpression referenceExpression = (org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) node;
- IMethodBinding method = getMethodBinding(referenceExpression.binding);
+ IMethodBinding method = getMethodBinding(referenceExpression.getMethodBinding());
if (method == null) return null;
return method.getReturnType();
}
@@ -1431,7 +1431,7 @@ class DefaultBindingResolver extends BindingResolver {
return getMethodBinding(memberValuePair.binding);
} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) {
org.eclipse.jdt.internal.compiler.ast.ReferenceExpression referenceExpression = (org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) node;
- return getMethodBinding(referenceExpression.binding);
+ return getMethodBinding(referenceExpression.getMethodBinding());
}
return null;
}

Back to the top