diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java index d281efae7603..595bbd97e14e 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java @@ -227,16 +227,18 @@ public class InlineConstantFieldProcessor extends BaseRefactoringProcessor { initializer.accept(collector); HashSet referencedWithVisibility = collector.myReferencedMembers; - boolean dependsOnContext = false; if (!myField.hasInitializer()) { + boolean dependsOnContext; PsiMethod[] constructors = Objects.requireNonNull(myField.getContainingClass()).getConstructors(); if (constructors.length == 1) { + Ref reference = new Ref<>(); dependsOnContext = !PsiTreeUtil.processElements(initializer, element -> { - if (element instanceof PsiReferenceExpression && - ((PsiReferenceExpression)element).getQualifierExpression() == null) { - PsiElement resolve = ((PsiReferenceExpression)element).resolve(); - if (resolve == null || - PsiTreeUtil.isAncestor(constructors[0], resolve, true)) { + if (element instanceof PsiJavaCodeReferenceElement) { + PsiElement resolve = ((PsiJavaCodeReferenceElement)element).resolve(); + if (resolve != null && + PsiTreeUtil.isAncestor(constructors[0], resolve, true) && + !PsiTreeUtil.isAncestor(initializer, resolve, true)) { + reference.set(resolve); return false; } } @@ -247,6 +249,7 @@ public class InlineConstantFieldProcessor extends BaseRefactoringProcessor { PsiElement element = usageInfo.getElement(); if (element != null && !PsiTreeUtil.isAncestor(constructors[0], element, true)) { conflicts.putValue(element, JavaRefactoringBundle.message("inline.field.initializer.is.not.accessible", + RefactoringUIUtil.getDescription(reference.get(), false), RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true))); } } diff --git a/java/java-tests/testData/refactoring/inlineConstantField/FieldInitializedLocalClass.java b/java/java-tests/testData/refactoring/inlineConstantField/FieldInitializedLocalClass.java new file mode 100644 index 000000000000..d9bcbe3ee118 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineConstantField/FieldInitializedLocalClass.java @@ -0,0 +1,12 @@ +class Test { + private final int myA; + + Test() { + class Local {} + myA = new Local().hashCode(); + } + + void test() { + System.out.println(myA); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineConstantField/FieldInitializedWithLambda.java b/java/java-tests/testData/refactoring/inlineConstantField/FieldInitializedWithLambda.java new file mode 100644 index 000000000000..5e1ee9a3f744 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineConstantField/FieldInitializedWithLambda.java @@ -0,0 +1,17 @@ +interface Consumer { + void accept(T t); +} + +class Test { + class X { + final Consumer myConsumer; + + X() { + myConsumer = s -> System.out.println(s); + } + + void test() { + myConsumer.accept("1"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineConstantField/FieldInitializedWithLambda.java.after b/java/java-tests/testData/refactoring/inlineConstantField/FieldInitializedWithLambda.java.after new file mode 100644 index 000000000000..8358feecc337 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineConstantField/FieldInitializedWithLambda.java.after @@ -0,0 +1,15 @@ +interface Consumer { + void accept(T t); +} + +class Test { + class X { + + X() { + } + + void test() { + ((Consumer) s -> System.out.println(s)).accept("1"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/inline/InlineConstantFieldTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/inline/InlineConstantFieldTest.java index 67ffbc688680..55fab8f3cc60 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/inline/InlineConstantFieldTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/inline/InlineConstantFieldTest.java @@ -88,7 +88,11 @@ public class InlineConstantFieldTest extends LightRefactoringTestCase { } public void testFieldInitializedWithParameter() { - doTestConflict("Field initializer is not accessible in method Test.test()"); + doTestConflict("Field initializer refers to parameter a which is not accessible in method Test.test()"); + } + + public void testFieldInitializedLocalClass() { + doTestConflict("Field initializer refers to class Local which is not accessible in method Test.test()"); } public void testFieldInitializedWithParameter1() { @@ -99,6 +103,10 @@ public class InlineConstantFieldTest extends LightRefactoringTestCase { doTest(); } + public void testFieldInitializedWithLambda() { + doTest(); + } + public void testFieldUsedInJavadoc() { doTestConflict("Inlined field is used in javadoc"); } diff --git a/java/openapi/resources/messages/JavaRefactoringBundle.properties b/java/openapi/resources/messages/JavaRefactoringBundle.properties index 89df9bf73531..847b819388b6 100644 --- a/java/openapi/resources/messages/JavaRefactoringBundle.properties +++ b/java/openapi/resources/messages/JavaRefactoringBundle.properties @@ -291,6 +291,7 @@ inline.field.title=Inline Field inline.field.used.in.javadoc=Inlined field is used in javadoc inline.field.used.in.reflection=Inlined field is used reflectively inline.field.view.occurrences=Press {0} to go through {1} inlined occurrences +inline.field.initializer.is.not.accessible=Field initializer refers to {0} which is not accessible in {1} inline.local.unable.try.catch.warning.message=Unable to inline outside try/catch statement inline.local.used.as.resource.cannot.refactor.message=Variable is used as resource reference inline.local.variable.declared.outside.cannot.refactor.message=Variable is declared outside a code block @@ -776,5 +777,4 @@ replace.constructor.builder.error.selected.class.was.not.found=Selected class wa replace.constructor.factory.error.invalid.factory.method.name=''{0}'' is invalid factory method name replace.constructor.factory.error.factory.method.already.exists=Factory method {0} already exists and will be used instead of newly created. java.safe.delete.empty.callee.text=Callee text would be shown here -java.safe.delete.caller.text=Caller text with highlighted callee would be shown here -inline.field.initializer.is.not.accessible=Field initializer is not accessible in {0} +java.safe.delete.caller.text=Caller text with highlighted callee would be shown here \ No newline at end of file