From 9f3fdd9a7ec4aad3e315ce0f3a93401e1dcfbdb8 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 30 Jun 2016 12:43:51 +0300 Subject: [PATCH] lambda -> anonym: qualify without making expressions invalid (IDEA-157725) --- .../ReplaceLambdaWithAnonymousInspection.java | 24 +++++++++----- .../QualifyThisAndSuperInside.after.java | 33 +++++++++++++++++++ .../QualifyThisAndSuperInside.java | 28 ++++++++++++++++ .../ReplaceLambdaWithAnonymousFixTest.java | 4 +++ 4 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/style/lambda2anonymous/QualifyThisAndSuperInside.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/style/lambda2anonymous/QualifyThisAndSuperInside.java diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/ReplaceLambdaWithAnonymousInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/ReplaceLambdaWithAnonymousInspection.java index c8c4beb6f2f8..6233797e070e 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/ReplaceLambdaWithAnonymousInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/ReplaceLambdaWithAnonymousInspection.java @@ -37,8 +37,7 @@ import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.List; -import java.util.Map; +import java.util.*; public class ReplaceLambdaWithAnonymousInspection extends BaseInspection { private static final Logger LOG = Logger.getInstance("#" + ReplaceLambdaWithAnonymousInspection.class.getName()); @@ -123,7 +122,7 @@ public class ReplaceLambdaWithAnonymousInspection extends BaseInspection { final PsiThisExpression thisAccessExpr = thisClass instanceof PsiAnonymousClass ? null : RefactoringChangeUtil .createThisExpression(lambdaExpression.getManager(), thisClass); ChangeContextUtil.decodeContextInfo(blockFromText, thisClass, thisAccessExpr); - final Map replacements = new HashMap(); + final Set replacements = new HashSet<>(); blockFromText.accept(new JavaRecursiveElementWalkingVisitor() { @Override public void visitClass(PsiClass aClass) {} @@ -132,7 +131,7 @@ public class ReplaceLambdaWithAnonymousInspection extends BaseInspection { public void visitSuperExpression(PsiSuperExpression expression) { super.visitSuperExpression(expression); if (expression.getQualifier() == null) { - replacements.put(expression, psiElementFactory.createExpressionFromText(thisClassName + "." + expression.getText(), expression)); + replacements.add(expression); } } @@ -141,14 +140,23 @@ public class ReplaceLambdaWithAnonymousInspection extends BaseInspection { super.visitMethodCallExpression(expression); if (thisAccessExpr != null) { final PsiMethod psiMethod = expression.resolveMethod(); - if (psiMethod != null && !psiMethod.hasModifierProperty(PsiModifier.STATIC) && expression.getMethodExpression().getQualifierExpression() == null) { - replacements.put(expression, psiElementFactory.createExpressionFromText(thisAccessExpr.getText() + "." + expression.getText(), expression)); + final PsiReferenceExpression methodExpression = expression.getMethodExpression(); + if (psiMethod != null && !psiMethod.hasModifierProperty(PsiModifier.STATIC) && methodExpression.getQualifierExpression() == null) { + replacements.add(expression); } } } }); - for (PsiElement psiElement : replacements.keySet()) { - psiElement.replace(replacements.get(psiElement)); + for (PsiExpression expression : replacements) { + if (expression instanceof PsiSuperExpression) { + expression.replace(psiElementFactory.createExpressionFromText(thisClassName + "." + expression.getText(), expression)); + } + else if (expression instanceof PsiMethodCallExpression) { + ((PsiMethodCallExpression)expression).getMethodExpression().setQualifierExpression(thisAccessExpr); + } + else { + LOG.error("Unexpected expression"); + } } } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/lambda2anonymous/QualifyThisAndSuperInside.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/lambda2anonymous/QualifyThisAndSuperInside.after.java new file mode 100644 index 000000000000..34783f9e3632 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/lambda2anonymous/QualifyThisAndSuperInside.after.java @@ -0,0 +1,33 @@ +class T { + static class A { + final String n; + + A(String n) { + this.n = n; + } + + void f(String s) { + System.out.println(s + " " + n); + } + } + + static class B extends A { + B(String n) { + super(n); + } + + void f2(String s) { + new Thread(new Runnable() { + @Override + public void run() { + B.this.f(s + " " + B.super.n); + } + }).start(); + } + } + + public static void main(String[] args) { + new A("a").f("run"); + new B("b").f2("run"); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/lambda2anonymous/QualifyThisAndSuperInside.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/lambda2anonymous/QualifyThisAndSuperInside.java new file mode 100644 index 000000000000..a82803559346 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/lambda2anonymous/QualifyThisAndSuperInside.java @@ -0,0 +1,28 @@ +class T { + static class A { + final String n; + + A(String n) { + this.n = n; + } + + void f(String s) { + System.out.println(s + " " + n); + } + } + + static class B extends A { + B(String n) { + super(n); + } + + void f2(String s) { + new Thread(() -> f(s + " " + super.n)).start(); + } + } + + public static void main(String[] args) { + new A("a").f("run"); + new B("b").f2("run"); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/style/ReplaceLambdaWithAnonymousFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/style/ReplaceLambdaWithAnonymousFixTest.java index 6176e78ed151..ed9a8b544444 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/style/ReplaceLambdaWithAnonymousFixTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/style/ReplaceLambdaWithAnonymousFixTest.java @@ -87,6 +87,10 @@ public class ReplaceLambdaWithAnonymousFixTest extends IGQuickFixesTestCase { doTest(); } + public void testQualifyThisAndSuperInside() throws Exception { + doTest(); + } + public void testStaticCalls() { doTest(); }