From bd6b96341fc0f5a2feb390c6a9f6ec8df38291a5 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 1 Mar 2018 15:42:42 +0300 Subject: [PATCH] 181: Move: Remove unnecessary runSynchronouslyWithProgress() call This method is already invoked under progress manager --- ...otlinMoveDirectoryWithClassesHelper.kt.181 | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/KotlinMoveDirectoryWithClassesHelper.kt.181 diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/KotlinMoveDirectoryWithClassesHelper.kt.181 b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/KotlinMoveDirectoryWithClassesHelper.kt.181 new file mode 100644 index 00000000000..7cb16ec5d5c --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/KotlinMoveDirectoryWithClassesHelper.kt.181 @@ -0,0 +1,151 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories + +import com.intellij.openapi.progress.ProgressManager +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiDirectory +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.refactoring.listeners.RefactoringElementListener +import com.intellij.refactoring.move.moveClassesOrPackages.MoveDirectoryWithClassesHelper +import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil +import com.intellij.usageView.UsageInfo +import com.intellij.util.Function +import com.intellij.util.containers.MultiMap +import org.jetbrains.kotlin.idea.core.getPackage +import org.jetbrains.kotlin.idea.core.quoteIfNeeded +import org.jetbrains.kotlin.idea.refactoring.invokeOnceOnCommandFinish +import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.KotlinDirectoryMoveTarget +import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveKotlinDeclarationsProcessor +import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.analyzeConflictsInFile +import org.jetbrains.kotlin.idea.runSynchronouslyWithProgress +import org.jetbrains.kotlin.idea.util.application.runReadAction +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtFile +import java.util.* + +class KotlinMoveDirectoryWithClassesHelper : MoveDirectoryWithClassesHelper() { + private data class FileUsagesWrapper( + val psiFile: KtFile, + val usages: List, + val moveDeclarationsProcessor: MoveKotlinDeclarationsProcessor? + ) : UsageInfo(psiFile) + + private class MoveContext( + val newParent: PsiDirectory, + val moveDeclarationsProcessor: MoveKotlinDeclarationsProcessor? + ) + + private val fileHandler = MoveKotlinFileHandler() + + private var fileToMoveContext: MutableMap? = null + + private fun getOrCreateMoveContextMap(): MutableMap { + return fileToMoveContext ?: HashMap().apply { + fileToMoveContext = this + invokeOnceOnCommandFinish { fileToMoveContext = null } + } + } + + override fun findUsages( + filesToMove: MutableCollection, + directoriesToMove: Array, + result: MutableCollection, + searchInComments: Boolean, + searchInNonJavaFiles: Boolean, + project: Project) { + filesToMove + .filterIsInstance() + .mapTo(result) { FileUsagesWrapper(it, fileHandler.findUsages(it, null, false), null) } + } + + override fun preprocessUsages( + project: Project, + files: MutableSet, + infos: Array, + directory: PsiDirectory?, + conflicts: MultiMap + ) { + val psiPackage = directory?.getPackage() ?: return + val moveTarget = KotlinDirectoryMoveTarget(FqName(psiPackage.qualifiedName), directory) + for ((index, usageInfo) in infos.withIndex()) { + if (usageInfo !is FileUsagesWrapper) continue + + ProgressManager.getInstance().progressIndicator?.text2 = "Processing ${usageInfo.psiFile.name}" + + runReadAction { + analyzeConflictsInFile(usageInfo.psiFile, usageInfo.usages, moveTarget, files, conflicts) { + infos[index] = usageInfo.copy(usages = it) + } + } + } + } + + override fun beforeMove(psiFile: PsiFile) { + + } + + // Actual move logic is implemented in postProcessUsages since usages are not available here + override fun move( + file: PsiFile, + moveDestination: PsiDirectory, + oldToNewElementsMapping: MutableMap, + movedFiles: MutableList, + listener: RefactoringElementListener? + ): Boolean { + if (file !is KtFile) return false + + val moveDeclarationsProcessor = fileHandler.initMoveProcessor(file, moveDestination, false) + val moveContextMap = getOrCreateMoveContextMap() + moveContextMap[file] = MoveContext(moveDestination, moveDeclarationsProcessor) + if (moveDeclarationsProcessor != null) { + moveDestination.getPackage()?.let { newPackage -> + file.packageDirective?.fqName = FqName(newPackage.qualifiedName).quoteIfNeeded() + } + } + return true + } + + override fun afterMove(newElement: PsiElement) { + + } + + override fun postProcessUsages(usages: Array, newDirMapper: Function) { + val fileToMoveContext = fileToMoveContext ?: return + try { + val usagesToProcess = ArrayList() + usages + .filterIsInstance() + .forEach body@ { + val file = it.psiFile + val moveContext = fileToMoveContext[file] ?: return@body + + MoveFilesOrDirectoriesUtil.doMoveFile(file, moveContext.newParent) + + val moveDeclarationsProcessor = moveContext.moveDeclarationsProcessor ?: return@body + val movedFile = moveContext.newParent.findFile(file.name) ?: return@body + + usagesToProcess += FileUsagesWrapper(movedFile as KtFile, it.usages, moveDeclarationsProcessor) + } + usagesToProcess.forEach { fileHandler.retargetUsages(it.usages, it.moveDeclarationsProcessor!!) } + } + finally { + this.fileToMoveContext = null + } + } +} \ No newline at end of file