Move: Do not report conflict on usages of inherited protected members

#KT-15190 Fixed
This commit is contained in:
Alexey Sedunov
2017-03-08 01:02:15 +03:00
parent e82b256640
commit 92fbca452d
14 changed files with 88 additions and 0 deletions
@@ -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())
@@ -0,0 +1,6 @@
package a
open class ProtectedParent {
protected open fun inherit() {}
}
@@ -0,0 +1,9 @@
package b
import a.ProtectedParent
class ProtectedChild : ProtectedParent() {
override fun inherit() {
super.inherit()
}
}
@@ -0,0 +1,11 @@
package a
open class ProtectedParent {
protected open fun inherit() {}
}
class <caret>ProtectedChild : ProtectedParent() {
override fun inherit() {
super.inherit()
}
}
@@ -0,0 +1,5 @@
{
"mainFile": "a/test.kt",
"type": "MOVE_KOTLIN_TOP_LEVEL_DECLARATIONS",
"targetPackage": "b"
}
@@ -0,0 +1,6 @@
package a
open class ProtectedParent {
protected open fun inherit() {}
}
@@ -0,0 +1,10 @@
package b
import a.ProtectedParent
class ProtectedChild : ProtectedParent() {
fun foo() {
this.inherit()
inherit()
}
}
@@ -0,0 +1,12 @@
package a
open class ProtectedParent {
protected open fun inherit() {}
}
class <caret>ProtectedChild : ProtectedParent() {
fun foo() {
this.inherit()
inherit()
}
}
@@ -0,0 +1,5 @@
{
"mainFile": "a/test.kt",
"type": "MOVE_KOTLIN_TOP_LEVEL_DECLARATIONS",
"targetPackage": "b"
}
@@ -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);
}
}