Bug 540520 - Problem compiling annonymous inner class
Change-Id: Iba83100204a6ad6225dffb5f65dae889e8aecddf
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
index 2ac9f09..2ab5c9e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
@@ -39,7 +39,7 @@
public class LambdaExpressionsTest extends AbstractRegressionTest {
static {
- TESTS_NAMES = new String[] { "test449063"};
+// TESTS_NAMES = new String[] { "testBug540520"};
// TESTS_NUMBERS = new int[] { 50 };
// TESTS_RANGE = new int[] { 11, -1 };
}
@@ -6997,6 +6997,76 @@
""
);
}
+public void testBug540520() {
+ Runner runner = new Runner();
+ runner.testFiles = new String[] {
+ "Run.java",
+ "import java.util.ArrayList;\n" +
+ "import java.util.HashMap;\n" +
+ "import java.util.List;\n" +
+ "import java.util.Map;\n" +
+ "import java.util.stream.Collectors;\n" +
+ "\n" +
+ "public class Run {\n" +
+ "\n" +
+ " public static void main(String[] args) {\n" +
+ " \n" +
+ " List<TypeDeptCount> list = new ArrayList<>();\n" +
+ " for(int i=0;i<10;i++) {\n" +
+ " TypeDeptCount ty = new TypeDeptCount();\n" +
+ " ty.setCykbbm(\"10\"+i);\n" +
+ " ty.setCount(i);\n" +
+ " }\n" +
+ " List<Map<String, Object>> datas = list.stream().collect(Collectors.groupingBy(TypeDeptCount::getType))\n" +
+ " .entrySet().stream().map(item -> item.getValue().stream().reduce(new HashMap<String, Object>() {\n" +
+ " private static final long serialVersionUID = 1L;\n" +
+ " {\n" +
+ " put(\"count\", 0);\n" +
+ " put(\"type\", item.getKey());\n" +
+ " }\n" +
+ " }, (data1, val) -> {\n" +
+ " data1.put(val.getCykbbm(), val.getCount());\n" +
+ " data1.put(\"count\", (Integer) data1.get(\"count\") + val.getCount());\n" +
+ " return data1;\n" +
+ " }, (data1, data2) -> {\n" +
+ " data2.put(\"count\", (Integer) data1.get(\"count\") + (Integer) data2.get(\"count\"));\n" +
+ " data1.putAll(data2);\n" +
+ " return data1;\n" +
+ " })).sorted((item1, item2) -> (Integer) item2.get(\"count\") - (Integer) item1.get(\"count\"))\n" +
+ " .collect(Collectors.toList());\n" +
+ " System.out.println(datas);\n" +
+ " }\n" +
+ "}\n",
+ "TypeDeptCount.java",
+ "public class TypeDeptCount {\n" +
+ "\n" +
+ " private String type;\n" +
+ " private String cykbbm;\n" +
+ " private Integer count;\n" +
+ " \n" +
+ " public String getType() {\n" +
+ " return type;\n" +
+ " }\n" +
+ " public void setType(String type) {\n" +
+ " this.type = type;\n" +
+ " }\n" +
+ " public String getCykbbm() {\n" +
+ " return cykbbm;\n" +
+ " }\n" +
+ " public void setCykbbm(String cykbbm) {\n" +
+ " this.cykbbm = cykbbm;\n" +
+ " }\n" +
+ " public Integer getCount() {\n" +
+ " return count;\n" +
+ " }\n" +
+ " public void setCount(Integer count) {\n" +
+ " this.count = count;\n" +
+ " }\n" +
+ "}\n"
+ };
+ runner.runConformTest();
+
+}
public static Class testClass() {
return LambdaExpressionsTest.class;
}
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 4d6b5d5..3494069 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
@@ -1475,7 +1475,7 @@
if (((LambdaExpression) lambdaScope2.referenceContext).sourceStart == LambdaExpression.this.sourceStart) {
// local type within this lambda needs replacement:
TypeBinding substType = this.localTypes2.get(orgLocal.sourceStart);
- if (substType != null) {
+ if (substType != null && substType != orgLocal) { //$IDENTITY-COMPARISON$
orgLocal.transferConstantPoolNameTo(substType);
return substType;
}
@@ -1501,10 +1501,11 @@
/**
* Perform substitution with a {@link LocalTypeSubstitutor} on all types mentioned in the given method binding.
*/
- void updateLocalTypesInMethod(MethodBinding method) {
+ boolean updateLocalTypesInMethod(MethodBinding method) {
if (this.localTypes == null)
- return;
+ return false;
updateLocalTypesInMethod(method, new LocalTypeSubstitutor(this.localTypes), new NullSubstitution(this.scope.environment()));
+ return true;
}
private void updateLocalTypesInMethod(MethodBinding method, Substitutor substor, Substitution subst) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
index 78f4eea..d5b9f6f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
@@ -358,6 +358,11 @@
if (methodType == null)
return;
+ if (methodType.isProperType(true) && lambda != null) {
+ // ensure that type conversions don't leak a preliminary local type:
+ if (lambda.updateLocalTypesInMethod(lambda.descriptor))
+ methodType = lambda.expectedResultType();
+ }
if (TypeBinding.notEquals(methodType, expressionType)) // must call before computeConversion() and typeMismatchError()
scope.compilationUnitScope().recordTypeConversion(methodType, expressionType);
if (this.expression.isConstantValueOfTypeAssignableToType(expressionType, methodType)