Fixed bug 478136: [1.8][clean up] Lambda rewriter removes annotations
from method
Change-Id: I6c0b4bf1cb4f625ee65ff1c8cba3707f33ace7e6
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 79dc1f4..350713e 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
@@ -36,6 +36,7 @@
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.ui.tests.core.Java18ProjectTestSetup;
+import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.text.correction.AssistContext;
@@ -943,6 +944,74 @@
assertExpectedExistInProposals(proposals, new String[] { expected1 });
}
+ public void testConvertToLambda19() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test;\n");
+ buf.append("public class C1 {\n");
+ buf.append(" Runnable r1 = new/*[1]*/ Runnable() {\n");
+ buf.append(" @Override @A @Deprecated\n");
+ buf.append(" public void run() {\n");
+ buf.append(" }\n");
+ buf.append(" };\n");
+ buf.append(" Runnable r2 = new/*[2]*/ Runnable() {\n");
+ buf.append(" @Override @Deprecated\n");
+ buf.append(" public void run() {\n");
+ buf.append(" }\n");
+ buf.append(" };\n");
+ buf.append("}\n");
+ buf.append("@interface A {}\n");
+ ICompilationUnit cu= pack1.createCompilationUnit("C1.java", buf.toString(), false, null);
+
+ int offset= buf.toString().indexOf("new/*[1]*/");
+ AssistContext context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ List<IJavaCompletionProposal> proposals= collectAssists(context, false);
+
+ assertNumberOfProposals(proposals, 1);
+ assertCorrectLabels(proposals);
+
+ StringBuffer buf1= new StringBuffer();
+ buf1.append("package test;\n");
+ buf1.append("public class C1 {\n");
+ buf1.append(" Runnable r1 = () -> {\n");
+ buf1.append(" };\n");
+ buf1.append(" Runnable r2 = new/*[2]*/ Runnable() {\n");
+ buf1.append(" @Override @Deprecated\n");
+ buf1.append(" public void run() {\n");
+ buf1.append(" }\n");
+ buf1.append(" };\n");
+ buf1.append("}\n");
+ buf1.append("@interface A {}\n");
+ String expected= buf1.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected });
+
+ offset= buf.toString().indexOf("new/*[2]*/");
+ context= getCorrectionContext(cu, offset, 0);
+ assertNoErrors(context);
+ proposals= collectAssists(context, false);
+
+ assertNumberOfProposals(proposals, 1);
+ assertCorrectLabels(proposals);
+
+ buf1= new StringBuffer();
+ buf1.append("package test;\n");
+ buf1.append("public class C1 {\n");
+ buf1.append(" Runnable r1 = new/*[1]*/ Runnable() {\n");
+ buf1.append(" @Override @A @Deprecated\n");
+ buf1.append(" public void run() {\n");
+ buf1.append(" }\n");
+ buf1.append(" };\n");
+ buf1.append(" Runnable r2 = () -> {\n");
+ buf1.append(" };\n");
+ buf1.append("}\n");
+ buf1.append("@interface A {}\n");
+ expected= buf1.toString();
+
+ assertExpectedExistInProposals(proposals, new String[] { expected });
+ }
+
public void testConvertToLambdaAmbiguousOverridden() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
StringBuffer buf= new StringBuffer();
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest18.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest18.java
index 46b67a3..825cc94 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest18.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest18.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013, 2014 IBM Corporation and others.
+ * Copyright (c) 2013, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -702,6 +702,46 @@
assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 });
}
+ public void testConvertToLambdaWithMethodAnnotations() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null);
+ StringBuffer buf= new StringBuffer();
+ buf.append("package test;\n");
+ buf.append("public class C1 {\n");
+ buf.append(" Runnable r1 = new Runnable() {\n");
+ buf.append(" @Override @A @Deprecated\n");
+ buf.append(" public void run() {\n");
+ buf.append(" }\n");
+ buf.append(" };\n");
+ buf.append(" Runnable r2 = new Runnable() {\n");
+ buf.append(" @Override @Deprecated\n");
+ buf.append(" public void run() {\n");
+ buf.append(" }\n");
+ buf.append(" };\n");
+ buf.append("}\n");
+ buf.append("@interface A {}\n");
+ String original= buf.toString();
+ ICompilationUnit cu1= pack1.createCompilationUnit("C1.java", original, false, null);
+
+ enable(CleanUpConstants.CONVERT_FUNCTIONAL_INTERFACES);
+ enable(CleanUpConstants.USE_LAMBDA);
+
+ buf= new StringBuffer();
+ buf.append("package test;\n");
+ buf.append("public class C1 {\n");
+ buf.append(" Runnable r1 = new Runnable() {\n");
+ buf.append(" @Override @A @Deprecated\n");
+ buf.append(" public void run() {\n");
+ buf.append(" }\n");
+ buf.append(" };\n");
+ buf.append(" Runnable r2 = () -> {\n");
+ buf.append(" };\n");
+ buf.append("}\n");
+ buf.append("@interface A {}\n");
+ String expected1= buf.toString();
+
+ assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 });
+ }
+
public void testConvertToAnonymousWithWildcards() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test", 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 2c7eb88..ee88eff 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
@@ -36,6 +36,7 @@
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ExpressionStatement;
+import org.eclipse.jdt.core.dom.IAnnotationBinding;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
@@ -89,7 +90,7 @@
@Override
public boolean visit(ClassInstanceCreation node) {
- if (isFunctionalAnonymous(node)) {
+ if (isFunctionalAnonymous(node) && !fConversionRemovesAnnotations) {
fNodes.add(node);
}
return true;
@@ -519,6 +520,8 @@
}
}
+ private static boolean fConversionRemovesAnnotations;
+
public static LambdaExpressionsFix createConvertToLambdaFix(ClassInstanceCreation cic) {
CompilationUnit root= (CompilationUnit) cic.getRoot();
if (!JavaModelUtil.is18OrHigher(root.getJavaElement().getJavaProject()))
@@ -609,10 +612,28 @@
if (!isInTargetTypeContext(node))
return false;
-
+
+ // Check if annotations other than @Override and @Deprecated will be removed
+ checkAnnotationsRemoval(methodBinding);
+
return true;
}
+ private static void checkAnnotationsRemoval(IMethodBinding methodBinding) {
+ fConversionRemovesAnnotations= false;
+ IAnnotationBinding[] declarationAnnotations= methodBinding.getAnnotations();
+ for (IAnnotationBinding declarationAnnotation : declarationAnnotations) {
+ ITypeBinding annotationType= declarationAnnotation.getAnnotationType();
+ if (annotationType != null) {
+ String qualifiedName= annotationType.getQualifiedName();
+ if (!"java.lang.Override".equals(qualifiedName) && !"java.lang.Deprecated".equals(qualifiedName)) { //$NON-NLS-1$ //$NON-NLS-2$
+ fConversionRemovesAnnotations= true;
+ return;
+ }
+ }
+ }
+ }
+
private static boolean isInTargetTypeContext(ClassInstanceCreation node) {
ITypeBinding targetType= ASTNodes.getTargetType(node);
return targetType != null && targetType.getFunctionalInterfaceMethod() != null;