diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java index 5ef0cc61e32e..d8decab47766 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java @@ -166,7 +166,7 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase } } - if (!validClass(myParentClass, editor)) { + if (!validClass(myParentClass, selectedExpr, editor)) { return true; } @@ -262,7 +262,7 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase return myParentClass; } - protected abstract boolean validClass(PsiClass parentClass, Editor editor); + protected abstract boolean validClass(PsiClass parentClass, PsiExpression selectedExpr, Editor editor); private static PsiElement getNormalizedAnchor(PsiElement anchorElement) { PsiElement child = anchorElement; diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/IntroduceConstantHandler.java b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/IntroduceConstantHandler.java index a3c16e868a03..a6c2313e6a31 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/IntroduceConstantHandler.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/IntroduceConstantHandler.java @@ -257,7 +257,7 @@ public class IntroduceConstantHandler extends BaseExpressionToFieldHandler imple } @Override - protected boolean validClass(PsiClass parentClass, Editor editor) { + protected boolean validClass(PsiClass parentClass, PsiExpression selectedExpr, Editor editor) { return true; } diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/IntroduceFieldHandler.java b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/IntroduceFieldHandler.java index 71ea3250c4fe..408b6f7833b7 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/IntroduceFieldHandler.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/IntroduceFieldHandler.java @@ -35,10 +35,17 @@ public class IntroduceFieldHandler extends BaseExpressionToFieldHandler implemen } @Override - protected boolean validClass(PsiClass parentClass, Editor editor) { - if (parentClass.isInterface() || parentClass.isRecord()) { - String message = RefactoringBundle.getCannotRefactorMessage( - JavaRefactoringBundle.message(parentClass.isRecord() ? "cannot.introduce.field.in.record" : "cannot.introduce.field.in.interface")); + protected boolean validClass(PsiClass parentClass, PsiExpression selectedExpr, Editor editor) { + if (parentClass.isInterface()) { + String message = RefactoringBundle.getCannotRefactorMessage(JavaRefactoringBundle.message("cannot.introduce.field.in.interface")); + CommonRefactoringUtil.showErrorHint(parentClass.getProject(), editor, message, getRefactoringNameText(), getHelpID()); + return false; + } + else if (parentClass.isRecord()) { + final PsiModifierListOwner staticParentElement = PsiUtil.getEnclosingStaticElement(selectedExpr, parentClass); + boolean declareStatic = staticParentElement != null; + if (declareStatic) return true; + String message = RefactoringBundle.getCannotRefactorMessage(JavaRefactoringBundle.message("cannot.introduce.field.in.record")); CommonRefactoringUtil.showErrorHint(parentClass.getProject(), editor, message, getRefactoringNameText(), getHelpID()); return false; } diff --git a/java/java-tests/testData/refactoring/introduceField/afterStaticFieldInRecord.java b/java/java-tests/testData/refactoring/introduceField/afterStaticFieldInRecord.java new file mode 100644 index 000000000000..88a014314afb --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceField/afterStaticFieldInRecord.java @@ -0,0 +1,6 @@ +record R() { + public static final String string = ""; + + private static void x(int i) { + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceField/beforeDisallowFieldInRecord.java b/java/java-tests/testData/refactoring/introduceField/beforeDisallowFieldInRecord.java new file mode 100644 index 000000000000..219aada97dce --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceField/beforeDisallowFieldInRecord.java @@ -0,0 +1,5 @@ +record R() { + private void x(int i) { + "" + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceField/beforeStaticFieldInRecord.java b/java/java-tests/testData/refactoring/introduceField/beforeStaticFieldInRecord.java new file mode 100644 index 000000000000..9e04ca854bd8 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceField/beforeStaticFieldInRecord.java @@ -0,0 +1,5 @@ +record R() { + private static void x(int i) { + "" + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceFieldInSameClassTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceFieldInSameClassTest.java index 13480765146e..fa2dcb6b4662 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceFieldInSameClassTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceFieldInSameClassTest.java @@ -116,6 +116,21 @@ public class IntroduceFieldInSameClassTest extends LightJavaCodeInsightTestCase } } + public void testDisallowFieldInRecord() { + configureByFile("beforeDisallowFieldInRecord.java"); + try { + performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, false); + fail("Should not proceed"); + } + catch (CommonRefactoringUtil.RefactoringErrorHintException e) { + assertEquals("Cannot perform refactoring.\nInstance fields are not allowed in a record.", e.getMessage()); + } + } + + public void testStaticFieldInRecord() { + doTest(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, true); + } + public void testAcceptIntroduceFieldFromExprInThisCall() { doTest(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, true); } diff --git a/java/openapi/resources/messages/JavaRefactoringBundle.properties b/java/openapi/resources/messages/JavaRefactoringBundle.properties index 92ebacd97658..31953370878e 100644 --- a/java/openapi/resources/messages/JavaRefactoringBundle.properties +++ b/java/openapi/resources/messages/JavaRefactoringBundle.properties @@ -57,8 +57,8 @@ auto.rename.module.entity=Java Module boolean.method.result=boolean method result can.t.restore.context.for.method.extraction=Can't restore context for method extraction cannot.find.or.create.destination.directory=Cannot find or create destination directory -cannot.introduce.field.in.interface=Instance fields are not allowed in the interface -cannot.introduce.field.in.record=Instance fields are not allowed in the record +cannot.introduce.field.in.interface=Non-constant fields are not allowed in an interface. +cannot.introduce.field.in.record=Instance fields are not allowed in a record. cannot.move=Cannot Move cannot.move.inner.class.0.into.itself=Cannot move inner class {0} into itself cannot.move.package.into.itself=Cannot move package into itself