From 71d76bdb4b222737f181ebbe5fb58c8267cf2865 Mon Sep 17 00:00:00 2001 From: Vladimir Dolzhenko Date: Mon, 5 Oct 2020 18:00:02 +0200 Subject: [PATCH] Revert "Perform shorten references under modal dialog" This reverts commit 0b822aa4 --- .../shorten/delayedRequestsWaitingSet.kt | 24 ++---- .../idea/references/KtSimpleNameReference.kt | 23 +++--- .../messages/KotlinIdeaCoreBundle.properties | 2 - .../kotlin/idea/core/ShortenReferences.kt | 79 ++++++------------- .../kotlin/idea/util/ApplicationUtils.kt | 14 +--- .../kotlin/idea/util/ApplicationUtils.kt.193 | 13 --- .../kotlin/idea/util/ApplicationUtils.kt.as40 | 13 --- .../KotlinCopyPasteReferenceProcessor.kt | 42 +++++----- 8 files changed, 60 insertions(+), 150 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/codeInsight/shorten/delayedRequestsWaitingSet.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/codeInsight/shorten/delayedRequestsWaitingSet.kt index 9fc4b9843fe..4e95634afea 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/codeInsight/shorten/delayedRequestsWaitingSet.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/codeInsight/shorten/delayedRequestsWaitingSet.kt @@ -16,20 +16,17 @@ package org.jetbrains.kotlin.idea.codeInsight.shorten -import com.intellij.openapi.application.runReadAction +import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.project.Project import com.intellij.openapi.util.Key import com.intellij.psi.* -import com.intellij.psi.codeStyle.CodeStyleManager import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMemberDescriptor import org.jetbrains.kotlin.idea.core.ShortenReferences import org.jetbrains.kotlin.idea.core.ShortenReferences.Options import org.jetbrains.kotlin.idea.util.ImportInsertHelper -import org.jetbrains.kotlin.idea.util.application.assertIsDispatchThread -import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType @@ -76,14 +73,14 @@ private fun Project.getOrCreateRefactoringRequests(): MutableSet - runReadAction { req.pointer.element }?.let { it to req.options } - }.toMap() + val elementToOptions = shorteningRequests.mapNotNull { req -> req.pointer.element?.let { it to req.options } }.toMap() val elements = elementToOptions.keys - val files = runReadAction { elements.map(KtElement::getContainingKtFile).toSet() } //TODO: this is not correct because it should not shorten deep into the elements! ShortenReferences { elementToOptions[it] ?: Options.DEFAULT }.process(elements) - files.forEach { file -> - file.importList?.let { importList -> - runWriteAction { - CodeStyleManager.getInstance(file.project).reformat(importList, true) - } - } - } - val importInsertHelper = ImportInsertHelper.getInstance(project) for ((file, requestsForFile) in importRequests.groupBy { it.filePointer.element }) { if (file == null) continue for (requestForFile in requestsForFile) { - val elementToImport = runReadAction { requestForFile.elementToImportPointer.element }?.unwrapped ?: continue + val elementToImport = requestForFile.elementToImportPointer.element?.unwrapped ?: continue val descriptorToImport = when (elementToImport) { is KtDeclaration -> elementToImport.unsafeResolveToDescriptor(BodyResolveMode.PARTIAL) is PsiMember -> elementToImport.getJavaMemberDescriptor() diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/KtSimpleNameReference.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/KtSimpleNameReference.kt index adcc8f6e598..8129ba0d0e0 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/KtSimpleNameReference.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/KtSimpleNameReference.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.references import com.intellij.openapi.extensions.Extensions import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiElement +import com.intellij.psi.PsiReference import com.intellij.psi.util.PsiTreeUtil import com.intellij.util.IncorrectOperationException import com.intellij.util.SmartList @@ -20,7 +21,6 @@ import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet import org.jetbrains.kotlin.idea.core.* import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName -import org.jetbrains.kotlin.idea.util.application.disablePostprocessFormattingInside import org.jetbrains.kotlin.lexer.KtToken import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor @@ -171,18 +171,15 @@ class KtSimpleNameReferenceDescriptorsImpl( if (expression !is KtNameReferenceExpression) return expression if (expression.parent is KtThisExpression || expression.parent is KtSuperExpression) return expression // TODO: it's a bad design of PSI tree, we should change it - val newExpression = - expression.project.disablePostprocessFormattingInside { - expression.changeQualifiedName( - fqName.quoteIfNeeded().let { - if (shorteningMode == ShorteningMode.NO_SHORTENING) - it - else - it.withRootPrefixIfNeeded(expression) - }, - targetElement - ) - } + val newExpression = expression.changeQualifiedName( + fqName.quoteIfNeeded().let { + if (shorteningMode == ShorteningMode.NO_SHORTENING) + it + else + it.withRootPrefixIfNeeded(expression) + }, + targetElement + ) val newQualifiedElement = newExpression.getQualifiedElementOrCallableRef() if (shorteningMode == ShorteningMode.NO_SHORTENING) return newExpression diff --git a/idea/idea-core/resources/messages/KotlinIdeaCoreBundle.properties b/idea/idea-core/resources/messages/KotlinIdeaCoreBundle.properties index e4a8f3646b3..038d79eceda 100644 --- a/idea/idea-core/resources/messages/KotlinIdeaCoreBundle.properties +++ b/idea/idea-core/resources/messages/KotlinIdeaCoreBundle.properties @@ -15,5 +15,3 @@ text.loading.kotlin.script.definitions=Loading kotlin script definitions text.loading.kotlin.script.configuration=Loading script configuration implement.members.handler.title=Implement Members override.members.handler.title=Override Members -shorten.references=Shortening references -shorten.references.pass.0=Shortening references, pass {0} diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt index a93598e3bd2..9fc6a07ed6f 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt @@ -5,27 +5,22 @@ package org.jetbrains.kotlin.idea.core -import com.intellij.openapi.diagnostic.Logger -import com.intellij.openapi.progress.ProgressManager +import com.intellij.openapi.application.runReadAction import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiElement import com.intellij.psi.SmartPsiElementPointer +import com.intellij.psi.impl.source.PostprocessReformattingAspect import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.analysis.analyzeAsReplacement import org.jetbrains.kotlin.idea.caches.resolve.allowResolveInDispatchThread import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade -import org.jetbrains.kotlin.idea.core.util.KotlinIdeaCoreBundle import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport import org.jetbrains.kotlin.idea.imports.getImportableTargets import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.references.resolveToDescriptors import org.jetbrains.kotlin.idea.util.* -import org.jetbrains.kotlin.idea.util.application.disablePostprocessFormattingInside -import org.jetbrains.kotlin.idea.util.application.isWriteAccessAllowed -import org.jetbrains.kotlin.idea.util.application.runReadAction -import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* @@ -59,8 +54,6 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT } companion object { - private val LOG = Logger.getInstance(ShortenReferences::class.java) - @JvmField val DEFAULT = ShortenReferences() @@ -197,8 +190,7 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT //TODO: that's not correct since we have options! val elementsToUse = dropNestedElements(elements) - val project = file.project - val helper = ImportInsertHelper.getInstance(project) + val helper = ImportInsertHelper.getInstance(file.project) val failedToImportDescriptors = LinkedHashSet() @@ -210,9 +202,7 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT } } - var pass = 0 while (true) { - pass++ // Processors order is important here so that enclosing elements are not shortened before their children are, e.g. // test.foo(this@A) -> foo(this) val processors: List> = runReadAction { @@ -224,41 +214,24 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT ) } - val step1And2 = { - // step 1: collect qualified elements to analyze (no resolve at this step) - val visitors = processors.map { it.collectElementsVisitor } - runReadAction { - for (visitor in visitors) { - for (element in elementsToUse) { - visitor.options = options(element) - element.accept(visitor) - } + // step 1: collect qualified elements to analyze (no resolve at this step) + val visitors = processors.map { it.collectElementsVisitor } + runReadAction { + for (visitor in visitors) { + for (element in elementsToUse) { + visitor.options = options(element) + element.accept(visitor) } - - // step 2: analyze collected elements with resolve and decide which can be shortened now and which need descriptors to be imported before shortening - val allElementsToAnalyze = visitors.flatMap { visitor -> visitor.getElementsToAnalyze().map { it.element } }.toSet() - - val bindingContext = - if (isWriteAccessAllowed()) { - allowResolveInDispatchThread { - file.getResolutionFacade().analyze(allElementsToAnalyze, BodyResolveMode.PARTIAL_WITH_CFA) - } - } else { - file.getResolutionFacade().analyze(allElementsToAnalyze, BodyResolveMode.PARTIAL_WITH_CFA) - } - - - processors.forEach { it.analyzeCollectedElements(bindingContext) } } - } - if (isWriteAccessAllowed()) { - LOG.warn("Shorten reference should not be invoked under write action") - step1And2.invoke() - } else { - ProgressManager.getInstance().runProcessWithProgressSynchronously( - step1And2, KotlinIdeaCoreBundle.message("shorten.references.pass.0", pass), false, project - ) + + // step 2: analyze collected elements with resolve and decide which can be shortened now and which need descriptors to be imported before shortening + val allElementsToAnalyze = visitors.flatMap { visitor -> visitor.getElementsToAnalyze().map { it.element } }.toSet() + val bindingContext = allowResolveInDispatchThread { + file.getResolutionFacade().analyze(allElementsToAnalyze, BodyResolveMode.PARTIAL_WITH_CFA) + } + + processors.forEach { it.analyzeCollectedElements(bindingContext) } } // step 3: shorten elements that can be shortened right now @@ -274,10 +247,7 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT for (descriptor in descriptorsToImport) { assert(descriptor !in failedToImportDescriptors) - val result = - runWriteAction { - helper.importDescriptor(file, descriptor) - } + val result = helper.importDescriptor(file, descriptor) if (result != ImportDescriptorResult.ALREADY_IMPORTED) { anyChange = true } @@ -417,9 +387,10 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT val element = elementPointer.element ?: continue if (!element.isValid) continue + var newElement: KtElement? = null // we never want any reformatting to happen because sometimes it causes strange effects (see KT-11633) - val newElement = element.project.disablePostprocessFormattingInside { - runWriteAction { shortenElement(element, options(element)) } + PostprocessReformattingAspect.getInstance(element.project).disablePostprocessFormattingInside { + newElement = shortenElement(element, options(element)) } if (element in elementSetToUpdate && newElement != element) { @@ -431,10 +402,8 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT fun removeRootPrefixes() { for (pointer in collectElementsVisitor.getElementsWithRootPrefix()) { - val element = runReadAction { pointer.element } ?: continue - runWriteAction { - shortenElement(element, Options.DEFAULT) - } + val element = pointer.element ?: continue + shortenElement(element, Options.DEFAULT) } } diff --git a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt index ada6e769db7..77f9eb8dfc5 100644 --- a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt @@ -11,8 +11,6 @@ import com.intellij.openapi.components.ComponentManager import com.intellij.openapi.progress.impl.CancellationCheck import com.intellij.openapi.project.DumbService import com.intellij.openapi.project.Project -import com.intellij.openapi.util.Computable -import com.intellij.psi.impl.source.PostprocessReformattingAspect fun runReadAction(action: () -> T): T { return ApplicationManager.getApplication().runReadAction(action) @@ -55,15 +53,6 @@ inline fun invokeLater(crossinline action: () -> Unit) = ApplicationManager.getApplication().invokeLater { action() } inline fun isUnitTestMode(): Boolean = ApplicationManager.getApplication().isUnitTestMode -inline fun isReadAccessAllowed() = ApplicationManager.getApplication().isReadAccessAllowed -inline fun isWriteAccessAllowed() = ApplicationManager.getApplication().isWriteAccessAllowed -inline fun isDispatchThread() = ApplicationManager.getApplication().isDispatchThread -inline fun assertWriteAccessAllowed() = ApplicationManager.getApplication().assertWriteAccessAllowed() -inline fun assertReadAccessAllowed() = ApplicationManager.getApplication().assertReadAccessAllowed() -inline fun assertIsDispatchThread() = ApplicationManager.getApplication().assertIsDispatchThread() - -inline fun Project.disablePostprocessFormattingInside(action: Computable): T = - PostprocessReformattingAspect.getInstance(this).disablePostprocessFormattingInside(action) inline fun ComponentManager.getServiceSafe(): T = this.getService(T::class.java) ?: error("Unable to locate service ${T::class.java.name}") @@ -71,5 +60,4 @@ inline fun ComponentManager.getServiceSafe(): T = fun Project.runReadActionInSmartMode(action: () -> T): T { if (ApplicationManager.getApplication().isReadAccessAllowed) return action() return DumbService.getInstance(this).runReadActionInSmartMode(action) -} - +} \ No newline at end of file diff --git a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt.193 b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt.193 index 6e0988c994f..39e98ebdfad 100644 --- a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt.193 +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt.193 @@ -11,8 +11,6 @@ import com.intellij.openapi.components.ComponentManager import com.intellij.openapi.project.Project import org.jetbrains.annotations.Nls import com.intellij.openapi.project.DumbService -import com.intellij.openapi.util.Computable -import com.intellij.psi.impl.source.PostprocessReformattingAspect fun runReadAction(action: () -> T): T { return ApplicationManager.getApplication().runReadAction(action) @@ -46,17 +44,6 @@ inline fun invokeLater(crossinline action: () -> Unit) = ApplicationManager.getApplication().invokeLater { action() } inline fun isUnitTestMode(): Boolean = ApplicationManager.getApplication().isUnitTestMode -inline fun isReadAccessAllowed() = ApplicationManager.getApplication().isReadAccessAllowed -inline fun isWriteAccessAllowed() = ApplicationManager.getApplication().isWriteAccessAllowed -inline fun isDispatchThread() = ApplicationManager.getApplication().isDispatchThread -inline fun assertWriteAccessAllowed() = - assert(isWriteAccessAllowed()) { "Write access is allowed inside write-action only (see com.intellij.openapi.application.Application.runWriteAction())" } -inline fun assertReadAccessAllowed() = - assert(isReadAccessAllowed()) { "Read access is allowed from event dispatch thread or inside read-action only (see com.intellij.openapi.application.Application.runReadAction())" } -inline fun assertIsDispatchThread() = ApplicationManager.getApplication().assertIsDispatchThread() - -inline fun Project.disablePostprocessFormattingInside(action: Computable): T = - PostprocessReformattingAspect.getInstance(this).disablePostprocessFormattingInside(action) inline fun ComponentManager.getServiceSafe(): T = this.getService(T::class.java) ?: error("Unable to locate service ${T::class.java.name}") diff --git a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt.as40 b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt.as40 index e509224293a..aebd7211d12 100644 --- a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt.as40 +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt.as40 @@ -25,8 +25,6 @@ import com.intellij.openapi.progress.ProgressIndicatorProvider import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.project.Project import com.intellij.openapi.project.DumbService -import com.intellij.openapi.util.Computable -import com.intellij.psi.impl.source.PostprocessReformattingAspect fun runReadAction(action: () -> T): T { return ApplicationManager.getApplication().runReadAction(action) @@ -60,17 +58,6 @@ inline fun invokeLater(crossinline action: () -> Unit) = ApplicationManager.getApplication().invokeLater { action() } inline fun isUnitTestMode(): Boolean = ApplicationManager.getApplication().isUnitTestMode -inline fun isReadAccessAllowed() = ApplicationManager.getApplication().isReadAccessAllowed -inline fun isWriteAccessAllowed() = ApplicationManager.getApplication().isWriteAccessAllowed -inline fun isDispatchThread() = ApplicationManager.getApplication().isDispatchThread -inline fun assertWriteAccessAllowed() = - assert(isWriteAccessAllowed()) { "Write access is allowed inside write-action only (see com.intellij.openapi.application.Application.runWriteAction())" } -inline fun assertReadAccessAllowed() = - assert(isReadAccessAllowed()) { "Read access is allowed from event dispatch thread or inside read-action only (see com.intellij.openapi.application.Application.runReadAction())" } -inline fun assertIsDispatchThread() = ApplicationManager.getApplication().assertIsDispatchThread() - -inline fun Project.disablePostprocessFormattingInside(action: Computable): T = - PostprocessReformattingAspect.getInstance(this).disablePostprocessFormattingInside(action) inline fun ComponentManager.getServiceSafe(): T = this.getService(T::class.java) ?: error("Unable to locate service ${T::class.java.name}") diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinCopyPasteReferenceProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinCopyPasteReferenceProcessor.kt index 7aefe1c11bf..166aac235d5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinCopyPasteReferenceProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinCopyPasteReferenceProcessor.kt @@ -9,7 +9,6 @@ import com.intellij.codeInsight.CodeInsightSettings import com.intellij.codeInsight.editorActions.CopyPastePostProcessor import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ReadAction -import com.intellij.openapi.command.CommandProcessor import com.intellij.openapi.diagnostic.ControlFlowException import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.editor.Editor @@ -44,8 +43,10 @@ import org.jetbrains.kotlin.idea.core.util.start import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.references.* import org.jetbrains.kotlin.idea.util.* -import org.jetbrains.kotlin.idea.util.application.* -import org.jetbrains.kotlin.idea.util.runReadActionInSmartMode +import org.jetbrains.kotlin.idea.util.application.executeWriteCommand +import org.jetbrains.kotlin.idea.util.application.invokeLater +import org.jetbrains.kotlin.idea.util.application.isUnitTestMode +import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.kdoc.psi.api.KDocElement import org.jetbrains.kotlin.name.FqName @@ -375,10 +376,12 @@ class KotlinCopyPasteReferenceProcessor : CopyPastePostProcessor() - restoreReferences(selectedReferencesToRestore, file, imported) + project.executeWriteCommand(KotlinBundle.message("resolve.pasted.references")) { + val imported = TreeSet() + restoreReferences(selectedReferencesToRestore, file, imported) - reviewAddedImports(project, editor, file, imported) + reviewAddedImports(project, editor, file, imported) + } } } @@ -686,9 +689,8 @@ class KotlinCopyPasteReferenceProcessor : CopyPastePostProcessor ) { - val project = file.project - val importHelper = ImportInsertHelper.getInstance(project) - val smartPointerManager = SmartPointerManager.getInstance(project) + val importHelper = ImportInsertHelper.getInstance(file.project) + val smartPointerManager = SmartPointerManager.getInstance(file.project) data class BindingRequest( val pointer: SmartPsiElementPointer, @@ -715,22 +717,18 @@ class KotlinCopyPasteReferenceProcessor : CopyPastePostProcessor {