From 35a27be9303c03396ad58423202f56722fbd42e7 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Mon, 25 Apr 2016 13:03:58 +0200 Subject: [PATCH] move instance method: update method reference qualifier according to the method reference shape (IDEA-155147) --- .../MoveInstanceMethodProcessor.java | 22 ++++++++++++++++--- ...ForeignMethodReferenceWithTargetField.java | 15 +++++++++++++ ...nMethodReferenceWithTargetField.java.after | 16 ++++++++++++++ .../ParameterMethodReference.java | 15 +++++++++++++ .../ParameterMethodReference.java.after | 16 ++++++++++++++ .../ThisMethodReferenceWithTargetField.java | 15 +++++++++++++ ...sMethodReferenceWithTargetField.java.after | 16 ++++++++++++++ .../moveMethod/MoveInstanceMethodTest.java | 18 +++++++++++++++ .../refactoring/BaseRefactoringProcessor.java | 2 +- 9 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/refactoring/moveInstanceMethod/ForeignMethodReferenceWithTargetField.java create mode 100644 java/java-tests/testData/refactoring/moveInstanceMethod/ForeignMethodReferenceWithTargetField.java.after create mode 100644 java/java-tests/testData/refactoring/moveInstanceMethod/ParameterMethodReference.java create mode 100644 java/java-tests/testData/refactoring/moveInstanceMethod/ParameterMethodReference.java.after create mode 100644 java/java-tests/testData/refactoring/moveInstanceMethod/ThisMethodReferenceWithTargetField.java create mode 100644 java/java-tests/testData/refactoring/moveInstanceMethod/ThisMethodReferenceWithTargetField.java.after diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java index cf4bdba86dc9..842fae7f5526 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java @@ -23,6 +23,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Ref; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.javadoc.PsiDocTagValue; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.ClassInheritorsSearch; @@ -240,9 +241,24 @@ public class MoveInstanceMethodProcessor extends BaseRefactoringProcessor{ final PsiElement expression = ((MethodCallUsageInfo)usage).getMethodCallExpression(); if (expression instanceof PsiMethodCallExpression) { correctMethodCall((PsiMethodCallExpression)expression, false); - } else if (expression instanceof PsiMethodReferenceExpression) { - PsiExpression newQualifier = JavaPsiFacade.getInstance(myProject).getElementFactory().createExpressionFromText(myTargetVariable.getType().getCanonicalText(), null); - ((PsiMethodReferenceExpression)expression).setQualifierExpression(newQualifier); + } + else if (expression instanceof PsiMethodReferenceExpression) { + PsiMethodReferenceExpression methodReferenceExpression = (PsiMethodReferenceExpression)expression; + PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression(); + String exprText; + if (myTargetVariable instanceof PsiParameter || + qualifierExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifierExpression).resolve() == myMethod.getContainingClass()) { + exprText = myTargetVariable.getType().getCanonicalText(); + } + else if (qualifierExpression instanceof PsiReferenceExpression) { + exprText = qualifierExpression.getText() + "." + myTargetVariable.getName(); + } + else { + exprText = myTargetVariable.getName(); + } + PsiExpression newQualifier = JavaPsiFacade.getInstance(myProject).getElementFactory().createExpressionFromText(exprText, null); + ((PsiMethodReferenceExpression)expression).setQualifierExpression( + (PsiExpression)JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(newQualifier)); } } else if (usage instanceof JavadocUsageInfo) { diff --git a/java/java-tests/testData/refactoring/moveInstanceMethod/ForeignMethodReferenceWithTargetField.java b/java/java-tests/testData/refactoring/moveInstanceMethod/ForeignMethodReferenceWithTargetField.java new file mode 100644 index 000000000000..9ba08edda44d --- /dev/null +++ b/java/java-tests/testData/refactoring/moveInstanceMethod/ForeignMethodReferenceWithTargetField.java @@ -0,0 +1,15 @@ +import java.util.stream.Stream; + +class Test { + private static class Destination{ } + + private final Destination destination = new Destination(); + + public void main(Stream stream, Test ref){ + stream.filter(ref::notNull); + } + + private boolean notNull(String it) { + return it != null; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/moveInstanceMethod/ForeignMethodReferenceWithTargetField.java.after b/java/java-tests/testData/refactoring/moveInstanceMethod/ForeignMethodReferenceWithTargetField.java.after new file mode 100644 index 000000000000..bbf4b0d6e2e0 --- /dev/null +++ b/java/java-tests/testData/refactoring/moveInstanceMethod/ForeignMethodReferenceWithTargetField.java.after @@ -0,0 +1,16 @@ +import java.util.stream.Stream; + +class Test { + private static class Destination{ + private boolean notNull(String it) { + return it != null; + } + } + + private final Destination destination = new Destination(); + + public void main(Stream stream, Test ref){ + stream.filter(ref.destination::notNull); + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/moveInstanceMethod/ParameterMethodReference.java b/java/java-tests/testData/refactoring/moveInstanceMethod/ParameterMethodReference.java new file mode 100644 index 000000000000..5cbaddb3528e --- /dev/null +++ b/java/java-tests/testData/refactoring/moveInstanceMethod/ParameterMethodReference.java @@ -0,0 +1,15 @@ +import java.util.stream.Stream; + +class Test { + private static class Destination{ } + + private final Destination destination = new Destination(); + + public void main(Stream stream){ + stream.filter(this::notNull); + } + + private boolean notNull(Destination d) { + return d != null; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/moveInstanceMethod/ParameterMethodReference.java.after b/java/java-tests/testData/refactoring/moveInstanceMethod/ParameterMethodReference.java.after new file mode 100644 index 000000000000..61ff4a019980 --- /dev/null +++ b/java/java-tests/testData/refactoring/moveInstanceMethod/ParameterMethodReference.java.after @@ -0,0 +1,16 @@ +import java.util.stream.Stream; + +class Test { + private static class Destination{ + private boolean notNull() { + return this != null; + } + } + + private final Destination destination = new Destination(); + + public void main(Stream stream){ + stream.filter(Test.Destination::notNull); + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/moveInstanceMethod/ThisMethodReferenceWithTargetField.java b/java/java-tests/testData/refactoring/moveInstanceMethod/ThisMethodReferenceWithTargetField.java new file mode 100644 index 000000000000..9aa240796011 --- /dev/null +++ b/java/java-tests/testData/refactoring/moveInstanceMethod/ThisMethodReferenceWithTargetField.java @@ -0,0 +1,15 @@ +import java.util.stream.Stream; + +class Test { + private static class Destination{ } + + private final Destination destination = new Destination(); + + public void main(Stream stream){ + stream.filter(this::notNull); + } + + private boolean notNull(String it) { + return it != null; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/moveInstanceMethod/ThisMethodReferenceWithTargetField.java.after b/java/java-tests/testData/refactoring/moveInstanceMethod/ThisMethodReferenceWithTargetField.java.after new file mode 100644 index 000000000000..f5b9e4f73ed2 --- /dev/null +++ b/java/java-tests/testData/refactoring/moveInstanceMethod/ThisMethodReferenceWithTargetField.java.after @@ -0,0 +1,16 @@ +import java.util.stream.Stream; + +class Test { + private static class Destination{ + private boolean notNull(String it) { + return it != null; + } + } + + private final Destination destination = new Destination(); + + public void main(Stream stream){ + stream.filter(destination::notNull); + } + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/moveMethod/MoveInstanceMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/moveMethod/MoveInstanceMethodTest.java index dac6566623b0..c84324b6dd29 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/moveMethod/MoveInstanceMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/moveMethod/MoveInstanceMethodTest.java @@ -93,6 +93,24 @@ public class MoveInstanceMethodTest extends LightRefactoringTestCase { } } + public void testThisMethodReferenceWithTargetField() throws Exception { + doTest(false, 0); + } + + public void testForeignMethodReferenceWithTargetField() throws Exception { + doTest(false, 0); + } + + public void testParameterMethodReference() throws Exception { + try { + BaseRefactoringProcessor.ConflictsInTestsException.setTestIgnore(true); + doTest(true, 0); + } + finally { + BaseRefactoringProcessor.ConflictsInTestsException.setTestIgnore(false); + } + } + private void doTest(boolean isTargetParameter, final int targetIndex) throws Exception { doTest(isTargetParameter, targetIndex, null); } diff --git a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java index df91d3ea19fd..60b05dae04a7 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java +++ b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java @@ -566,7 +566,7 @@ public abstract class BaseRefactoringProcessor implements Runnable { } @TestOnly - static void setTestIgnore(boolean myIgnore) { + public static void setTestIgnore(boolean myIgnore) { myTestIgnore = myIgnore; }