[extract method] IDEA-313664: allow 'make static' for methods inside inner classes if language level supports this

GitOrigin-RevId: 3eba22a8685ecb6905a867ff68b9f96f7438140d
This commit is contained in:
Alexandr Suhinin
2023-03-02 09:12:52 +00:00
committed by intellij-monorepo-bot
parent 32638f1cae
commit 72af44b14d
7 changed files with 77 additions and 7 deletions
@@ -2,6 +2,7 @@
package com.intellij.refactoring.extractMethod.newImpl
import com.intellij.codeInsight.AnnotationUtil.*
import com.intellij.codeInsight.daemon.impl.analysis.HighlightingFeature
import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil
import com.intellij.codeInsight.daemon.impl.quickfix.AnonymousTargetClassPreselectionUtil
import com.intellij.codeInsight.navigation.PsiTargetNavigator
@@ -222,7 +223,8 @@ object ExtractMethodPipeline {
fun withForcedStatic(analyzer: CodeFragmentAnalyzer, extractOptions: ExtractOptions): ExtractOptions? {
val targetClass = PsiTreeUtil.getParentOfType(extractOptions.anchor, PsiClass::class.java)!!
if (PsiUtil.isLocalOrAnonymousClass(targetClass) || PsiUtil.isInnerClass(targetClass)) return null
val isInnerClass = PsiUtil.isLocalOrAnonymousClass(targetClass) || PsiUtil.isInnerClass(targetClass)
if (isInnerClass && !HighlightingFeature.INNER_STATICS.isAvailable(targetClass)) return null
val memberUsages = analyzer.findInstanceMemberUsages(targetClass, extractOptions.elements)
if (memberUsages.any(::isNotExtractableUsage)) return null
val addedParameters = memberUsages.groupBy(MemberUsage::member).entries
@@ -0,0 +1,8 @@
class X {
Runnable r = new Runnable() {
@Override
public void run() {
<selection>System.out.println("hello");</selection>
}
};
}
@@ -0,0 +1,8 @@
class X {
Runnable r = new Runnable() {
@Override
public void run() {
<selection>System.out.println("hello");</selection>
}
};
}
@@ -0,0 +1,12 @@
class X {
Runnable r = new Runnable() {
@Override
public void run() {
extracted();
}
private void extracted() {
System.out.println("hello");
}
};
}
@@ -0,0 +1,12 @@
class X {
Runnable r = new Runnable() {
@Override
public void run() {
extracted();
}
private static void extracted() {
System.out.println("hello");
}
};
}
@@ -5,9 +5,12 @@ import com.intellij.codeInsight.lookup.LookupManager
import com.intellij.codeInsight.template.impl.TemplateManagerImpl
import com.intellij.codeInsight.template.impl.TemplateState
import com.intellij.ide.DataManager
import com.intellij.ide.IdeEventQueue
import com.intellij.ide.IdePopupManager
import com.intellij.openapi.actionSystem.*
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.ui.popup.JBPopup
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.TextRange
import com.intellij.pom.java.LanguageLevel
@@ -20,6 +23,8 @@ import com.intellij.refactoring.listeners.RefactoringEventListener
import com.intellij.refactoring.util.CommonRefactoringUtil.RefactoringErrorHintException
import com.intellij.testFramework.IdeaTestUtil
import com.intellij.testFramework.LightJavaCodeInsightTestCase
import com.intellij.ui.UiInterceptors
import com.intellij.ui.UiInterceptors.UiInterceptor
import com.intellij.util.ui.UIUtil
import org.jetbrains.annotations.NonNls
@@ -326,9 +331,29 @@ class ExtractMethodAndDuplicatesInplaceTest: LightJavaCodeInsightTestCase() {
}
fun testIntroduceObjectInsideNestedClass(){
IdeEventQueue.getInstance().popupManager.closeAllPopups()
IdePopupManager().closeAllPopups()
doTest()
}
fun testMakeStaticInsideInner(){
UiInterceptors.register(DefaultChooserInterceptor)
doTest()
}
fun testMakeStaticInsideInnerFail(){
IdeaTestUtil.withLevel(module, LanguageLevel.JDK_15) {
UiInterceptors.register(DefaultChooserInterceptor)
doTest()
}
}
object DefaultChooserInterceptor: UiInterceptor<JBPopup>(JBPopup::class.java){
override fun doIntercept(component: JBPopup) {
component.closeOk(null)
}
}
fun testMakeStaticFailsWithClassUsage(){
JavaRefactoringSettings.getInstance().EXTRACT_STATIC_METHOD_AND_PASS_FIELDS = true
doTest()
@@ -26,6 +26,7 @@ import com.intellij.refactoring.extractMethod.PrepareFailedException;
import com.intellij.refactoring.extractMethod.newImpl.ExtractException;
import com.intellij.refactoring.extractMethod.newImpl.MethodExtractor;
import com.intellij.refactoring.util.duplicates.Match;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.LightJavaCodeInsightTestCase;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.IncorrectOperationException;
@@ -1440,12 +1441,14 @@ public class ExtractMethodNewTest extends LightJavaCodeInsightTestCase {
}
public void testNoStaticForInnerClass() {
try {
configureByFile(BASE_PATH + getTestName(false) + ".java");
performExtractMethod(true, true, getEditor(), getFile(), getProject(), false, null, true, null, null, null);
fail("Static modifier is forbidden inside inner classes");
} catch (PrepareFailedException e){
}
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_15, () -> {
try {
configureByFile(BASE_PATH + getTestName(false) + ".java");
performExtractMethod(true, true, getEditor(), getFile(), getProject(), false, null, true, null, null, null);
fail("Static modifier is forbidden inside inner classes");
} catch (PrepareFailedException ignored){
}
});
}
public void testStaticForNestedClass() throws Exception {