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)
|
.search(lightElement, projectScope, false)
|
||||||
.mapNotNullTo(ArrayList()) { ref ->
|
.mapNotNullTo(ArrayList()) { ref ->
|
||||||
if (foundReferences.add(ref) && elementsToMove.all { !it.isAncestor(ref.element)}) {
|
if (foundReferences.add(ref) && elementsToMove.all { !it.isAncestor(ref.element)}) {
|
||||||
createMoveUsageInfoIfPossible(ref, lightElement, true)
|
createMoveUsageInfoIfPossible(ref, lightElement, true, null)
|
||||||
}
|
}
|
||||||
else null
|
else null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,8 +121,13 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange(
|
|||||||
|
|
||||||
fun processReference(refExpr: KtSimpleNameExpression, bindingContext: BindingContext): ((KtSimpleNameExpression) -> UsageInfo?)? {
|
fun processReference(refExpr: KtSimpleNameExpression, bindingContext: BindingContext): ((KtSimpleNameExpression) -> UsageInfo?)? {
|
||||||
val descriptor = bindingContext[BindingContext.REFERENCE_TARGET, refExpr]?.getImportableDescriptor() ?: return null
|
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 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)
|
// 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
|
if (refExpr.textRange.isEmpty) return null
|
||||||
@@ -134,7 +139,6 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange(
|
|||||||
val isCallableReference = isCallableReference(refExpr.mainReference)
|
val isCallableReference = isCallableReference(refExpr.mainReference)
|
||||||
|
|
||||||
if (isCallable && !isCallableReference) {
|
if (isCallable && !isCallableReference) {
|
||||||
val containingDescriptor = descriptor.containingDeclaration
|
|
||||||
if (isExtension && containingDescriptor is ClassDescriptor) {
|
if (isExtension && containingDescriptor is ClassDescriptor) {
|
||||||
val implicitClass = (refExpr.getResolvedCall(bindingContext)?.dispatchReceiver as? ImplicitClassReceiver)?.classDescriptor
|
val implicitClass = (refExpr.getResolvedCall(bindingContext)?.dispatchReceiver as? ImplicitClassReceiver)?.classDescriptor
|
||||||
if (DescriptorUtils.isCompanionObject(implicitClass)) {
|
if (DescriptorUtils.isCompanionObject(implicitClass)) {
|
||||||
@@ -174,7 +178,8 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange(
|
|||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
|
|
||||||
fun doCreateUsageInfo(refExpr: KtSimpleNameExpression): UsageInfo? {
|
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 (descriptor.importableFqName == null) return null
|
||||||
if (isUnqualifiedExtensionReference(refExpr.mainReference, declaration)) return null
|
if (isUnqualifiedExtensionReference(refExpr.mainReference, declaration)) return null
|
||||||
if (isCallableReference(refExpr.mainReference)) 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
|
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
|
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(
|
fun createMoveUsageInfoIfPossible(
|
||||||
reference: PsiReference,
|
reference: PsiReference,
|
||||||
referencedElement: PsiElement,
|
referencedElement: PsiElement,
|
||||||
addImportToOriginalFile: Boolean
|
addImportToOriginalFile: Boolean,
|
||||||
|
newFqName: FqName?
|
||||||
): UsageInfo? {
|
): UsageInfo? {
|
||||||
val element = reference.element
|
val element = reference.element
|
||||||
if (element.getStrictParentOfType<KtSuperExpression>() != null) return null
|
if (element.getStrictParentOfType<KtSuperExpression>() != null) return null
|
||||||
@@ -243,7 +258,7 @@ fun createMoveUsageInfoIfPossible(
|
|||||||
element, reference, startOffset, endOffset, referencedElement, element.containingFile!!, addImportToOriginalFile
|
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 {
|
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
|
val reference = usage.reference ?: (usage.element as? KtSimpleNameExpression)?.mainReference
|
||||||
try {
|
try {
|
||||||
when {
|
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
|
reference is PsiReferenceExpression && updateJavaReference(reference, oldElement, newElement) -> continue@usageLoop
|
||||||
else -> reference?.bindToElement(newElement)
|
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);
|
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")
|
@TestMetadata("kotlin/moveTopLevelDeclarations/misc/delegateInObject/delegateInObject.test")
|
||||||
public void testKotlin_moveTopLevelDeclarations_misc_delegateInObject_DelegateInObject() throws Exception {
|
public void testKotlin_moveTopLevelDeclarations_misc_delegateInObject_DelegateInObject() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/delegateInObject/delegateInObject.test");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/delegateInObject/delegateInObject.test");
|
||||||
|
|||||||
Reference in New Issue
Block a user