Move: Fix callable reference processing when moving to another package

#KT-14197 Fixed
This commit is contained in:
Alexey Sedunov
2016-11-24 15:22:22 +03:00
parent 0e9b024720
commit 61210d6ba2
13 changed files with 73 additions and 10 deletions
+1
View File
@@ -345,6 +345,7 @@ These artifacts include extensions for the types available in the latter JDKs, s
- [`KT-14361`](https://youtrack.jetbrains.com/issue/KT-14361) Rename: Do not report redeclaration conflict for private top-level declarations located in different files
- [`KT-14596`](https://youtrack.jetbrains.com/issue/KT-14596) Safe Delete: Fix exception on deleting Java class used in Kotlin import directive(s)
- [`KT-14325`](https://youtrack.jetbrains.com/issue/KT-14325) Rename: Fix exceptions on moving file with facade class to another package
- [`KT-14197`](https://youtrack.jetbrains.com/issue/KT-14197) Move: Fix callable reference processing when moving to another package
## 1.0.5
@@ -47,7 +47,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet
import org.jetbrains.kotlin.idea.core.deleteSingle
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
import org.jetbrains.kotlin.idea.refactoring.move.MoveRenameUsageInfoForExtension
import org.jetbrains.kotlin.idea.refactoring.move.UnqualifiableMoveRenameUsageInfo
import org.jetbrains.kotlin.idea.refactoring.move.createMoveUsageInfoIfPossible
import org.jetbrains.kotlin.idea.refactoring.move.getInternalReferencesToUpdateOnPackageNameChange
import org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories.MoveKotlinClassHandler
@@ -177,7 +177,7 @@ class MoveKotlinDeclarationsProcessor(
val packageNameInfo = descriptor.delegate.getContainerChangeInfo(it, descriptor.moveTarget)
val (usagesToProcessLater, usagesToProcessEarly) = it
.getInternalReferencesToUpdateOnPackageNameChange(packageNameInfo)
.partition { it is MoveRenameUsageInfoForExtension }
.partition { it is UnqualifiableMoveRenameUsageInfo }
usages.addAll(usagesToProcessLater)
usagesToProcessBeforeMove.addAll(usagesToProcessEarly)
}
@@ -23,7 +23,6 @@ import com.intellij.openapi.util.Comparing
import com.intellij.openapi.util.Key
import com.intellij.psi.*
import com.intellij.refactoring.RefactoringBundle
import com.intellij.refactoring.RefactoringSettings
import com.intellij.refactoring.copy.CopyFilesOrDirectoriesHandler
import com.intellij.refactoring.move.MoveHandler
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor
@@ -59,7 +58,6 @@ import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
import org.jetbrains.kotlin.idea.util.application.executeCommand
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.resolve.BindingContext
@@ -133,8 +131,9 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange(
val isCallable = descriptor is CallableDescriptor
val isExtension = isCallable && declaration.isExtensionDeclaration()
val isCallableReference = isCallableReference(refExpr.mainReference)
if (isCallable) {
if (isCallable && !isCallableReference) {
val containingDescriptor = descriptor.containingDeclaration
if (isExtension && containingDescriptor is ClassDescriptor) {
val implicitClass = (refExpr.getResolvedCall(bindingContext)?.dispatchReceiver as? ImplicitClassReceiver)?.classDescriptor
@@ -143,6 +142,7 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange(
}
return null
}
if (!isExtension) {
if (refExpr.getReceiverExpression() != null) {
return fun(refExpr: KtSimpleNameExpression): UsageInfo? {
@@ -177,6 +177,7 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange(
if (isAncestor(declaration, false)) {
if (descriptor.importableFqName == null) return null
if (isUnqualifiedExtensionReference(refExpr.mainReference, declaration)) return null
if (isCallableReference(refExpr.mainReference)) return null
if (containerFqName == null || newContainer is ContainerInfo.UnknownPackage) return null
return fqName.asString().let {
val prefix = containerFqName.asString()
@@ -194,7 +195,7 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange(
return createMoveUsageInfoIfPossible(refExpr.mainReference, declaration, false)
}
if (isExtension || containerFqName != null || isImported(descriptor)) return ::doCreateUsageInfo
if (isExtension || isCallableReference || containerFqName != null || isImported(descriptor)) return ::doCreateUsageInfo
return null
}
@@ -210,7 +211,7 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange(
class ImplicitCompanionAsDispatchReceiverUsageInfo(callee: KtSimpleNameExpression) : UsageInfo(callee)
class MoveRenameUsageInfoForExtension(
class UnqualifiableMoveRenameUsageInfo(
element: PsiElement,
reference: PsiReference,
startOffset: Int,
@@ -237,8 +238,8 @@ fun createMoveUsageInfoIfPossible(
val startOffset = range.startOffset
val endOffset = range.endOffset
if (isUnqualifiedExtensionReference(reference, referencedElement)) {
return MoveRenameUsageInfoForExtension(
if (isUnqualifiedExtensionReference(reference, referencedElement) || isCallableReference(reference)) {
return UnqualifiableMoveRenameUsageInfo(
element, reference, startOffset, endOffset, referencedElement, element.containingFile!!, addImportToOriginalFile
)
}
@@ -251,6 +252,11 @@ private fun isUnqualifiedExtensionReference(reference: PsiReference, referencedE
&& reference.element.getNonStrictParentOfType<KtImportDirective>() == null
}
private fun isCallableReference(reference: PsiReference): Boolean {
return reference is KtSimpleNameReference
&& reference.element.getParentOfTypeAndBranch<KtCallableReferenceExpression> { callableReference } != null
}
fun guessNewFileName(declarationsToMove: Collection<KtNamedDeclaration>): String? {
if (declarationsToMove.isEmpty()) return null
@@ -333,7 +339,7 @@ fun postProcessMoveUsages(usages: List<UsageInfo>,
usage.reference?.bindToFqName(usage.newFqName, shorteningMode)
}
is MoveRenameUsageInfoForExtension -> {
is UnqualifiableMoveRenameUsageInfo -> {
val file = with(usage) { if (addImportToOriginalFile) originalFile else counterpart(originalFile) } as KtFile
val declaration = counterpart(usage.referencedElement!!).unwrapped as KtDeclaration
ImportInsertHelper.getInstance(usage.project).importDescriptor(file, declaration.resolveToDescriptor())
@@ -0,0 +1,3 @@
package a
fun f2() = 2
@@ -0,0 +1,14 @@
package b
import a.f2
import b.f3
import c.f4
fun test() {
val ref1 = ::f1
val ref2 = ::f2
val ref3 = ::f3
val ref4 = ::f4
}
fun f1() = 1
@@ -0,0 +1,3 @@
package b
fun f3() = 3
@@ -0,0 +1,3 @@
package c
fun f4() = 4
@@ -0,0 +1,13 @@
package a
import b.f3
import c.f4
fun test() {
val ref1 = ::f1
val ref2 = ::f2
val ref3 = ::f3
val ref4 = ::f4
}
fun f1() = 1
@@ -0,0 +1,3 @@
package a
fun f2() = 2
@@ -0,0 +1,3 @@
package b
fun f3() = 3
@@ -0,0 +1,3 @@
package c
fun f4() = 4
@@ -0,0 +1,5 @@
{
"mainFile": "a/test.kt",
"type": "MOVE_FILES",
"targetPackage": "b"
}
@@ -246,6 +246,12 @@ public class MoveTestGenerated extends AbstractMoveTest {
doTest(fileName);
}
@TestMetadata("kotlin/moveFile/callableReferences/callableReferences.test")
public void testKotlin_moveFile_callableReferences_CallableReferences() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveFile/callableReferences/callableReferences.test");
doTest(fileName);
}
@TestMetadata("kotlin/moveFile/internalReferences/internalReferences.test")
public void testKotlin_moveFile_internalReferences_InternalReferences() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveFile/internalReferences/internalReferences.test");