Move: Fix processing of references to non-real members of companion object
#KT-15559 Fixed
This commit is contained in:
+1
-1
@@ -142,7 +142,7 @@ class MoveKotlinDeclarationsProcessor(
|
||||
.search(lightElement, projectScope, false)
|
||||
.mapNotNullTo(ArrayList()) { ref ->
|
||||
if (foundReferences.add(ref) && elementsToMove.all { !it.isAncestor(ref.element)}) {
|
||||
createMoveUsageInfoIfPossible(ref, lightElement, true)
|
||||
createMoveUsageInfoIfPossible(ref, lightElement, true, null)
|
||||
}
|
||||
else null
|
||||
}
|
||||
|
||||
@@ -121,8 +121,13 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange(
|
||||
|
||||
fun processReference(refExpr: KtSimpleNameExpression, bindingContext: BindingContext): ((KtSimpleNameExpression) -> UsageInfo?)? {
|
||||
val descriptor = bindingContext[BindingContext.REFERENCE_TARGET, refExpr]?.getImportableDescriptor() ?: return null
|
||||
val containingDescriptor = descriptor.containingDeclaration ?: return null
|
||||
|
||||
val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor) ?: return null
|
||||
val callableKind = (descriptor as? CallableMemberDescriptor)?.kind
|
||||
val containingDeclarationForNonRealMember = if (callableKind != CallableMemberDescriptor.Kind.DECLARATION) {
|
||||
DescriptorToSourceUtilsIde.getAnyDeclaration(project, containingDescriptor) as? KtClassOrObject
|
||||
} else null
|
||||
|
||||
// Special case for enum entry superclass references (they have empty text and don't need to be processed by the refactoring)
|
||||
if (refExpr.textRange.isEmpty) return null
|
||||
@@ -134,7 +139,6 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange(
|
||||
val isCallableReference = isCallableReference(refExpr.mainReference)
|
||||
|
||||
if (isCallable && !isCallableReference) {
|
||||
val containingDescriptor = descriptor.containingDeclaration
|
||||
if (isExtension && containingDescriptor is ClassDescriptor) {
|
||||
val implicitClass = (refExpr.getResolvedCall(bindingContext)?.dispatchReceiver as? ImplicitClassReceiver)?.classDescriptor
|
||||
if (DescriptorUtils.isCompanionObject(implicitClass)) {
|
||||
@@ -174,7 +178,8 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange(
|
||||
.firstOrNull()
|
||||
|
||||
fun doCreateUsageInfo(refExpr: KtSimpleNameExpression): UsageInfo? {
|
||||
if (isAncestor(declaration, false)) {
|
||||
// Check container instead of declaration itself as the latter may be not real (e.g. fake override)
|
||||
if (isAncestor(containingDeclarationForNonRealMember ?: declaration, false)) {
|
||||
if (descriptor.importableFqName == null) return null
|
||||
if (isUnqualifiedExtensionReference(refExpr.mainReference, declaration)) return null
|
||||
if (isCallableReference(refExpr.mainReference)) return null
|
||||
@@ -192,7 +197,7 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange(
|
||||
}
|
||||
}
|
||||
|
||||
return createMoveUsageInfoIfPossible(refExpr.mainReference, declaration, false)
|
||||
return createMoveUsageInfoIfPossible(refExpr.mainReference, declaration, false, fqName.toSafe())
|
||||
}
|
||||
|
||||
if (isExtension || isCallableReference || containerFqName != null || isImported(descriptor)) return ::doCreateUsageInfo
|
||||
@@ -226,10 +231,20 @@ class MoveRenameSelfUsageInfo(ref: KtSimpleNameReference, refTarget: PsiElement,
|
||||
override fun getReference() = super.getReference() as? KtSimpleNameReference
|
||||
}
|
||||
|
||||
class QualifiableMoveRenameUsageInfo(
|
||||
element: PsiElement,
|
||||
reference: PsiReference,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
referencedElement: PsiElement,
|
||||
val newFqName: FqName?
|
||||
): MoveRenameUsageInfo(element, reference, startOffset, endOffset, referencedElement, false)
|
||||
|
||||
fun createMoveUsageInfoIfPossible(
|
||||
reference: PsiReference,
|
||||
referencedElement: PsiElement,
|
||||
addImportToOriginalFile: Boolean
|
||||
addImportToOriginalFile: Boolean,
|
||||
newFqName: FqName?
|
||||
): UsageInfo? {
|
||||
val element = reference.element
|
||||
if (element.getStrictParentOfType<KtSuperExpression>() != null) return null
|
||||
@@ -243,7 +258,7 @@ fun createMoveUsageInfoIfPossible(
|
||||
element, reference, startOffset, endOffset, referencedElement, element.containingFile!!, addImportToOriginalFile
|
||||
)
|
||||
}
|
||||
return MoveRenameUsageInfo(element, reference, startOffset, endOffset, referencedElement, false)
|
||||
return QualifiableMoveRenameUsageInfo(element, reference, startOffset, endOffset, referencedElement, newFqName)
|
||||
}
|
||||
|
||||
private fun isUnqualifiedExtensionReference(reference: PsiReference, referencedElement: PsiElement): Boolean {
|
||||
@@ -351,7 +366,15 @@ fun postProcessMoveUsages(usages: Collection<UsageInfo>,
|
||||
val reference = usage.reference ?: (usage.element as? KtSimpleNameExpression)?.mainReference
|
||||
try {
|
||||
when {
|
||||
reference is KtSimpleNameReference -> reference.bindToElement(newElement, shorteningMode)
|
||||
reference is KtSimpleNameReference -> {
|
||||
val newFqName = (usage as? QualifiableMoveRenameUsageInfo)?.newFqName
|
||||
if (newFqName != null) {
|
||||
reference.bindToFqName(newFqName, shorteningMode)
|
||||
}
|
||||
else {
|
||||
reference.bindToElement(newElement, shorteningMode)
|
||||
}
|
||||
}
|
||||
reference is PsiReferenceExpression && updateJavaReference(reference, oldElement, newElement) -> continue@usageLoop
|
||||
else -> reference?.bindToElement(newElement)
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package source
|
||||
|
||||
class Logger {
|
||||
fun debug(s: () -> String) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
open class Klogging
|
||||
|
||||
val Klogging.loggerExt: Logger get() = Logger
|
||||
fun Klogging.logExt(s: String) {}
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package target
|
||||
|
||||
import source.Klogging
|
||||
import source.logExt
|
||||
import source.loggerExt
|
||||
|
||||
class Foo {
|
||||
companion object : Klogging()
|
||||
|
||||
fun baz() {
|
||||
loggerExt.debug { "something" }
|
||||
logExt("something")
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package source
|
||||
|
||||
class Logger {
|
||||
fun debug(s: () -> String) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
open class Klogging
|
||||
|
||||
val Klogging.loggerExt: Logger get() = Logger
|
||||
fun Klogging.logExt(s: String) {}
|
||||
|
||||
class <caret>Foo {
|
||||
companion object : Klogging()
|
||||
|
||||
fun baz() {
|
||||
loggerExt.debug { "something" }
|
||||
logExt("something")
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"mainFile": "source/Foo.kt",
|
||||
"type": "MOVE_KOTLIN_TOP_LEVEL_DECLARATIONS",
|
||||
"targetPackage": "target"
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package source
|
||||
|
||||
class Logger {
|
||||
fun debug(s: () -> String) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
interface ILogging {
|
||||
val logger: Logger
|
||||
fun log(s: String)
|
||||
}
|
||||
|
||||
class Klogging : ILogging {
|
||||
override val logger = Logger()
|
||||
override fun log(s: String) {}
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package target
|
||||
|
||||
import source.ILogging
|
||||
import source.Klogging
|
||||
|
||||
class Foo {
|
||||
companion object : ILogging by Klogging()
|
||||
|
||||
fun baz() {
|
||||
logger.debug { "something" }
|
||||
log("something")
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package source
|
||||
|
||||
class Logger {
|
||||
fun debug(s: () -> String) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
interface ILogging {
|
||||
val logger: Logger
|
||||
fun log(s: String)
|
||||
}
|
||||
|
||||
class Klogging : ILogging {
|
||||
override val logger = Logger()
|
||||
override fun log(s: String) {}
|
||||
}
|
||||
|
||||
class <caret>Foo {
|
||||
companion object : ILogging by Klogging()
|
||||
|
||||
fun baz() {
|
||||
logger.debug { "something" }
|
||||
log("something")
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"mainFile": "source/Foo.kt",
|
||||
"type": "MOVE_KOTLIN_TOP_LEVEL_DECLARATIONS",
|
||||
"targetPackage": "target"
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package source
|
||||
|
||||
class Logger {
|
||||
fun debug(s: () -> String) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
open class Klogging {
|
||||
val logger = Logger()
|
||||
fun log(s: String) {}
|
||||
}
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package target
|
||||
|
||||
import source.Klogging
|
||||
|
||||
class Foo {
|
||||
companion object : Klogging()
|
||||
|
||||
fun baz() {
|
||||
logger.debug { "something" }
|
||||
log("something")
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package source
|
||||
|
||||
class Logger {
|
||||
fun debug(s: () -> String) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
open class Klogging {
|
||||
val logger = Logger()
|
||||
fun log(s: String) {}
|
||||
}
|
||||
|
||||
class <caret>Foo {
|
||||
companion object : Klogging()
|
||||
|
||||
fun baz() {
|
||||
logger.debug { "something" }
|
||||
log("something")
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"mainFile": "source/Foo.kt",
|
||||
"type": "MOVE_KOTLIN_TOP_LEVEL_DECLARATIONS",
|
||||
"targetPackage": "target"
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package source
|
||||
|
||||
class Logger {
|
||||
fun debug(s: () -> String) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package source;
|
||||
|
||||
public class Klogging {
|
||||
public Logger logger = Logger();
|
||||
public void log(String s) {}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package target
|
||||
|
||||
import source.Klogging
|
||||
|
||||
class Foo {
|
||||
companion object : Klogging()
|
||||
|
||||
fun baz() {
|
||||
logger.debug { "something" }
|
||||
log("something")
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package source
|
||||
|
||||
class Logger {
|
||||
fun debug(s: () -> String) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class <caret>Foo {
|
||||
companion object : Klogging()
|
||||
|
||||
fun baz() {
|
||||
logger.debug { "something" }
|
||||
log("something")
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package source;
|
||||
|
||||
public class Klogging {
|
||||
public Logger logger = Logger();
|
||||
public void log(String s) {}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"mainFile": "source/Foo.kt",
|
||||
"type": "MOVE_KOTLIN_TOP_LEVEL_DECLARATIONS",
|
||||
"targetPackage": "target"
|
||||
}
|
||||
@@ -414,6 +414,30 @@ public class MoveTestGenerated extends AbstractMoveTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveTopLevelDeclarations/misc/companionExtensionMemberRef/companionExtensionMemberRef.test")
|
||||
public void testKotlin_moveTopLevelDeclarations_misc_companionExtensionMemberRef_CompanionExtensionMemberRef() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/companionExtensionMemberRef/companionExtensionMemberRef.test");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveTopLevelDeclarations/misc/companionMemberRefDelegation/companionMemberRefDelegation.test")
|
||||
public void testKotlin_moveTopLevelDeclarations_misc_companionMemberRefDelegation_CompanionMemberRefDelegation() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/companionMemberRefDelegation/companionMemberRefDelegation.test");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveTopLevelDeclarations/misc/companionMemberRefFakeOverride/companionMemberRefFakeOverride.test")
|
||||
public void testKotlin_moveTopLevelDeclarations_misc_companionMemberRefFakeOverride_CompanionMemberRefFakeOverride() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/companionMemberRefFakeOverride/companionMemberRefFakeOverride.test");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveTopLevelDeclarations/misc/companionMemberRefWithJavaParent/companionMemberRefWithJavaParent.test")
|
||||
public void testKotlin_moveTopLevelDeclarations_misc_companionMemberRefWithJavaParent_CompanionMemberRefWithJavaParent() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/companionMemberRefWithJavaParent/companionMemberRefWithJavaParent.test");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveTopLevelDeclarations/misc/delegateInObject/delegateInObject.test")
|
||||
public void testKotlin_moveTopLevelDeclarations_misc_delegateInObject_DelegateInObject() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/delegateInObject/delegateInObject.test");
|
||||
|
||||
Reference in New Issue
Block a user