From e2d6fcdffd5c7037dc6edd1e5358c2ae853ba22b Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 14 Apr 2022 08:57:22 +0200 Subject: [PATCH] [java] inline super class: allow to inline super calls in "foreign" methods (IDEA-291915) GitOrigin-RevId: ade765200f9e93ead924225bb8824f54697bd6b4 --- .../InlineSuperClassRefactoringProcessor.java | 2 +- .../memberPushDown/JavaPushDownDelegate.java | 28 ++++++++-------- .../memberPushDown/PushDownConflicts.java | 32 +++++-------------- .../abstractOverrides/before/Super.java | 2 +- .../abstractOverrides/before/Test.java | 2 +- .../inlineOneClass/after/Super.java | 2 +- .../inlineOneClass/before/Super.java | 2 +- .../inlineOneClass/before/Test.java | 2 +- .../multipleSuperCalls/after/Test.java | 20 ++++++++++++ .../multipleSuperCalls/before/Test.java | 20 ++++++++++++ .../refactoring/InlineSuperClassTest.java | 1 + 11 files changed, 69 insertions(+), 44 deletions(-) create mode 100644 java/java-tests/testData/refactoring/inlineSuperClass/multipleSuperCalls/after/Test.java create mode 100644 java/java-tests/testData/refactoring/inlineSuperClass/multipleSuperCalls/before/Test.java diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java b/java/java-impl-refactorings/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java index 76f572fedf43..ec6254694cea 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java @@ -160,7 +160,7 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori if (element instanceof PsiReferenceExpression && ((PsiReferenceExpression)element).getQualifierExpression() instanceof PsiSuperExpression && PsiTreeUtil.isAncestor(targetClass, element, false) && - !PushDownConflicts.isSuperCallToBeInlined(member, targetClass, mySuperClass, element)) { + !PushDownConflicts.isSuperCallToBeInlined(member, targetClass, mySuperClass)) { usages.add(new RemoveQualifierUsageInfo((PsiReferenceExpression)element)); } } diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/memberPushDown/JavaPushDownDelegate.java b/java/java-impl-refactorings/src/com/intellij/refactoring/memberPushDown/JavaPushDownDelegate.java index a6ede45a8ff9..02615c3e2995 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/memberPushDown/JavaPushDownDelegate.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/memberPushDown/JavaPushDownDelegate.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.refactoring.memberPushDown; import com.intellij.codeInsight.AnnotationUtil; @@ -33,7 +33,6 @@ import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.refactoring.util.classMembers.MemberInfo; import com.intellij.util.IncorrectOperationException; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -344,18 +343,19 @@ public class JavaPushDownDelegate extends PushDownDelegate memberInfo, PsiMethod methodBySignature) { PsiMethod superMethod = (PsiMethod)memberInfo.getMember(); - Collection superReferences = - ReferencesSearch.search(superMethod, new LocalSearchScope(methodBySignature)).findAll(); - if (superReferences.size() == 1) { - PsiReference reference = ContainerUtil.getFirstItem(superReferences); - if (reference == null) return; - PsiElement element = reference.getElement(); - if (element instanceof PsiReferenceExpression) { - PsiReferenceExpression referenceExpression = (PsiReferenceExpression)element; - if (superMethod.getBody() != null) { - // No super method body: either native method or compilation error - new InlineMethodProcessor(element.getProject(), superMethod, referenceExpression, null, true) - .inlineMethodCall(referenceExpression); + PsiClass containingClass = methodBySignature.getContainingClass(); + if (containingClass != null) { + Collection superReferences = + ReferencesSearch.search(superMethod, new LocalSearchScope(containingClass)).findAll(); + for (PsiReference reference : superReferences) { + PsiElement element = reference.getElement(); + if (element instanceof PsiReferenceExpression) { + PsiReferenceExpression referenceExpression = (PsiReferenceExpression)element; + if (superMethod.getBody() != null) { + // No super method body: either native method or compilation error + new InlineMethodProcessor(element.getProject(), superMethod, referenceExpression, null, true) + .inlineMethodCall(referenceExpression); + } } } } diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/memberPushDown/PushDownConflicts.java b/java/java-impl-refactorings/src/com/intellij/refactoring/memberPushDown/PushDownConflicts.java index bfeda02b50f5..edf8c1325e2b 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/memberPushDown/PushDownConflicts.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/memberPushDown/PushDownConflicts.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.refactoring.memberPushDown; import com.intellij.codeInsight.AnnotationUtil; @@ -22,7 +8,10 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; -import com.intellij.psi.util.*; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.RefactoringConflictsUtil; @@ -58,10 +47,6 @@ public class PushDownConflicts { myConflicts = conflicts; } - public boolean isAnyConflicts() { - return !myConflicts.isEmpty(); - } - public MultiMap getConflicts() { return myConflicts; } @@ -157,7 +142,7 @@ public class PushDownConflicts { if (myConflicts.containsKey(element)) continue; final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)element; final PsiExpression qualifier = referenceExpression.getQualifierExpression(); - if (qualifier instanceof PsiSuperExpression && isSuperCallToBeInlined(member, targetClass, myClass, element)) continue; + if (qualifier instanceof PsiSuperExpression && isSuperCallToBeInlined(member, targetClass, myClass)) continue; if (qualifier != null) { final PsiType qualifierType = qualifier.getType(); PsiClass aClass = null; @@ -238,14 +223,13 @@ public class PushDownConflicts { public static boolean isSuperCallToBeInlined(PsiMember member, PsiClass targetClass, - PsiClass sourceClass, - PsiElement referenceOnSuper) { + PsiClass sourceClass) { if (member instanceof PsiMethod) { PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(sourceClass, targetClass, PsiSubstitutor.EMPTY); PsiMethod methodInTarget = MethodSignatureUtil.findMethodBySuperSignature(targetClass, ((PsiMethod)member).getSignature(substitutor), true); - return methodInTarget != null && PsiTreeUtil.isAncestor(methodInTarget, referenceOnSuper, false); + return methodInTarget != null && targetClass.equals(methodInTarget.getContainingClass()); } return false; } diff --git a/java/java-tests/testData/refactoring/inlineSuperClass/abstractOverrides/before/Super.java b/java/java-tests/testData/refactoring/inlineSuperClass/abstractOverrides/before/Super.java index 3e91df260046..38fa30500280 100644 --- a/java/java-tests/testData/refactoring/inlineSuperClass/abstractOverrides/before/Super.java +++ b/java/java-tests/testData/refactoring/inlineSuperClass/abstractOverrides/before/Super.java @@ -1,3 +1,3 @@ abstract class Super { - public abstract void method() {} + public abstract void method(); } \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineSuperClass/abstractOverrides/before/Test.java b/java/java-tests/testData/refactoring/inlineSuperClass/abstractOverrides/before/Test.java index 2b8fb60a05cf..1d2d8c53f8d1 100644 --- a/java/java-tests/testData/refactoring/inlineSuperClass/abstractOverrides/before/Test.java +++ b/java/java-tests/testData/refactoring/inlineSuperClass/abstractOverrides/before/Test.java @@ -1,6 +1,6 @@ class Test extends Super{ public void context() { - super.method(); + method(); } @Override diff --git a/java/java-tests/testData/refactoring/inlineSuperClass/inlineOneClass/after/Super.java b/java/java-tests/testData/refactoring/inlineSuperClass/inlineOneClass/after/Super.java index 3e91df260046..38fa30500280 100644 --- a/java/java-tests/testData/refactoring/inlineSuperClass/inlineOneClass/after/Super.java +++ b/java/java-tests/testData/refactoring/inlineSuperClass/inlineOneClass/after/Super.java @@ -1,3 +1,3 @@ abstract class Super { - public abstract void method() {} + public abstract void method(); } \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineSuperClass/inlineOneClass/before/Super.java b/java/java-tests/testData/refactoring/inlineSuperClass/inlineOneClass/before/Super.java index 3e91df260046..38fa30500280 100644 --- a/java/java-tests/testData/refactoring/inlineSuperClass/inlineOneClass/before/Super.java +++ b/java/java-tests/testData/refactoring/inlineSuperClass/inlineOneClass/before/Super.java @@ -1,3 +1,3 @@ abstract class Super { - public abstract void method() {} + public abstract void method(); } \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineSuperClass/inlineOneClass/before/Test.java b/java/java-tests/testData/refactoring/inlineSuperClass/inlineOneClass/before/Test.java index 5fe8937f4a15..fb37b6060bc1 100644 --- a/java/java-tests/testData/refactoring/inlineSuperClass/inlineOneClass/before/Test.java +++ b/java/java-tests/testData/refactoring/inlineSuperClass/inlineOneClass/before/Test.java @@ -1,6 +1,6 @@ class Test extends Super{ public void context() { - super.method(); + method(); } @Override diff --git a/java/java-tests/testData/refactoring/inlineSuperClass/multipleSuperCalls/after/Test.java b/java/java-tests/testData/refactoring/inlineSuperClass/multipleSuperCalls/after/Test.java new file mode 100644 index 000000000000..69b9dad5d460 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineSuperClass/multipleSuperCalls/after/Test.java @@ -0,0 +1,20 @@ +class Super { + boolean add(Integer key, String value) { + System.out.println("0"); + return true; + } +} + + +class Test { + boolean add(Integer key, String value) { + System.out.println("1"); + System.out.println("0"); + return true; + } + + void assign(Integer key, String value) { + System.out.println("2"); + System.out.println("0"); + } +} diff --git a/java/java-tests/testData/refactoring/inlineSuperClass/multipleSuperCalls/before/Test.java b/java/java-tests/testData/refactoring/inlineSuperClass/multipleSuperCalls/before/Test.java new file mode 100644 index 000000000000..5270dc376382 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineSuperClass/multipleSuperCalls/before/Test.java @@ -0,0 +1,20 @@ +class Super { + boolean add(Integer key, String value) { + System.out.println("0"); + return true; + } +} + + +class Test extends Super { + @Override + boolean add(Integer key, String value) { + System.out.println("1"); + return super.add(key, value); + } + + void assign(Integer key, String value) { + System.out.println("2"); + super.add(key, value); + } +} diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/InlineSuperClassTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/InlineSuperClassTest.java index e64d37edbcb1..a9ae0f156212 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/InlineSuperClassTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/InlineSuperClassTest.java @@ -76,6 +76,7 @@ public class InlineSuperClassTest extends LightMultiFileTestCase { public void testSealedGrandParentNonSealedInheritor() { doTest(false, true); } public void testSealedParentInlineAll() { doTest(); } public void testMultipleSealedParents() { doTest(false, true); } + public void testMultipleSuperCalls() { doTest(false, true); } private void doTest() { doTest(false, false);