diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest18.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest18.java index 8919cbf..4c770c1 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest18.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest18.java @@ -464,6 +464,190 @@ assertExpectedExistInProposals(proposals, new String[] { expected1 }); } + public void testConvertToLambda10() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("interface I {\n"); + buf.append(" int foo(String s);\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("interface J {\n"); + buf.append(" Integer foo(String s);\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("public class X {\n"); + buf.append(" static void goo(I i) { }\n"); + buf.append("\n"); + buf.append(" static void goo(J j) { }\n"); + buf.append("\n"); + buf.append(" public static void main(String[] args) {\n"); + buf.append(" goo(new I() {\n"); + buf.append(" @Override\n"); + buf.append(" public int foo(String s) {\n"); + buf.append(" return 0;\n"); + buf.append(" }\n"); + buf.append(" });\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("X.java", buf.toString(), false, null); + + int offset= buf.toString().indexOf("I()"); + AssistContext context= getCorrectionContext(cu, offset, 0); + assertNoErrors(context); + List proposals= collectAssists(context, false); + + assertNumberOfProposals(proposals, 2); + assertCorrectLabels(proposals); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("interface I {\n"); + buf.append(" int foo(String s);\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("interface J {\n"); + buf.append(" Integer foo(String s);\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("public class X {\n"); + buf.append(" static void goo(I i) { }\n"); + buf.append("\n"); + buf.append(" static void goo(J j) { }\n"); + buf.append("\n"); + buf.append(" public static void main(String[] args) {\n"); + buf.append(" goo((I) s -> 0);\n"); + buf.append(" }\n"); + buf.append("}\n"); + String expected1= buf.toString(); + + assertExpectedExistInProposals(proposals, new String[] { expected1 }); + } + + public void testConvertToLambda11() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("interface I {\n"); + buf.append(" int foo(String s);\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("interface J {\n"); + buf.append(" Integer foo(String s);\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("public class X extends Y {\n"); + buf.append(" static void goo(I i) { }\n"); + buf.append(" public static void main(String[] args) {\n"); + buf.append(" goo(new I() {\n"); + buf.append(" @Override\n"); + buf.append(" public int foo(String s) {\n"); + buf.append(" return 0;\n"); + buf.append(" }\n"); + buf.append(" });\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("class Y {\n"); + buf.append(" private static void goo(J j) { } \n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("X.java", buf.toString(), false, null); + + int offset= buf.toString().indexOf("I()"); + AssistContext context= getCorrectionContext(cu, offset, 0); + assertNoErrors(context); + List proposals= collectAssists(context, false); + + assertNumberOfProposals(proposals, 2); + assertCorrectLabels(proposals); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("interface I {\n"); + buf.append(" int foo(String s);\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("interface J {\n"); + buf.append(" Integer foo(String s);\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("public class X extends Y {\n"); + buf.append(" static void goo(I i) { }\n"); + buf.append(" public static void main(String[] args) {\n"); + buf.append(" goo(s -> 0);\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("class Y {\n"); + buf.append(" private static void goo(J j) { } \n"); + buf.append("}\n"); + String expected1= buf.toString(); + + assertExpectedExistInProposals(proposals, new String[] { expected1 }); + } + + public void testConvertToLambda12() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("interface I {\n"); + buf.append(" int foo(String s);\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("interface J {\n"); + buf.append(" Integer foo(String s);\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("public class X extends Y {\n"); + buf.append(" static void goo(I i) { }\n"); + buf.append(" public static void main(String[] args) {\n"); + buf.append(" goo(new I() {\n"); + buf.append(" @Override\n"); + buf.append(" public int foo(String s) {\n"); + buf.append(" return 0;\n"); + buf.append(" }\n"); + buf.append(" });\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("class Y {\n"); + buf.append(" static void goo(J j) { } \n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("X.java", buf.toString(), false, null); + + int offset= buf.toString().indexOf("I()"); + AssistContext context= getCorrectionContext(cu, offset, 0); + assertNoErrors(context); + List proposals= collectAssists(context, false); + + assertNumberOfProposals(proposals, 2); + assertCorrectLabels(proposals); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("interface I {\n"); + buf.append(" int foo(String s);\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("interface J {\n"); + buf.append(" Integer foo(String s);\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("public class X extends Y {\n"); + buf.append(" static void goo(I i) { }\n"); + buf.append(" public static void main(String[] args) {\n"); + buf.append(" goo((I) s -> 0);\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("class Y {\n"); + buf.append(" static void goo(J j) { } \n"); + buf.append("}\n"); + String expected1= buf.toString(); + + assertExpectedExistInProposals(proposals, new String[] { expected1 }); + } + public void testConvertToAnonymousClassCreation1() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); StringBuffer buf= new StringBuffer(); diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/LambdaExpressionsFix.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/LambdaExpressionsFix.java index 2412b9f..968464a 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/LambdaExpressionsFix.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/LambdaExpressionsFix.java @@ -27,16 +27,11 @@ import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; -import org.eclipse.jdt.core.dom.ArrayInitializer; -import org.eclipse.jdt.core.dom.Assignment; import org.eclipse.jdt.core.dom.Block; import org.eclipse.jdt.core.dom.BodyDeclaration; import org.eclipse.jdt.core.dom.CastExpression; import org.eclipse.jdt.core.dom.ClassInstanceCreation; import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.ConditionalExpression; -import org.eclipse.jdt.core.dom.ConstructorInvocation; -import org.eclipse.jdt.core.dom.EnumConstantDeclaration; import org.eclipse.jdt.core.dom.Expression; import org.eclipse.jdt.core.dom.ExpressionStatement; import org.eclipse.jdt.core.dom.IBinding; @@ -49,8 +44,6 @@ import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.Statement; -import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; -import org.eclipse.jdt.core.dom.SuperConstructorInvocation; import org.eclipse.jdt.core.dom.SuperFieldAccess; import org.eclipse.jdt.core.dom.SuperMethodInvocation; import org.eclipse.jdt.core.dom.ThisExpression; @@ -65,6 +58,7 @@ import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext; import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility2; import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; +import org.eclipse.jdt.internal.corext.dom.ASTNodes; import org.eclipse.jdt.internal.corext.dom.Bindings; import org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor; import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; @@ -75,7 +69,6 @@ import org.eclipse.jdt.ui.cleanup.ICleanUpFix; import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings; -import org.eclipse.jdt.internal.ui.text.correction.ASTResolving; public class LambdaExpressionsFix extends CompilationUnitRewriteOperationsFix { @@ -251,8 +244,17 @@ // lambdaBody.accept(new InterfaceAccessQualifier(rewrite, classInstanceCreation.getType().resolveBinding())); //TODO: maybe need a separate ASTRewrite and string placeholder lambdaExpression.setBody(rewrite.createCopyTarget(lambdaBody)); - rewrite.replace(classInstanceCreation, lambdaExpression, group); - + Expression replacement= lambdaExpression; + if (ASTNodes.isTargetAmbiguous(classInstanceCreation)) { + CastExpression cast= ast.newCastExpression(); + cast.setExpression(lambdaExpression); + ImportRewrite importRewrite= cuRewrite.getImportRewrite(); + ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(classInstanceCreation, importRewrite); + cast.setType(importRewrite.addImport(classInstanceCreation.getType().resolveBinding(), ast, importRewriteContext)); + replacement= cast; + } + rewrite.replace(classInstanceCreation, replacement, group); + importRemover.registerRemovedNode(classInstanceCreation); importRemover.registerRetainedNode(lambdaBody); } @@ -414,6 +416,10 @@ } private static boolean isInTargetTypeContext(ClassInstanceCreation node) { + ITypeBinding targetType= ASTNodes.getTargetType(node); + return targetType != null && targetType.isFunctionalInterface(); + + /* //TODO: probably incomplete, should reuse https://bugs.eclipse.org/bugs/show_bug.cgi?id=408966#c6 StructuralPropertyDescriptor locationInParent= node.getLocationInParent(); @@ -445,5 +451,6 @@ || locationInParent == ConditionalExpression.THEN_EXPRESSION_PROPERTY || locationInParent == ConditionalExpression.ELSE_EXPRESSION_PROPERTY || locationInParent == CastExpression.EXPRESSION_PROPERTY; - } + */ + } }