From afc3e23260ea789e9294cd230682284d5026cb34 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 23 Dec 2014 11:25:24 +0100 Subject: [PATCH] extract method: disable make static when extracting from default method; ensure static extracting from constant in interface (IDEA-134636) --- .../extractMethod/ExtractMethodProcessor.java | 49 ++++++++++++------- .../Method2InterfaceFromConstant.java | 3 ++ .../Method2InterfaceFromConstant_after.java | 10 ++++ .../Method2InterfaceFromStatic.java | 5 ++ .../Method2InterfaceFromStatic_after.java | 9 ++++ .../refactoring/ExtractMethodTest.java | 8 +++ 6 files changed, 66 insertions(+), 18 deletions(-) create mode 100644 java/java-tests/testData/refactoring/extractMethod/Method2InterfaceFromConstant.java create mode 100644 java/java-tests/testData/refactoring/extractMethod/Method2InterfaceFromConstant_after.java create mode 100644 java/java-tests/testData/refactoring/extractMethod/Method2InterfaceFromStatic.java create mode 100644 java/java-tests/testData/refactoring/extractMethod/Method2InterfaceFromStatic_after.java diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java index 6b3e2e709d13..7804e23aedd4 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java @@ -1339,7 +1339,10 @@ public class ExtractMethodProcessor implements MatchProvider { } if (myTargetClass.isInterface() && PsiUtil.isLanguageLevel8OrHigher(myTargetClass)) { - PsiUtil.setModifierProperty(newMethod, PsiModifier.DEFAULT, true); + final PsiMethod containingMethod = PsiTreeUtil.getParentOfType(myCodeFragmentMember, PsiMethod.class, false); + if (containingMethod != null && containingMethod.hasModifierProperty(PsiModifier.DEFAULT)) { + PsiUtil.setModifierProperty(newMethod, PsiModifier.DEFAULT, true); + } } return (PsiMethod)myStyleManager.reformat(newMethod); } @@ -1579,24 +1582,34 @@ public class ExtractMethodProcessor implements MatchProvider { myStatic = shouldBeStatic(); final Set fields = new LinkedHashSet(); if (!PsiUtil.isLocalOrAnonymousClass(myTargetClass) && (myTargetClass.getContainingClass() == null || myTargetClass.hasModifierProperty(PsiModifier.STATIC))) { - ElementNeedsThis needsThis = new ElementNeedsThis(myTargetClass) { - @Override - protected void visitClassMemberReferenceElement(PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) { - if (classMember instanceof PsiField && !classMember.hasModifierProperty(PsiModifier.STATIC)) { - final PsiExpression expression = PsiTreeUtil.getParentOfType(classMemberReference, PsiExpression.class, false); - if (expression == null || !PsiUtil.isAccessedForWriting(expression)) { - fields.add((PsiField)classMember); - return; - } - } - super.visitClassMemberReferenceElement(classMember, classMemberReference); - } - }; - for (int i = 0; i < myElements.length && !needsThis.usesMembers(); i++) { - PsiElement element = myElements[i]; - element.accept(needsThis); + boolean canBeStatic = true; + if (myTargetClass.isInterface()) { + final PsiMethod containingMethod = PsiTreeUtil.getParentOfType(myCodeFragmentMember, PsiMethod.class, false); + canBeStatic = containingMethod == null || containingMethod.hasModifierProperty(PsiModifier.STATIC); + } + if (canBeStatic) { + ElementNeedsThis needsThis = new ElementNeedsThis(myTargetClass) { + @Override + protected void visitClassMemberReferenceElement(PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) { + if (classMember instanceof PsiField && !classMember.hasModifierProperty(PsiModifier.STATIC)) { + final PsiExpression expression = PsiTreeUtil.getParentOfType(classMemberReference, PsiExpression.class, false); + if (expression == null || !PsiUtil.isAccessedForWriting(expression)) { + fields.add((PsiField)classMember); + return; + } + } + super.visitClassMemberReferenceElement(classMember, classMemberReference); + } + }; + for (int i = 0; i < myElements.length && !needsThis.usesMembers(); i++) { + PsiElement element = myElements[i]; + element.accept(needsThis); + } + myCanBeStatic = !needsThis.usesMembers(); + } + else { + myCanBeStatic = false; } - myCanBeStatic = !needsThis.usesMembers(); } else { myCanBeStatic = false; diff --git a/java/java-tests/testData/refactoring/extractMethod/Method2InterfaceFromConstant.java b/java/java-tests/testData/refactoring/extractMethod/Method2InterfaceFromConstant.java new file mode 100644 index 000000000000..3ea40ddcabfd --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/Method2InterfaceFromConstant.java @@ -0,0 +1,3 @@ +interface I { + String FOO = "hello"; +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethod/Method2InterfaceFromConstant_after.java b/java/java-tests/testData/refactoring/extractMethod/Method2InterfaceFromConstant_after.java new file mode 100644 index 000000000000..fc47db84d46e --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/Method2InterfaceFromConstant_after.java @@ -0,0 +1,10 @@ +import org.jetbrains.annotations.NotNull; + +interface I { + String FOO = newMethod(); + + @NotNull + private static String newMethod() { + return "hello"; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethod/Method2InterfaceFromStatic.java b/java/java-tests/testData/refactoring/extractMethod/Method2InterfaceFromStatic.java new file mode 100644 index 000000000000..1272d81384aa --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/Method2InterfaceFromStatic.java @@ -0,0 +1,5 @@ +interface I { + static void foo () { + System.out.println("hello"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethod/Method2InterfaceFromStatic_after.java b/java/java-tests/testData/refactoring/extractMethod/Method2InterfaceFromStatic_after.java new file mode 100644 index 000000000000..ba4666f11485 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/Method2InterfaceFromStatic_after.java @@ -0,0 +1,9 @@ +interface I { + static void foo () { + newMethod(); + } + + private static void newMethod() { + System.out.println("hello"); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java index 220956b56aa4..327ab42363f3 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java @@ -581,6 +581,14 @@ public class ExtractMethodTest extends LightCodeInsightTestCase { public void testMethod2Interface() throws Exception { doTest(); } + + public void testMethod2InterfaceFromStatic() throws Exception { + doTest(); + } + + public void testMethod2InterfaceFromConstant() throws Exception { + doTest(); + } public void testParamDetection() throws Exception { doTest();