From 4feb9ddd29bc10e33483325979bc0e08401ae57c Mon Sep 17 00:00:00 2001 From: Alexandr Suhinin Date: Tue, 6 Aug 2024 14:08:04 +0300 Subject: [PATCH] [extract method] avoid using EDT in find and replace duplicates GitOrigin-RevId: cf8b55fa6fbb53da88221b20c7cfc6bb02991723 --- .../inplace/DuplicatesMethodExtractor.kt | 43 ++++++++++++------- .../newImpl/inplace/InplaceMethodExtractor.kt | 4 +- .../messages/JavaRefactoringBundle.properties | 2 + 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethod/newImpl/inplace/DuplicatesMethodExtractor.kt b/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethod/newImpl/inplace/DuplicatesMethodExtractor.kt index 1947ecd04db7..8a0227aa661b 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethod/newImpl/inplace/DuplicatesMethodExtractor.kt +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethod/newImpl/inplace/DuplicatesMethodExtractor.kt @@ -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) -> 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) { - 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) } } \ No newline at end of file diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethod/newImpl/inplace/InplaceMethodExtractor.kt b/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethod/newImpl/inplace/InplaceMethodExtractor.kt index d0a655a2b0db..a1cfc586c0a8 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethod/newImpl/inplace/InplaceMethodExtractor.kt +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethod/newImpl/inplace/InplaceMethodExtractor.kt @@ -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) diff --git a/java/openapi/resources/messages/JavaRefactoringBundle.properties b/java/openapi/resources/messages/JavaRefactoringBundle.properties index fff0fbbc32cf..f2027ed0870d 100644 --- a/java/openapi/resources/messages/JavaRefactoringBundle.properties +++ b/java/openapi/resources/messages/JavaRefactoringBundle.properties @@ -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