Move remove redundant imports to bg thread
#KT-24122 Fixed
This commit is contained in:
+44
-64
@@ -16,8 +16,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.codeInsight
|
||||
|
||||
import com.intellij.openapi.application.invokeLater
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.progress.Task
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
@@ -26,81 +29,66 @@ import com.intellij.psi.codeStyle.CodeStyleManager
|
||||
import com.intellij.refactoring.RefactoringHelper
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import com.intellij.util.SequentialModalProgressTask
|
||||
import com.intellij.util.SequentialTask
|
||||
import org.jetbrains.kotlin.idea.inspections.KotlinUnusedImportInspection
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtImportDirective
|
||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||
|
||||
// Based on com.intellij.refactoring.OptimizeImportsRefactoringHelper
|
||||
class KotlinOptimizeImportsRefactoringHelper : RefactoringHelper<Set<KtFile>> {
|
||||
internal class CollectUnusedImportsTask(
|
||||
private val task: SequentialModalProgressTask,
|
||||
internal open class CollectUnusedImportsTask(
|
||||
project: Project,
|
||||
private val dumbService: DumbService,
|
||||
private val unusedImports: MutableSet<SmartPsiElementPointer<KtImportDirective>>,
|
||||
operationData: Set<KtFile>
|
||||
) : SequentialTask {
|
||||
private val myTotalCount = operationData.size
|
||||
private val operationIterator = operationData.withIndex().iterator()
|
||||
private val operationData: Set<KtFile>
|
||||
) : Task.Backgroundable(project, COLLECT_UNUSED_IMPORTS_TITLE, false) {
|
||||
|
||||
override fun prepare() {}
|
||||
override fun run(indicator: ProgressIndicator) {
|
||||
val myTotalCount = operationData.size
|
||||
for ((counter, file) in operationData.withIndex()) {
|
||||
if (!file.isValid) return
|
||||
val virtualFile = file.virtualFile ?: return
|
||||
|
||||
override fun stop() {}
|
||||
with(indicator) {
|
||||
text2 = virtualFile.presentableUrl
|
||||
fraction = counter.toDouble() / myTotalCount
|
||||
}
|
||||
|
||||
override fun isDone(): Boolean = !operationIterator.hasNext()
|
||||
|
||||
override fun iteration(): Boolean {
|
||||
val (counter, file) = operationIterator.next()
|
||||
if (!file.isValid) return isDone
|
||||
val virtualFile = file.virtualFile ?: return isDone
|
||||
|
||||
with(task.indicator) {
|
||||
text2 = virtualFile.presentableUrl
|
||||
fraction = counter.toDouble() / myTotalCount
|
||||
dumbService.runReadActionInSmartMode {
|
||||
KotlinUnusedImportInspection.analyzeImports(file)?.unusedImports?.mapTo(unusedImports) { it.createSmartPointer() }
|
||||
}
|
||||
}
|
||||
|
||||
dumbService.runReadActionInSmartMode {
|
||||
KotlinUnusedImportInspection.analyzeImports(file)?.unusedImports?.mapTo(unusedImports) { it.createSmartPointer() }
|
||||
}
|
||||
return isDone
|
||||
}
|
||||
}
|
||||
|
||||
internal class OptimizeImportsTask(
|
||||
private val task: SequentialModalProgressTask,
|
||||
pointers: Set<SmartPsiElementPointer<KtImportDirective>>
|
||||
) : SequentialTask {
|
||||
private val pointerIterator = pointers.withIndex().iterator()
|
||||
private val myTotal: Int = pointers.size
|
||||
project: Project,
|
||||
private val pointers: Set<SmartPsiElementPointer<KtImportDirective>>
|
||||
) : Task.Modal(project, REMOVING_REDUNDANT_IMPORTS_TITLE, false) {
|
||||
|
||||
override fun prepare() {}
|
||||
override fun run(indicator: ProgressIndicator) {
|
||||
val myTotal: Int = pointers.size
|
||||
for ((counter, pointer) in pointers.withIndex()) {
|
||||
indicator.fraction = counter.toDouble() / myTotal
|
||||
|
||||
override fun isDone() = !pointerIterator.hasNext()
|
||||
|
||||
override fun iteration(): Boolean {
|
||||
val (counter, pointer) = pointerIterator.next()
|
||||
|
||||
task.indicator?.fraction = counter.toDouble() / myTotal
|
||||
|
||||
val directive = pointer.element
|
||||
if (directive?.isValid == true) {
|
||||
task.indicator?.text2 = directive.containingFile.virtualFile.presentableUrl
|
||||
runWriteAction {
|
||||
try {
|
||||
directive.delete()
|
||||
} catch (e: IncorrectOperationException) {
|
||||
LOG.error(e)
|
||||
val directive = pointer.element
|
||||
if (directive?.isValid == true) {
|
||||
val presentableUrl = directive.containingFile.virtualFile.presentableUrl
|
||||
indicator.text2 = presentableUrl
|
||||
invokeLater {
|
||||
project.executeWriteCommand("delete $presentableUrl") {
|
||||
try {
|
||||
directive.delete()
|
||||
} catch (e: IncorrectOperationException) {
|
||||
LOG.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isDone
|
||||
}
|
||||
|
||||
override fun stop() {}
|
||||
|
||||
companion object {
|
||||
private val LOG = Logger.getInstance("#" + OptimizeImportsTask::class.java.name)
|
||||
}
|
||||
@@ -112,38 +100,30 @@ class KotlinOptimizeImportsRefactoringHelper : RefactoringHelper<Set<KtFile>> {
|
||||
}
|
||||
|
||||
override fun prepareOperation(usages: Array<UsageInfo>): Set<KtFile> {
|
||||
return usages.mapNotNullTo(LinkedHashSet<KtFile>()) {
|
||||
return usages.mapNotNullTo(LinkedHashSet()) {
|
||||
if (!it.isNonCodeUsage) it.file as? KtFile else null
|
||||
}
|
||||
}
|
||||
|
||||
override fun performOperation(project: Project, operationData: Set<KtFile>) {
|
||||
if (operationData.isEmpty()) return
|
||||
|
||||
CodeStyleManager.getInstance(project).performActionWithFormatterDisabled {
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
}
|
||||
|
||||
if (operationData.isEmpty()) return
|
||||
|
||||
val unusedImports = mutableSetOf<SmartPsiElementPointer<KtImportDirective>>()
|
||||
|
||||
val progressManager = ProgressManager.getInstance()
|
||||
|
||||
val dumbService = DumbService.getInstance(project)
|
||||
|
||||
val collectTask = object : SequentialModalProgressTask(project, COLLECT_UNUSED_IMPORTS_TITLE, false) {
|
||||
val collectTask = object : CollectUnusedImportsTask(project, dumbService, unusedImports, operationData) {
|
||||
override fun onSuccess() {
|
||||
val progressTask = SequentialModalProgressTask(project, REMOVING_REDUNDANT_IMPORTS_TITLE, false)
|
||||
with(progressTask) {
|
||||
setMinIterationTime(200)
|
||||
setTask(OptimizeImportsTask(this, unusedImports))
|
||||
}
|
||||
val progressTask = OptimizeImportsTask(project, unusedImports)
|
||||
progressManager.run(progressTask)
|
||||
}
|
||||
}
|
||||
with(collectTask) {
|
||||
setMinIterationTime(200)
|
||||
setTask(CollectUnusedImportsTask(this, dumbService, unusedImports, operationData))
|
||||
}
|
||||
progressManager.run(collectTask)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user