From 92fbca452dd7dec80d7984b0603545e6bd3ff433 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 8 Mar 2017 01:02:15 +0300 Subject: [PATCH] Move: Do not report conflict on usages of inherited protected members #KT-15190 Fixed --- .../move/moveDeclarations/moveConflictUtils.kt | 12 ++++++++++++ .../protectedMemberUsageWithSuper/after/a/test.kt | 6 ++++++ .../after/b/ProtectedChild.kt | 9 +++++++++ .../protectedMemberUsageWithSuper/after/b/dummy.txt | 0 .../protectedMemberUsageWithSuper/before/a/test.kt | 11 +++++++++++ .../protectedMemberUsageWithSuper/before/b/dummy.txt | 0 .../protectedMemberUsageWithSuper.test | 5 +++++ .../protectedMemberUsageWithThis/after/a/test.kt | 6 ++++++ .../after/b/ProtectedChild.kt | 10 ++++++++++ .../protectedMemberUsageWithThis/after/b/dummy.txt | 0 .../protectedMemberUsageWithThis/before/a/test.kt | 12 ++++++++++++ .../protectedMemberUsageWithThis/before/b/dummy.txt | 0 .../protectedMemberUsageWithThis.test | 5 +++++ .../idea/refactoring/move/MoveTestGenerated.java | 12 ++++++++++++ 14 files changed, 88 insertions(+) create mode 100644 idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/after/a/test.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/after/b/ProtectedChild.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/after/b/dummy.txt create mode 100644 idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/before/a/test.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/before/b/dummy.txt create mode 100644 idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/protectedMemberUsageWithSuper.test create mode 100644 idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/after/a/test.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/after/b/ProtectedChild.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/after/b/dummy.txt create mode 100644 idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/before/a/test.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/before/b/dummy.txt create mode 100644 idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/protectedMemberUsageWithThis.test diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/moveConflictUtils.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/moveConflictUtils.kt index 977788b6f2f..12932a68a52 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/moveConflictUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/moveConflictUtils.kt @@ -41,8 +41,11 @@ import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode +import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.kotlin.resolve.source.KotlinSourceElement +import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.utils.SmartSet import java.util.* @@ -232,6 +235,15 @@ class MoveConflictChecker( is PsiMember -> target.getJavaMemberDescriptor() else -> null } ?: return@forEach + if (targetDescriptor is CallableMemberDescriptor && + targetDescriptor.visibility.normalize() == Visibilities.PROTECTED) { + val resolvedCall = refExpr.getResolvedCall(refExpr.analyze(BodyResolveMode.PARTIAL)) ?: return@forEach + val dispatchReceiver = resolvedCall.dispatchReceiver + if (dispatchReceiver is ExpressionReceiver && dispatchReceiver.expression is KtSuperExpression) return@forEach + val receiverClass = resolvedCall.dispatchReceiver?.type?.constructor?.declarationDescriptor?.source?.getPsi() + if (receiverClass != null && receiverClass.isInsideOf(elementsToMove)) return@forEach + } + if (!targetDescriptor.isVisibleIn(targetContainer)) { val message = "${render(declaration)} uses ${render(target)} which will be inaccessible after move" conflicts.putValue(refExpr, message.capitalize()) diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/after/a/test.kt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/after/a/test.kt new file mode 100644 index 00000000000..c004f56d72c --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/after/a/test.kt @@ -0,0 +1,6 @@ +package a + +open class ProtectedParent { + protected open fun inherit() {} +} + diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/after/b/ProtectedChild.kt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/after/b/ProtectedChild.kt new file mode 100644 index 00000000000..f0a0bbc3630 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/after/b/ProtectedChild.kt @@ -0,0 +1,9 @@ +package b + +import a.ProtectedParent + +class ProtectedChild : ProtectedParent() { + override fun inherit() { + super.inherit() + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/after/b/dummy.txt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/after/b/dummy.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/before/a/test.kt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/before/a/test.kt new file mode 100644 index 00000000000..3a17ad49655 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/before/a/test.kt @@ -0,0 +1,11 @@ +package a + +open class ProtectedParent { + protected open fun inherit() {} +} + +class ProtectedChild : ProtectedParent() { + override fun inherit() { + super.inherit() + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/before/b/dummy.txt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/before/b/dummy.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/protectedMemberUsageWithSuper.test b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/protectedMemberUsageWithSuper.test new file mode 100644 index 00000000000..cf0a7242bb6 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/protectedMemberUsageWithSuper.test @@ -0,0 +1,5 @@ +{ + "mainFile": "a/test.kt", + "type": "MOVE_KOTLIN_TOP_LEVEL_DECLARATIONS", + "targetPackage": "b" +} diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/after/a/test.kt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/after/a/test.kt new file mode 100644 index 00000000000..c004f56d72c --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/after/a/test.kt @@ -0,0 +1,6 @@ +package a + +open class ProtectedParent { + protected open fun inherit() {} +} + diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/after/b/ProtectedChild.kt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/after/b/ProtectedChild.kt new file mode 100644 index 00000000000..ddff7ad6df0 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/after/b/ProtectedChild.kt @@ -0,0 +1,10 @@ +package b + +import a.ProtectedParent + +class ProtectedChild : ProtectedParent() { + fun foo() { + this.inherit() + inherit() + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/after/b/dummy.txt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/after/b/dummy.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/before/a/test.kt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/before/a/test.kt new file mode 100644 index 00000000000..995aa9415aa --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/before/a/test.kt @@ -0,0 +1,12 @@ +package a + +open class ProtectedParent { + protected open fun inherit() {} +} + +class ProtectedChild : ProtectedParent() { + fun foo() { + this.inherit() + inherit() + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/before/b/dummy.txt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/before/b/dummy.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/protectedMemberUsageWithThis.test b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/protectedMemberUsageWithThis.test new file mode 100644 index 00000000000..cf0a7242bb6 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/protectedMemberUsageWithThis.test @@ -0,0 +1,5 @@ +{ + "mainFile": "a/test.kt", + "type": "MOVE_KOTLIN_TOP_LEVEL_DECLARATIONS", + "targetPackage": "b" +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java index aa797996d3d..9ec9e06bb5c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java @@ -665,4 +665,16 @@ public class MoveTestGenerated extends AbstractMoveTest { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/movePropertyToPackageWithConflicts/movePropertyToPackageWithConflicts.test"); doTest(fileName); } + + @TestMetadata("kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/protectedMemberUsageWithSuper.test") + public void testKotlin_moveTopLevelDeclarations_protectedMemberUsageWithSuper_ProtectedMemberUsageWithSuper() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithSuper/protectedMemberUsageWithSuper.test"); + doTest(fileName); + } + + @TestMetadata("kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/protectedMemberUsageWithThis.test") + public void testKotlin_moveTopLevelDeclarations_protectedMemberUsageWithThis_ProtectedMemberUsageWithThis() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/protectedMemberUsageWithThis/protectedMemberUsageWithThis.test"); + doTest(fileName); + } }