From 5f10f7a6a5cef136ef2c0e5f6d98c0f369542135 Mon Sep 17 00:00:00 2001 From: joe Date: Wed, 14 May 2025 11:47:46 +0000 Subject: [PATCH] [java-refactorings] IDEA-372592 Fix anonymous to inner class conversion incorrectly converting already-qualified this expressions #IDEA-372592 fixed closes https://github.com/JetBrains/intellij-community/pull/3048 Merge-request: IJ-MR-162908 Merged-by: Bartek Pacia GitOrigin-RevId: 0ad34047e08bde4a4689e992768832863036fca0 --- .../AnonymousToInnerHandler.java | 44 ++++--------------- .../anonymousToInner/addThisQualifier.java | 9 ++++ .../addThisQualifierWithImplicitThis.java | 11 +++++ ...ddThisQualifierWithImplicitThis_after.java | 16 +++++++ .../addThisQualifier_after.java | 14 ++++++ .../anonymousToInner/outerThisQualifier.java | 12 +++++ .../outerThisQualifier_after.java | 17 +++++++ .../refactoring/AnonymousToInnerTest.java | 13 +++++- 8 files changed, 100 insertions(+), 36 deletions(-) create mode 100644 java/java-tests/testData/refactoring/anonymousToInner/addThisQualifier.java create mode 100644 java/java-tests/testData/refactoring/anonymousToInner/addThisQualifierWithImplicitThis.java create mode 100644 java/java-tests/testData/refactoring/anonymousToInner/addThisQualifierWithImplicitThis_after.java create mode 100644 java/java-tests/testData/refactoring/anonymousToInner/addThisQualifier_after.java create mode 100644 java/java-tests/testData/refactoring/anonymousToInner/outerThisQualifier.java create mode 100644 java/java-tests/testData/refactoring/anonymousToInner/outerThisQualifier_after.java diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerHandler.java b/java/java-impl-refactorings/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerHandler.java index 6cef0ae48a51..905853234668 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerHandler.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerHandler.java @@ -688,43 +688,17 @@ public class AnonymousToInnerHandler implements RefactoringActionHandlerOnPsiEle PsiMethodCallExpression methodCall = (PsiMethodCallExpression) ((PsiExpressionStatement) statement).getExpression(); PsiExpressionList exprList = methodCall.getArgumentList(); + final PsiThisExpression qualifiedThis = (PsiThisExpression) factory.createExpressionFromText("A.this", null); + final PsiJavaCodeReferenceElement targetClassRef = factory.createClassReferenceElement(myTargetClass); + PsiJavaCodeReferenceElement thisQualifier = qualifiedThis.getQualifier(); + assert thisQualifier != null; + thisQualifier.replace(targetClassRef); - { - final PsiThisExpression qualifiedThis = - (PsiThisExpression) factory.createExpressionFromText("A.this", null); - final PsiJavaCodeReferenceElement targetClassRef = factory.createClassReferenceElement(myTargetClass); - PsiJavaCodeReferenceElement thisQualifier = qualifiedThis.getQualifier(); - assert thisQualifier != null; - thisQualifier.replace(targetClassRef); - - for (PsiExpression expr : paramExpressions) { - ChangeContextUtil.encodeContextInfo(expr, true); - final PsiElement newExpr = exprList.add(expr); - ChangeContextUtil.decodeContextInfo(newExpr, myTargetClass, qualifiedThis); - } + for (PsiExpression expr : paramExpressions) { + ChangeContextUtil.encodeContextInfo(expr, true); + final PsiElement newExpr = exprList.add(expr); + ChangeContextUtil.decodeContextInfo(newExpr, myTargetClass, qualifiedThis); } - - class SupersConvertor extends JavaRecursiveElementVisitor { - @Override public void visitThisExpression(@NotNull PsiThisExpression expression) { - try { - final PsiThisExpression qualifiedThis = - (PsiThisExpression) factory.createExpressionFromText("A.this", null); - final PsiJavaCodeReferenceElement targetClassRef = factory.createClassReferenceElement(myTargetClass); - PsiJavaCodeReferenceElement thisQualifier = qualifiedThis.getQualifier(); - assert thisQualifier != null; - thisQualifier.replace(targetClassRef); - expression.replace(qualifiedThis); - } catch (IncorrectOperationException e) { - LOG.error(e); - } - } - - @Override public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) { - } - } - - final SupersConvertor supersConvertor = new SupersConvertor(); - methodCall.getArgumentList().accept(supersConvertor); } private void calculateTypeParametersToCreate () { diff --git a/java/java-tests/testData/refactoring/anonymousToInner/addThisQualifier.java b/java/java-tests/testData/refactoring/anonymousToInner/addThisQualifier.java new file mode 100644 index 000000000000..ec24ed415b77 --- /dev/null +++ b/java/java-tests/testData/refactoring/anonymousToInner/addThisQualifier.java @@ -0,0 +1,9 @@ +public class LocalClass { + public LocalClass(LocalClass o) { + } + + void test() { + new LocalClass(this) { + }; + } +} diff --git a/java/java-tests/testData/refactoring/anonymousToInner/addThisQualifierWithImplicitThis.java b/java/java-tests/testData/refactoring/anonymousToInner/addThisQualifierWithImplicitThis.java new file mode 100644 index 000000000000..bd714a31bbbb --- /dev/null +++ b/java/java-tests/testData/refactoring/anonymousToInner/addThisQualifierWithImplicitThis.java @@ -0,0 +1,11 @@ +public class LocalClass { + LocalClass field; + + public LocalClass(LocalClass o) { + } + + void test() { + new LocalClass(field) { + }; + } +} diff --git a/java/java-tests/testData/refactoring/anonymousToInner/addThisQualifierWithImplicitThis_after.java b/java/java-tests/testData/refactoring/anonymousToInner/addThisQualifierWithImplicitThis_after.java new file mode 100644 index 000000000000..96de8b85e39a --- /dev/null +++ b/java/java-tests/testData/refactoring/anonymousToInner/addThisQualifierWithImplicitThis_after.java @@ -0,0 +1,16 @@ +public class LocalClass { + LocalClass field; + + public LocalClass(LocalClass o) { + } + + void test() { + new MyClass(); + } + + private static class MyClass extends LocalClass { + public MyClass() { + super(LocalClass.this.field); + } + } +} diff --git a/java/java-tests/testData/refactoring/anonymousToInner/addThisQualifier_after.java b/java/java-tests/testData/refactoring/anonymousToInner/addThisQualifier_after.java new file mode 100644 index 000000000000..e4e2f2597ff7 --- /dev/null +++ b/java/java-tests/testData/refactoring/anonymousToInner/addThisQualifier_after.java @@ -0,0 +1,14 @@ +public class LocalClass { + public LocalClass(LocalClass o) { + } + + void test() { + new MyClass(); + } + + private static class MyClass extends LocalClass { + public MyClass() { + super(LocalClass.this); + } + } +} diff --git a/java/java-tests/testData/refactoring/anonymousToInner/outerThisQualifier.java b/java/java-tests/testData/refactoring/anonymousToInner/outerThisQualifier.java new file mode 100644 index 000000000000..170e23ba7d50 --- /dev/null +++ b/java/java-tests/testData/refactoring/anonymousToInner/outerThisQualifier.java @@ -0,0 +1,12 @@ +public class Test { + public Test(Test test) { + } + + private class Inner { + public void x() { + new Test(Test.this) { + + }; + } + } +} diff --git a/java/java-tests/testData/refactoring/anonymousToInner/outerThisQualifier_after.java b/java/java-tests/testData/refactoring/anonymousToInner/outerThisQualifier_after.java new file mode 100644 index 000000000000..0a1990ffc0c2 --- /dev/null +++ b/java/java-tests/testData/refactoring/anonymousToInner/outerThisQualifier_after.java @@ -0,0 +1,17 @@ +public class Test { + public Test(Test test) { + } + + private class Inner { + public void x() { + new MyClass(); + } + + private static class MyClass extends Test { + public MyClass() { + super(Test.this); + } + } + + } +} diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/AnonymousToInnerTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/AnonymousToInnerTest.java index 499648d6a8d4..99f16354d59b 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/AnonymousToInnerTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/AnonymousToInnerTest.java @@ -133,7 +133,18 @@ public class AnonymousToInnerTest extends LightJavaCodeInsightTestCase { public void testTypeParameterNotMentioned() { doTest("MyClass", true); } - + + public void testAddThisQualifier() { + doTest("MyClass", true); + } + + public void testAddThisQualifierWithImplicitThis() { + doTest("MyClass", true); + } + + public void testOuterThisQualifier() { + doTest("MyClass", true); + } private void doTest(final String newClassName, final boolean makeStatic) { configureByFile(TEST_ROOT + getTestName(true) + ".java");