[extract method] avoid using EDT in find and replace duplicates

GitOrigin-RevId: cf8b55fa6fbb53da88221b20c7cfc6bb02991723
This commit is contained in:
Alexandr Suhinin
2024-08-06 14:08:04 +03:00
committed by intellij-monorepo-bot
parent a7155c2242
commit 4feb9ddd29
3 changed files with 31 additions and 18 deletions

View File

@@ -15,6 +15,7 @@ import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.ScrollType
import com.intellij.openapi.util.TextRange
import com.intellij.platform.ide.progress.runWithModalProgressBlocking
import com.intellij.platform.ide.progress.withBackgroundProgress
import com.intellij.psi.*
import com.intellij.psi.codeStyle.CodeStyleManager
import com.intellij.psi.search.LocalSearchScope
@@ -85,22 +86,31 @@ class DuplicatesMethodExtractor(val extractOptions: ExtractOptions, val targetCl
}
suspend fun replaceDuplicates(editor: Editor, method: PsiMethod, beforeDuplicateReplaced: (candidate: List<PsiElement>) -> Unit = {}) {
val prepareTimeStart = System.currentTimeMillis()
val calls = callsToReplace?.map { it.element!! } ?: return
val project = readAction { editor.project } ?: return
val calls = readAction { callsToReplace?.map { it.element!! } }?: return
val defaultExtraction = ExtractedElements(calls, method)
val (exactDuplicates, parametrizedDuplicates) = findDuplicates(method, calls)
val exactReplacement = ReplaceDescriptor(exactDuplicates, defaultExtraction, extractOptions.inputParameters)
val parametrizedReplacement = findParametrizedDescriptor(extractOptions.copy(methodName = method.name), parametrizedDuplicates)
val prepareTimeStart = System.currentTimeMillis()
val searchTitle = JavaRefactoringBundle.message("extract.method.progress.search.duplicates")
val (exactReplacement, parametrizedReplacement) = withBackgroundProgress(project, searchTitle) {
readAction {
val (exactDuplicates, parametrizedDuplicates) = findDuplicates(method, calls)
val exactReplacement = ReplaceDescriptor(exactDuplicates, defaultExtraction, extractOptions.inputParameters)
val parametrizedReplacement = findParametrizedDescriptor(extractOptions.copy(methodName = method.name), parametrizedDuplicates)
exactReplacement to parametrizedReplacement
}
}
val prepareTimeEnd = System.currentTimeMillis()
InplaceExtractMethodCollector.duplicatesSearched.log(prepareTimeEnd - prepareTimeStart)
val shouldChangeSignature = askToChangeSignature(exactReplacement, parametrizedReplacement)
val chosenReplacement = if (shouldChangeSignature) parametrizedReplacement else exactReplacement
val confirmedDuplicates = confirmDuplicates(editor, chosenReplacement.duplicates)
val replacement = chosenReplacement.copy(duplicates = confirmedDuplicates)
val replacement = withContext(Dispatchers.EDT) {
val shouldChangeSignature = askToChangeSignature(exactReplacement, parametrizedReplacement)
val chosenReplacement = if (shouldChangeSignature) parametrizedReplacement else exactReplacement
val confirmedDuplicates = confirmDuplicates(editor, chosenReplacement.duplicates)
chosenReplacement.copy(duplicates = confirmedDuplicates)
}
replacement.duplicates.forEach { beforeDuplicateReplaced(it.candidate) }
@@ -108,8 +118,13 @@ class DuplicatesMethodExtractor(val extractOptions: ExtractOptions, val targetCl
}
private suspend fun replaceDuplicates(replacement: ReplaceDescriptor, method: PsiMethod, calls: List<PsiElement>) {
val project = replacement.elements.method.project
val duplicatesExtractOptions = replacement.duplicates.map { duplicate -> createExtractDescriptor(duplicate, replacement.parameters) }
val project = readAction { method.project }
val replaceTitle = JavaRefactoringBundle.message("extract.method.progress.replace.duplicates")
val duplicatesExtractOptions = withBackgroundProgress(project, replaceTitle) {
readAction {
replacement.duplicates.map { duplicate -> createExtractDescriptor(duplicate, replacement.parameters) }
}
}
writeCommandAction(project, ExtractMethodHandler.getRefactoringName()) {
if (duplicatesExtractOptions.any { options -> options.isStatic }) {
@@ -337,8 +352,6 @@ fun DuplicatesMethodExtractor.extractInDialog() {
MethodExtractor.sendRefactoringDoneEvent(method)
val editor = PsiEditorUtil.findEditor(targetClass) ?: return
runWithModalProgressBlocking(extractOptions.project, ExtractMethodHandler.getRefactoringName()) {
withContext(Dispatchers.EDT) {
mappedExtractor.replaceDuplicates(editor, method)
}
mappedExtractor.replaceDuplicates(editor, method)
}
}

View File

@@ -140,9 +140,7 @@ internal class InplaceMethodExtractor(private val editor: Editor,
installGotItTooltips(editor, callIdentifierRange?.asTextRange, methodIdentifierRange?.asTextRange)
MethodExtractor.sendRefactoringDoneEvent(extractedMethod)
runWithModalProgressBlocking(project, ExtractMethodHandler.getRefactoringName()) {
withContext(Dispatchers.EDT) {
extractor.replaceDuplicates(editor, extractedMethod)
}
extractor.replaceDuplicates(editor, extractedMethod)
}
}
.disposeWithTemplate(disposable)

View File

@@ -796,6 +796,8 @@ extract.method.checkbox.annotate=Annotate
extract.method.checkbox.make.static=Make static
extract.method.checkbox.make.static.and.pass.fields=Make static and pass fields
extract.method.link.label.more.options=More options
extract.method.progress.search.duplicates=Searching for duplicates
extract.method.progress.replace.duplicates=Replacing duplicates
dialog.message.field.doesnt.have.initializer=Field {0} doesn''t have an initializer
dialog.message.replace.duplicates.works.with.constants.only=Replace Duplicates works with constants only
dialog.message.caret.should.be.inside.method.or.constant=Caret should be positioned inside a method or constant