Java: Fixed modifiers when extracting method from default or private method in interface (IDEA-211141)

This commit is contained in:
Pavel Dolgov
2019-04-18 15:38:04 +03:00
parent 0b05b96778
commit aa1b72ba7a
8 changed files with 103 additions and 10 deletions

View File

@@ -33,6 +33,7 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.*;
import com.intellij.psi.controlFlow.ControlFlow;
@@ -1634,18 +1635,34 @@ public class ExtractMethodProcessor implements MatchProvider {
throwsList.add(JavaPsiFacade.getElementFactory(myManager.getProject()).createReferenceElementByType(exception));
}
if (myTargetClass.isInterface() && PsiUtil.isLanguageLevel8OrHigher(myTargetClass)) {
final PsiMethod containingMethod = PsiTreeUtil.getParentOfType(myCodeFragmentMember, PsiMethod.class, false);
if (containingMethod != null && containingMethod.hasModifierProperty(PsiModifier.DEFAULT)) {
PsiUtil.setModifierProperty(newMethod, PsiModifier.DEFAULT, true);
}
PsiUtil.setModifierProperty(newMethod, PsiModifier.PUBLIC, false);
PsiUtil.setModifierProperty(newMethod, PsiModifier.PRIVATE, false);
PsiUtil.setModifierProperty(newMethod, PsiModifier.PROTECTED, false);
if (myTargetClass.isInterface()) {
updateModifiersInInterface(newMethod);
}
return (PsiMethod)myStyleManager.reformat(newMethod);
}
private void updateModifiersInInterface(PsiMethod newMethod) {
LanguageLevel languageLevel = PsiUtil.getLanguageLevel(myTargetClass);
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
if (!isStatic()) {
final PsiMethod containingMethod = PsiTreeUtil.getParentOfType(myCodeFragmentMember, PsiMethod.class, false);
if (containingMethod != null && containingMethod.hasModifierProperty(PsiModifier.DEFAULT)) {
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_9)) {
PsiUtil.setModifierProperty(newMethod, PsiModifier.PRIVATE, true); // don't increase the API surface
}
else {
PsiUtil.setModifierProperty(newMethod, PsiModifier.DEFAULT, true);
}
}
}
PsiUtil.setModifierProperty(newMethod, PsiModifier.PUBLIC, false);
PsiUtil.setModifierProperty(newMethod, PsiModifier.PROTECTED, false);
if (isStatic() || !languageLevel.isAtLeast(LanguageLevel.JDK_1_9)) {
PsiUtil.setModifierProperty(newMethod, PsiModifier.PRIVATE, false);
}
}
}
protected boolean defineVariablesForUnselectedParameters() {
return true;
}

View File

@@ -0,0 +1,8 @@
public interface FromDefaultMethodInInterface {
default void test(String a, String b) {
<selection>
String c = a + b;
System.out.println(c);
</selection>
}
}

View File

@@ -0,0 +1,12 @@
public interface FromDefaultMethodInInterface {
default void test(String a, String b) {
newMethod(a, b);
}
private void newMethod(String a, String b) {
String c = a + b;
System.out.println(c);
}
}

View File

@@ -0,0 +1,8 @@
public interface FromPrivateMethodInInterface {
private void test(String a, String b) {
<selection>
String c = a + b;
System.out.println(c);
</selection>
}
}

View File

@@ -0,0 +1,12 @@
public interface FromPrivateMethodInInterface {
private void test(String a, String b) {
newMethod(a, b);
}
private void newMethod(String a, String b) {
String c = a + b;
System.out.println(c);
}
}

View File

@@ -0,0 +1,8 @@
public interface FromStaticMethodInInterface {
static void test(String a, String b) {
<selection>
String c = a + b;
System.out.println(c);
</selection>
}
}

View File

@@ -0,0 +1,12 @@
public interface FromStaticMethodInInterface {
static void test(String a, String b) {
newMethod(a, b);
}
static void newMethod(String a, String b) {
String c = a + b;
System.out.println(c);
}
}

View File

@@ -263,10 +263,14 @@ public class ExtractMethodTest extends LightCodeInsightTestCase {
}
private void doTestWithJava17() throws Exception {
doTestWithLanguageLevel(LanguageLevel.JDK_1_7);
}
private void doTestWithLanguageLevel(LanguageLevel languageLevel) throws Exception {
LanguageLevelProjectExtension projectExtension = LanguageLevelProjectExtension.getInstance(getProject());
LanguageLevel oldLevel = projectExtension.getLanguageLevel();
try {
projectExtension.setLanguageLevel(LanguageLevel.JDK_1_7);
projectExtension.setLanguageLevel(languageLevel);
doTest();
}
finally {
@@ -701,7 +705,7 @@ public class ExtractMethodTest extends LightCodeInsightTestCase {
}
public void testMethod2Interface() throws Exception {
doTest();
doTestWithLanguageLevel(LanguageLevel.JDK_1_8);
}
public void testMethod2InterfaceFromStatic() throws Exception {
@@ -1367,6 +1371,18 @@ public class ExtractMethodTest extends LightCodeInsightTestCase {
doTest();
}
public void testFromDefaultMethodInInterface() throws Exception {
doTest();
}
public void testFromPrivateMethodInInterface() throws Exception {
doTest();
}
public void testFromStaticMethodInInterface() throws Exception {
doTest();
}
private void doTestDisabledParam() throws PrepareFailedException {
final CommonCodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject()).getCommonSettings(JavaLanguage.INSTANCE);
settings.ELSE_ON_NEW_LINE = true;