Rename ResolveInWriteActionManager -> ResolveInDispatchThreadManager

This commit is contained in:
Nikolay Krasko
2019-09-24 14:26:23 +03:00
parent ea56a5e8b1
commit 343502125b
11 changed files with 51 additions and 50 deletions
@@ -16,8 +16,6 @@
package org.jetbrains.kotlin.idea.caches.resolve package org.jetbrains.kotlin.idea.caches.resolve
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.analyzer.AnalysisResult
@@ -26,7 +24,6 @@ import org.jetbrains.kotlin.container.getService
import org.jetbrains.kotlin.container.tryGetService import org.jetbrains.kotlin.container.tryGetService
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.idea.KotlinPluginUtil
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.project.ResolveElementCache import org.jetbrains.kotlin.idea.project.ResolveElementCache
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
@@ -57,7 +54,7 @@ internal class ModuleResolutionFacadeImpl(
} }
override fun analyze(elements: Collection<KtElement>, bodyResolveMode: BodyResolveMode): BindingContext { override fun analyze(elements: Collection<KtElement>, bodyResolveMode: BodyResolveMode): BindingContext {
ResolveInWriteActionManager.assertNoResolveUnderWriteAction() ResolveInDispatchThreadManager.assertNoResolveInDispatchThread()
if (elements.isEmpty()) return BindingContext.EMPTY if (elements.isEmpty()) return BindingContext.EMPTY
val resolveElementCache = getFrontendService(elements.first(), ResolveElementCache::class.java) val resolveElementCache = getFrontendService(elements.first(), ResolveElementCache::class.java)
@@ -65,7 +62,7 @@ internal class ModuleResolutionFacadeImpl(
} }
override fun analyzeWithAllCompilerChecks(elements: Collection<KtElement>): AnalysisResult { override fun analyzeWithAllCompilerChecks(elements: Collection<KtElement>): AnalysisResult {
ResolveInWriteActionManager.assertNoResolveUnderWriteAction() ResolveInDispatchThreadManager.assertNoResolveInDispatchThread()
return projectFacade.getAnalysisResultsForElements(elements) return projectFacade.getAnalysisResultsForElements(elements)
} }
@@ -76,7 +73,7 @@ internal class ModuleResolutionFacadeImpl(
bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration] bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration]
?: getFrontendService(moduleInfo, AbsentDescriptorHandler::class.java).diagnoseDescriptorNotFound(declaration) ?: getFrontendService(moduleInfo, AbsentDescriptorHandler::class.java).diagnoseDescriptorNotFound(declaration)
} else { } else {
ResolveInWriteActionManager.assertNoResolveUnderWriteAction() ResolveInDispatchThreadManager.assertNoResolveInDispatchThread()
val resolveSession = projectFacade.resolverForElement(declaration).componentProvider.get<ResolveSession>() val resolveSession = projectFacade.resolverForElement(declaration).componentProvider.get<ResolveSession>()
resolveSession.resolveToDescriptor(declaration) resolveSession.resolveToDescriptor(declaration)
@@ -11,13 +11,13 @@ import com.intellij.openapi.util.registry.Registry
import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.TestOnly
/** /**
* Temporary allow resolve in write action. * Temporary allow resolve in dispatch thread.
* *
* All resolve should be banned from write action. This method is needed for the transition period to document * All resolve should be banned from the UI thread. This method is needed for the transition period to document
* places that are not fixed yet. * places that are not fixed yet.
*/ */
fun <T> allowResolveInWriteAction(runnable: () -> T): T { fun <T> allowResolveInDispatchThread(runnable: () -> T): T {
return ResolveInWriteActionManager.runWithResolveAllowedInWriteAction(runnable) return ResolveInDispatchThreadManager.runWithResolveAllowedInDispatchThread(runnable)
} }
/** /**
@@ -28,31 +28,36 @@ fun <T> allowResolveInWriteAction(runnable: () -> T): T {
* *
* (A better check is needed instead that would assert no resolve result are obtained outside of caches.) * (A better check is needed instead that would assert no resolve result are obtained outside of caches.)
*/ */
fun <T> allowResolveExpectedToBeCached(runnable: () -> T): T { fun <T> allowCachedResolveInDispatchThread(runnable: () -> T): T {
return ResolveInWriteActionManager.runWithResolveAllowedInWriteAction(runnable) return ResolveInDispatchThreadManager.runWithResolveAllowedInDispatchThread(runnable)
} }
/** /**
* Force resolve check in tests. * Force resolve check in tests as it disabled by default.
*/ */
@TestOnly @TestOnly
fun <T> forceResolveInWriteActionCheckInTests(errorHandler: (() -> Unit)? = null, runnable: () -> T): T { fun <T> forceCheckForResolveInDispatchThreadInTests(errorHandler: (() -> Unit)? = null, runnable: () -> T): T {
return ResolveInWriteActionManager.runWithForceResolveAllowedCheckInTests(errorHandler, runnable) return ResolveInDispatchThreadManager.runWithForceCheckForResolveInDispatchThreadInTests(errorHandler, runnable)
} }
private const val RESOLVE_IN_WRITE_ACTION_ERROR_MESSAGE = "Resolve is not allowed under the write action!" private const val RESOLVE_IN_DISPATCH_THREAD_ERROR_MESSAGE = "Resolve is not allowed in dispatch thread!"
class ResolveInWriteActionException(message: String? = null) : IllegalThreadStateException(message ?: RESOLVE_IN_WRITE_ACTION_ERROR_MESSAGE) class ResolveInDispatchThreadException(message: String? = null) :
IllegalThreadStateException(message ?: RESOLVE_IN_DISPATCH_THREAD_ERROR_MESSAGE)
internal object ResolveInWriteActionManager { internal object ResolveInDispatchThreadManager {
private val LOG = Logger.getInstance(ResolveInWriteActionManager::class.java) private val LOG = Logger.getInstance(ResolveInDispatchThreadManager::class.java)
// Should be accessed only from dispatch thread // Guarded by isDispatchThread check
private var isResolveAllowed: Boolean = false private var isResolveAllowed: Boolean = false
// Guarded by isDispatchThread check
private var isForceCheckInTests: Boolean = false private var isForceCheckInTests: Boolean = false
// Guarded by isDispatchThread check
private var errorHandler: (() -> Unit)? = null private var errorHandler: (() -> Unit)? = null
fun assertNoResolveUnderWriteAction() { internal fun assertNoResolveInDispatchThread() {
val application = ApplicationManager.getApplication() ?: return val application = ApplicationManager.getApplication() ?: return
if (!application.isDispatchThread) { if (!application.isDispatchThread) {
return return
@@ -69,16 +74,16 @@ internal object ResolveInWriteActionManager {
return return
} }
throw ResolveInWriteActionException() throw ResolveInDispatchThreadException()
} else { } else {
@Suppress("InvalidBundleOrProperty") @Suppress("InvalidBundleOrProperty")
if (!Registry.`is`("kotlin.write.resolve.check", false)) return if (!Registry.`is`("kotlin.dispatch.thread.resolve.check", false)) return
LOG.error(RESOLVE_IN_WRITE_ACTION_ERROR_MESSAGE) LOG.error(RESOLVE_IN_DISPATCH_THREAD_ERROR_MESSAGE)
} }
} }
internal inline fun <T> runWithResolveAllowedInWriteAction(runnable: () -> T): T { internal inline fun <T> runWithResolveAllowedInDispatchThread(runnable: () -> T): T {
val wasSet = val wasSet =
if (ApplicationManager.getApplication()?.isDispatchThread == true && !isResolveAllowed) { if (ApplicationManager.getApplication()?.isDispatchThread == true && !isResolveAllowed) {
isResolveAllowed = true isResolveAllowed = true
@@ -95,8 +100,8 @@ internal object ResolveInWriteActionManager {
} }
} }
internal fun <T> runWithForceResolveAllowedCheckInTests(errorHandler: (() -> Unit)?, runnable: () -> T): T { internal fun <T> runWithForceCheckForResolveInDispatchThreadInTests(errorHandler: (() -> Unit)?, runnable: () -> T): T {
ApplicationManager.getApplication()?.assertIsDispatchThread() ApplicationManager.getApplication()?.assertIsDispatchThread() ?: error("Application is not available")
val wasSet = if (!isForceCheckInTests) { val wasSet = if (!isForceCheckInTests) {
isForceCheckInTests = true isForceCheckInTests = true
@@ -11,7 +11,7 @@ import com.intellij.psi.PsiClass
import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiDocumentManager
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.allowResolveInWriteAction import org.jetbrains.kotlin.idea.caches.resolve.allowResolveInDispatchThread
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.completion.isAfterDot import org.jetbrains.kotlin.idea.completion.isAfterDot
import org.jetbrains.kotlin.idea.completion.isArtificialImportAliasedDescriptor import org.jetbrains.kotlin.idea.completion.isArtificialImportAliasedDescriptor
@@ -53,7 +53,7 @@ object KotlinClassifierInsertHandler : BaseDeclarationInsertHandler() {
val token = file.findElementAt(startOffset)!! val token = file.findElementAt(startOffset)!!
val nameRef = token.parent as? KtNameReferenceExpression val nameRef = token.parent as? KtNameReferenceExpression
if (nameRef != null) { if (nameRef != null) {
val bindingContext = allowResolveInWriteAction { nameRef.analyze(BodyResolveMode.PARTIAL) } val bindingContext = allowResolveInDispatchThread { nameRef.analyze(BodyResolveMode.PARTIAL) }
val target = bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, nameRef] val target = bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, nameRef]
?: bindingContext[BindingContext.REFERENCE_TARGET, nameRef] as? ClassDescriptor ?: bindingContext[BindingContext.REFERENCE_TARGET, nameRef] as? ClassDescriptor
if (target != null && IdeDescriptorRenderers.SOURCE_CODE.renderClassifierName(target) == qualifiedName) return if (target != null && IdeDescriptorRenderers.SOURCE_CODE.renderClassifierName(target) == qualifiedName) return
@@ -13,7 +13,7 @@ import com.intellij.psi.impl.source.PostprocessReformattingAspect
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.analysis.analyzeAsReplacement import org.jetbrains.kotlin.idea.analysis.analyzeAsReplacement
import org.jetbrains.kotlin.idea.caches.resolve.allowResolveInWriteAction import org.jetbrains.kotlin.idea.caches.resolve.allowResolveInDispatchThread
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport
import org.jetbrains.kotlin.idea.imports.getImportableTargets import org.jetbrains.kotlin.idea.imports.getImportableTargets
@@ -200,7 +200,7 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
// step 2: analyze collected elements with resolve and decide which can be shortened now and which need descriptors to be imported before shortening // 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 allElementsToAnalyze = visitors.flatMap { visitor -> visitor.getElementsToAnalyze().map { it.element } }.toSet()
val bindingContext = allowResolveInWriteAction { val bindingContext = allowResolveInDispatchThread {
file.getResolutionFacade().analyze(allElementsToAnalyze, BodyResolveMode.PARTIAL_WITH_CFA) file.getResolutionFacade().analyze(allElementsToAnalyze, BodyResolveMode.PARTIAL_WITH_CFA)
} }
@@ -33,7 +33,7 @@ import org.intellij.plugins.intelliLang.inject.java.JavaLanguageInjectionSupport
import org.intellij.plugins.intelliLang.util.AnnotationUtilEx import org.intellij.plugins.intelliLang.util.AnnotationUtilEx
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.idea.caches.resolve.allowResolveInWriteAction import org.jetbrains.kotlin.idea.caches.resolve.allowResolveInDispatchThread
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.util.runInReadActionWithWriteActionPriority import org.jetbrains.kotlin.idea.core.util.runInReadActionWithWriteActionPriority
import org.jetbrains.kotlin.idea.patterns.KotlinFunctionPattern import org.jetbrains.kotlin.idea.patterns.KotlinFunctionPattern
@@ -269,7 +269,7 @@ class KotlinLanguageInjector(
for (reference in callee.references) { for (reference in callee.references) {
ProgressManager.checkCanceled() ProgressManager.checkCanceled()
val resolvedTo = allowResolveInWriteAction { reference.resolve() } val resolvedTo = allowResolveInDispatchThread { reference.resolve() }
if (resolvedTo is PsiMethod) { if (resolvedTo is PsiMethod) {
val injectionForJavaMethod = injectionForJavaMethod(argument, resolvedTo) val injectionForJavaMethod = injectionForJavaMethod(argument, resolvedTo)
if (injectionForJavaMethod != null) { if (injectionForJavaMethod != null) {
@@ -298,7 +298,7 @@ class KotlinLanguageInjector(
if (!fastCheckInjectionsExists(annotationEntry)) return null if (!fastCheckInjectionsExists(annotationEntry)) return null
val calleeExpression = annotationEntry.calleeExpression ?: return null val calleeExpression = annotationEntry.calleeExpression ?: return null
val callee = getNameReference(calleeExpression)?.mainReference?.let { reference -> val callee = getNameReference(calleeExpression)?.mainReference?.let { reference ->
allowResolveInWriteAction { reference.resolve() } allowResolveInDispatchThread { reference.resolve() }
} }
when (callee) { when (callee) {
is PsiClass -> { is PsiClass -> {
@@ -346,7 +346,7 @@ class KotlinLanguageInjector(
// Found psi element after resolve can be obtained from compiled declaration but annotations parameters are lost there. // Found psi element after resolve can be obtained from compiled declaration but annotations parameters are lost there.
// Search for original descriptor from reference. // Search for original descriptor from reference.
val ktReference = reference as? KtReference ?: return null val ktReference = reference as? KtReference ?: return null
val functionDescriptor = allowResolveInWriteAction { val functionDescriptor = allowResolveInDispatchThread {
val bindingContext = ktReference.element.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS) val bindingContext = ktReference.element.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS)
ktReference.resolveToDescriptors(bindingContext).singleOrNull() as? FunctionDescriptor ktReference.resolveToDescriptors(bindingContext).singleOrNull() as? FunctionDescriptor
} ?: return null } ?: return null
+1 -1
View File
@@ -383,7 +383,7 @@
<errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/> <errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/>
<registryKey <registryKey
key="kotlin.write.resolve.check" key="kotlin.dispatch.thread.resolve.check"
description="Whether to enable the check for resolve activated from the write action" description="Whether to enable the check for resolve activated from the write action"
defaultValue="false" defaultValue="false"
restartRequired="false"/> restartRequired="false"/>
@@ -33,7 +33,7 @@ import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.allowResolveInWriteAction import org.jetbrains.kotlin.idea.caches.resolve.allowResolveInDispatchThread
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedRefactoringRequests import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedRefactoringRequests
@@ -130,7 +130,7 @@ class KotlinCopyPasteReferenceProcessor : CopyPastePostProcessor<KotlinReference
val allElementsToResolve = elementsByRange.values.flatten().flatMap { it.collectDescendantsOfType<KtElement>() } val allElementsToResolve = elementsByRange.values.flatten().flatMap { it.collectDescendantsOfType<KtElement>() }
val bindingContext = val bindingContext =
allowResolveInWriteAction { allowResolveInDispatchThread {
file.getResolutionFacade().analyze(allElementsToResolve, BodyResolveMode.PARTIAL) file.getResolutionFacade().analyze(allElementsToResolve, BodyResolveMode.PARTIAL)
} }
@@ -20,7 +20,7 @@ import com.intellij.lang.SmartEnterProcessorWithFixers
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.builtins.isFunctionType
import org.jetbrains.kotlin.idea.caches.resolve.allowResolveInWriteAction import org.jetbrains.kotlin.idea.caches.resolve.allowResolveInDispatchThread
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.idea.editor.KotlinSmartEnterHandler import org.jetbrains.kotlin.idea.editor.KotlinSmartEnterHandler
import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtCallExpression
@@ -30,7 +30,7 @@ class KotlinLastLambdaParameterFixer : SmartEnterProcessorWithFixers.Fixer<Kotli
override fun apply(editor: Editor, processor: KotlinSmartEnterHandler, element: PsiElement) { override fun apply(editor: Editor, processor: KotlinSmartEnterHandler, element: PsiElement) {
if (element !is KtCallExpression) return if (element !is KtCallExpression) return
val resolvedCall = allowResolveInWriteAction { element.resolveToCall() } ?: return val resolvedCall = allowResolveInDispatchThread { element.resolveToCall() } ?: return
val valueParameters = resolvedCall.candidateDescriptor.valueParameters val valueParameters = resolvedCall.candidateDescriptor.valueParameters
@@ -10,7 +10,7 @@ import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.idea.caches.resolve.allowResolveExpectedToBeCached import org.jetbrains.kotlin.idea.caches.resolve.allowCachedResolveInDispatchThread
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
abstract class KotlinQuickFixAction<out T : PsiElement>(element: T) : QuickFixActionBase<T>(element) { abstract class KotlinQuickFixAction<out T : PsiElement>(element: T) : QuickFixActionBase<T>(element) {
@@ -18,7 +18,7 @@ abstract class KotlinQuickFixAction<out T : PsiElement>(element: T) : QuickFixAc
override fun isAvailableImpl(project: Project, editor: Editor?, file: PsiFile): Boolean { override fun isAvailableImpl(project: Project, editor: Editor?, file: PsiFile): Boolean {
val ktFile = file as? KtFile ?: return false val ktFile = file as? KtFile ?: return false
return allowResolveExpectedToBeCached { return allowCachedResolveInDispatchThread {
// Quick fixes availability is checked in UI thread but only after background highlighting pass is finished // Quick fixes availability is checked in UI thread but only after background highlighting pass is finished
// so we are expecting that every relevant results are already cached. // so we are expecting that every relevant results are already cached.
isAvailable(project, editor, ktFile) isAvailable(project, editor, ktFile)
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.idea.conversion.copy
import com.intellij.openapi.actionSystem.IdeActions import com.intellij.openapi.actionSystem.IdeActions
import org.jetbrains.kotlin.idea.AbstractCopyPasteTest import org.jetbrains.kotlin.idea.AbstractCopyPasteTest
import org.jetbrains.kotlin.idea.caches.resolve.forceResolveInWriteActionCheckInTests import org.jetbrains.kotlin.idea.caches.resolve.forceCheckForResolveInDispatchThreadInTests
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File import java.io.File
@@ -26,13 +26,13 @@ abstract class AbstractLiteralTextToKotlinCopyPasteTest : AbstractCopyPasteTest(
if (!myFixture.editor.selectionModel.hasSelection()) if (!myFixture.editor.selectionModel.hasSelection())
myFixture.editor.selectionModel.setSelection(0, fileText.length) myFixture.editor.selectionModel.setSelection(0, fileText.length)
forceResolveInWriteActionCheckInTests { forceCheckForResolveInDispatchThreadInTests {
myFixture.performEditorAction(IdeActions.ACTION_COPY) myFixture.performEditorAction(IdeActions.ACTION_COPY)
} }
configureTargetFile(targetFileName) configureTargetFile(targetFileName)
forceResolveInWriteActionCheckInTests { forceCheckForResolveInDispatchThreadInTests {
myFixture.performEditorAction(IdeActions.ACTION_PASTE) myFixture.performEditorAction(IdeActions.ACTION_PASTE)
} }
@@ -16,13 +16,12 @@ import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.CharsetToolkit import com.intellij.openapi.vfs.CharsetToolkit
import com.intellij.rt.execution.junit.FileComparisonFailure import com.intellij.rt.execution.junit.FileComparisonFailure
import com.intellij.testFramework.LightPlatformTestCase
import com.intellij.testFramework.LightProjectDescriptor import com.intellij.testFramework.LightProjectDescriptor
import com.intellij.testFramework.UsefulTestCase import com.intellij.testFramework.UsefulTestCase
import com.intellij.util.ui.UIUtil import com.intellij.util.ui.UIUtil
import junit.framework.TestCase import junit.framework.TestCase
import org.jetbrains.kotlin.idea.caches.resolve.ResolveInWriteActionException import org.jetbrains.kotlin.idea.caches.resolve.ResolveInDispatchThreadException
import org.jetbrains.kotlin.idea.caches.resolve.forceResolveInWriteActionCheckInTests import org.jetbrains.kotlin.idea.caches.resolve.forceCheckForResolveInDispatchThreadInTests
import org.jetbrains.kotlin.idea.facet.KotlinFacet import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.idea.test.* import org.jetbrains.kotlin.idea.test.*
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
@@ -179,12 +178,12 @@ abstract class AbstractQuickFixTest : KotlinLightCodeInsightFixtureTestCase(), Q
val intentionClassName = unwrappedIntention.javaClass.name val intentionClassName = unwrappedIntention.javaClass.name
if (!quickFixesAllowedToResolveInWriteAction.isWriteActionAllowed(intentionClassName)) { if (!quickFixesAllowedToResolveInWriteAction.isWriteActionAllowed(intentionClassName)) {
throw ResolveInWriteActionException("Resolve is not allowed under the write action for `$intentionClassName`!") throw ResolveInDispatchThreadException("Resolve is not allowed under the write action for `$intentionClassName`!")
} }
} }
val stubComparisonFailure: ComparisonFailure? = try { val stubComparisonFailure: ComparisonFailure? = try {
forceResolveInWriteActionCheckInTests(writeActionResolveHandler) { forceCheckForResolveInDispatchThreadInTests(writeActionResolveHandler) {
myFixture.launchAction(intention) myFixture.launchAction(intention)
} }
null null