diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethod/newImpl/ExtractOptionsPipeline.kt b/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethod/newImpl/ExtractOptionsPipeline.kt
index a35dc1c24838..145fd48b3c70 100644
--- a/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethod/newImpl/ExtractOptionsPipeline.kt
+++ b/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethod/newImpl/ExtractOptionsPipeline.kt
@@ -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
diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/MakeStaticInsideInner.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/MakeStaticInsideInner.java
new file mode 100644
index 000000000000..39c55288103e
--- /dev/null
+++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/MakeStaticInsideInner.java
@@ -0,0 +1,8 @@
+class X {
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ System.out.println("hello");
+ }
+ };
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/MakeStaticInsideInnerFail.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/MakeStaticInsideInnerFail.java
new file mode 100644
index 000000000000..39c55288103e
--- /dev/null
+++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/MakeStaticInsideInnerFail.java
@@ -0,0 +1,8 @@
+class X {
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ System.out.println("hello");
+ }
+ };
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/MakeStaticInsideInnerFail_after.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/MakeStaticInsideInnerFail_after.java
new file mode 100644
index 000000000000..1bb43086c7ab
--- /dev/null
+++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/MakeStaticInsideInnerFail_after.java
@@ -0,0 +1,12 @@
+class X {
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ extracted();
+ }
+
+ private void extracted() {
+ System.out.println("hello");
+ }
+ };
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/MakeStaticInsideInner_after.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/MakeStaticInsideInner_after.java
new file mode 100644
index 000000000000..2788dd08b79b
--- /dev/null
+++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/MakeStaticInsideInner_after.java
@@ -0,0 +1,12 @@
+class X {
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ extracted();
+ }
+
+ private static void extracted() {
+ System.out.println("hello");
+ }
+ };
+}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodAndDuplicatesInplaceTest.kt b/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodAndDuplicatesInplaceTest.kt
index d55270aa0694..da8b8d8aa645 100644
--- a/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodAndDuplicatesInplaceTest.kt
+++ b/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodAndDuplicatesInplaceTest.kt
@@ -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::class.java){
+ override fun doIntercept(component: JBPopup) {
+ component.closeOk(null)
+ }
+ }
+
fun testMakeStaticFailsWithClassUsage(){
JavaRefactoringSettings.getInstance().EXTRACT_STATIC_METHOD_AND_PASS_FIELDS = true
doTest()
diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodNewTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodNewTest.java
index 530fb28ae235..6f8e254a9ca6 100644
--- a/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodNewTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodNewTest.java
@@ -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 {