Pull Up: Skip super members without explicit declarations

#KT-13124 Fixed
This commit is contained in:
Alexey Sedunov
2016-08-15 18:46:54 +03:00
parent 6766494581
commit 94c4b426f5
6 changed files with 55 additions and 9 deletions
+1
View File
@@ -269,6 +269,7 @@ Using 'this' as function argument in constructor of non-final class
- [`KT-13240`](https://youtrack.jetbrains.com/issue/KT-13240) Rename: Do not report shadowing conflict if redeclaration is detected
- [`KT-13253`](https://youtrack.jetbrains.com/issue/KT-13253) Rename: Report conflicts for constructor parameters
- [`KT-12971`](https://youtrack.jetbrains.com/issue/KT-12971) Push Down: Do not specifiy visibility on generated overriding members
- [`KT-13124`](https://youtrack.jetbrains.com/issue/KT-13124) Pull Up: Skip super members without explicit declarations
##### New features
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.refactoring.pullUp
import com.intellij.openapi.util.Key
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet
import org.jetbrains.kotlin.idea.imports.importableFqName
@@ -27,9 +28,11 @@ import org.jetbrains.kotlin.idea.core.ShortenReferences
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.allChildren
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForReceiver
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForReceiverOrThis
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getExplicitReceiverValue
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
@@ -53,8 +56,10 @@ fun markElements(
private fun visitSuperOrThis(expression: KtInstanceExpressionWithLabel) {
if (targetClassDescriptor == null) return
val referenceTarget = context[BindingContext.REFERENCE_TARGET, expression.instanceReference]
if (referenceTarget == targetClassDescriptor) {
val callee = expression.getQualifiedExpressionForReceiver()?.selectorExpression?.getCalleeExpressionIfAny() ?: return
val calleeTarget = callee.getResolvedCall(context)?.resultingDescriptor ?: return
if ((calleeTarget as? CallableMemberDescriptor)?.kind != CallableMemberDescriptor.Kind.DECLARATION) return
if (calleeTarget.containingDeclaration == targetClassDescriptor) {
expression.replaceWithTargetThis = true
affectedElements.add(expression)
}
@@ -91,13 +91,13 @@ private fun KotlinPullUpData.checkClashWithSuperDeclaration(
member: KtNamedDeclaration,
memberDescriptor: DeclarationDescriptor,
conflicts: MultiMap<PsiElement, String>) {
if (memberDescriptor is CallableMemberDescriptor) {
val clashingSuper = getClashingMemberInTargetClass(memberDescriptor)
if (clashingSuper != null && clashingSuper.modality != Modality.ABSTRACT) {
val message = "${targetClassDescriptor.renderForConflicts()} already contains ${memberDescriptor.renderForConflicts()}"
conflicts.putValue(member, message.capitalize())
}
}
if (memberDescriptor !is CallableMemberDescriptor) return
val clashingSuper = getClashingMemberInTargetClass(memberDescriptor) ?: return
if (clashingSuper.modality == Modality.ABSTRACT) return
if (clashingSuper.kind != CallableMemberDescriptor.Kind.DECLARATION) return
val message = "${targetClassDescriptor.renderForConflicts()} already contains ${memberDescriptor.renderForConflicts()}"
conflicts.putValue(member, message.capitalize())
}
private fun KotlinPullUpData.checkAccidentalOverrides(
@@ -0,0 +1,17 @@
// TARGET_CLASS: B
open class A {
open fun callSuper() {
// Something important
}
}
open class B : A() {
}
class <caret>C : B() {
// INFO: {"checked": "true"}
override fun callSuper() {
super.callSuper() // We simply call up to the base class
}
}
@@ -0,0 +1,17 @@
// TARGET_CLASS: B
open class A {
open fun callSuper() {
// Something important
}
}
open class B : A() {
// INFO: {"checked": "true"}
override fun callSuper() {
super.callSuper() // We simply call up to the base class
}
}
class C : B() {
}
@@ -223,6 +223,12 @@ public class PullUpTestGenerated extends AbstractPullUpTest {
doKotlinTest(fileName);
}
@TestMetadata("skipFakeOverrides.kt")
public void testSkipFakeOverrides() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/pullUp/k2k/skipFakeOverrides.kt");
doKotlinTest(fileName);
}
@TestMetadata("spaceAfterModifier.kt")
public void testSpaceAfterModifier() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/pullUp/k2k/spaceAfterModifier.kt");