Move: Correctly determine target module for deferred files
This commit is contained in:
+11
-1
@@ -16,11 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiDirectory
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.idea.core.getOrCreateCompanionObject
|
||||
import org.jetbrains.kotlin.idea.util.projectStructure.getModule
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
@@ -38,10 +40,16 @@ interface KotlinMoveTarget {
|
||||
|
||||
// Check possible errors and return corresponding message, or null if no errors are detected
|
||||
fun verify(file: PsiFile): String?
|
||||
|
||||
val targetScope: VirtualFile?
|
||||
get() = targetFile
|
||||
}
|
||||
|
||||
interface KotlinDirectoryBasedMoveTarget : KotlinMoveTarget {
|
||||
val directory: PsiDirectory?
|
||||
|
||||
override val targetScope: VirtualFile?
|
||||
get() = super.targetScope ?: directory?.virtualFile
|
||||
}
|
||||
|
||||
object EmptyKotlinMoveTarget: KotlinMoveTarget {
|
||||
@@ -110,4 +118,6 @@ class KotlinDirectoryMoveTarget(
|
||||
override fun getTargetPsiIfExists(originalPsi: PsiElement) = null
|
||||
|
||||
override fun verify(file: PsiFile) = null
|
||||
}
|
||||
}
|
||||
|
||||
fun KotlinMoveTarget.getTargetModule(project: Project) = targetScope?.getModule(project)
|
||||
+1
-2
@@ -49,7 +49,6 @@ import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
||||
import org.jetbrains.kotlin.idea.refactoring.move.*
|
||||
import org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories.MoveKotlinClassHandler
|
||||
import org.jetbrains.kotlin.idea.search.projectScope
|
||||
import org.jetbrains.kotlin.idea.util.projectStructure.getModule
|
||||
import org.jetbrains.kotlin.idea.util.projectStructure.module
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -158,7 +157,7 @@ class MoveKotlinDeclarationsProcessor(
|
||||
val ktDeclaration = element.namedUnwrappedElement as? KtNamedDeclaration ?: return false
|
||||
if (ktDeclaration.hasModifier(KtTokens.PRIVATE_KEYWORD)) return false
|
||||
val (oldContainer, newContainer) = descriptor.delegate.getContainerChangeInfo(ktDeclaration, descriptor.moveTarget)
|
||||
val targetModule = descriptor.moveTarget.targetFile?.getModule(project) ?: return false
|
||||
val targetModule = descriptor.moveTarget.getTargetModule(project) ?: return false
|
||||
return oldContainer == newContainer && ktDeclaration.module == targetModule
|
||||
}
|
||||
|
||||
|
||||
+11
-17
@@ -118,13 +118,8 @@ class MoveConflictChecker(
|
||||
|
||||
is KotlinDirectoryBasedMoveTarget -> {
|
||||
val packageFqName = targetContainerFqName ?: return null
|
||||
val targetDir = directory?.virtualFile ?: targetFile
|
||||
val targetModuleDescriptor = if (targetDir != null) {
|
||||
getModuleDescriptor(targetDir) ?: return null
|
||||
}
|
||||
else {
|
||||
resolutionFacade.moduleDescriptor
|
||||
}
|
||||
val targetModuleDescriptor = targetScope?.let { getModuleDescriptor(it) ?: return null }
|
||||
?: resolutionFacade.moduleDescriptor
|
||||
MutablePackageFragmentDescriptor(targetModuleDescriptor, packageFqName).withSource(fakeFile)
|
||||
}
|
||||
|
||||
@@ -171,11 +166,11 @@ class MoveConflictChecker(
|
||||
// Based on RefactoringConflictsUtil.analyzeModuleConflicts
|
||||
fun analyzeModuleConflictsInUsages(project: Project,
|
||||
usages: Collection<UsageInfo>,
|
||||
targetFile: VirtualFile,
|
||||
targetScope: VirtualFile,
|
||||
conflicts: MultiMap<PsiElement, String>) {
|
||||
val targetModule = targetFile.getModule(project) ?: return
|
||||
val targetModule = targetScope.getModule(project) ?: return
|
||||
|
||||
val isInTestSources = ModuleRootManager.getInstance(targetModule).fileIndex.isInTestSourceContent(targetFile)
|
||||
val isInTestSources = ModuleRootManager.getInstance(targetModule).fileIndex.isInTestSourceContent(targetScope)
|
||||
NextUsage@ for (usage in usages) {
|
||||
val element = usage.element ?: continue
|
||||
if (PsiTreeUtil.getParentOfType(element, PsiImportStatement::class.java, false) != null) continue
|
||||
@@ -205,9 +200,9 @@ class MoveConflictChecker(
|
||||
|
||||
fun checkModuleConflictsInUsages(externalUsages: MutableSet<UsageInfo>, conflicts: MultiMap<PsiElement, String>) {
|
||||
val newConflicts = MultiMap<PsiElement, String>()
|
||||
val targetFile = moveTarget.targetFile ?: return
|
||||
val targetScope = moveTarget.targetScope ?: return
|
||||
|
||||
analyzeModuleConflictsInUsages(project, externalUsages, targetFile, newConflicts)
|
||||
analyzeModuleConflictsInUsages(project, externalUsages, targetScope, newConflicts)
|
||||
if (!newConflicts.isEmpty) {
|
||||
val referencedElementsToSkip = newConflicts.keySet().mapNotNullTo(HashSet()) { it.namedUnwrappedElement }
|
||||
externalUsages.removeIf {
|
||||
@@ -247,8 +242,8 @@ class MoveConflictChecker(
|
||||
internalUsages: MutableSet<UsageInfo>,
|
||||
conflicts: MultiMap<PsiElement, String>
|
||||
) {
|
||||
val targetFile = moveTarget.targetFile ?: return
|
||||
val targetModule = targetFile.getModule(project) ?: return
|
||||
val targetScope = moveTarget.targetScope ?: return
|
||||
val targetModule = targetScope.getModule(project) ?: return
|
||||
val resolveScope = targetModule.getScopeWithPlatformAwareDependencies()
|
||||
|
||||
fun isInScope(targetElement: PsiElement, targetDescriptor: DeclarationDescriptor): Boolean {
|
||||
@@ -260,7 +255,7 @@ class MoveConflictChecker(
|
||||
val renderedImportableTarget = DESCRIPTOR_RENDERER_FOR_COMPARISON.render(importableDescriptor)
|
||||
val renderedTarget by lazy { DESCRIPTOR_RENDERER_FOR_COMPARISON.render(targetDescriptor) }
|
||||
|
||||
val targetModuleInfo = getModuleInfoByVirtualFile(project, targetFile)
|
||||
val targetModuleInfo = getModuleInfoByVirtualFile(project, targetScope)
|
||||
val dummyFile = KtPsiFactory(targetElement.project).createFile("dummy.kt", "").apply {
|
||||
moduleInfo = targetModuleInfo
|
||||
targetPlatform = TargetPlatformDetector.getPlatform(targetModule)
|
||||
@@ -432,8 +427,7 @@ class MoveConflictChecker(
|
||||
private fun isToBeMoved(element: PsiElement): Boolean = allElementsToMove.any { it.isAncestor(element, false) }
|
||||
|
||||
private fun checkInternalMemberUsages(conflicts: MultiMap<PsiElement, String>) {
|
||||
val sourceRoot = moveTarget.targetFile ?: return
|
||||
val targetModule = ModuleUtilCore.findModuleForFile(sourceRoot, project) ?: return
|
||||
val targetModule = moveTarget.getTargetModule(project) ?: return
|
||||
|
||||
val membersToCheck = LinkedHashSet<KtDeclaration>()
|
||||
val memberCollector = object : KtVisitorVoid() {
|
||||
|
||||
Reference in New Issue
Block a user