diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt index a7e73eeaa08..a6937ee8d42 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt @@ -18,7 +18,6 @@ package org.jetbrains.kotlin.idea.util.application import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.command.CommandProcessor -import com.intellij.openapi.project.DumbService import com.intellij.openapi.project.Project fun runReadAction(action: () -> T): T { diff --git a/idea/src/org/jetbrains/kotlin/idea/ProgressUtil.kt b/idea/src/org/jetbrains/kotlin/idea/ProgressUtil.kt new file mode 100644 index 00000000000..d9a9182b218 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/ProgressUtil.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea + +import com.intellij.openapi.progress.ProcessCanceledException +import com.intellij.openapi.progress.util.ProgressIndicatorUtils + + +fun runInReadActionWithWriteActionPriority(f: () -> T): T { + var r: T? = null + val complete = ProgressIndicatorUtils.runInReadActionWithWriteActionPriority { + r = f() + } + + // There is a write action in progress or pending, so no point in counting the result + if (!complete) throw ProcessCanceledException() + + return r!! +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinDebuggerCaches.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinDebuggerCaches.kt index 787e7f58970..bb2271d89d4 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinDebuggerCaches.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinDebuggerCaches.kt @@ -42,6 +42,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult import org.jetbrains.kotlin.idea.debugger.BinaryCacheKey import org.jetbrains.kotlin.idea.debugger.BytecodeDebugInfo import org.jetbrains.kotlin.idea.debugger.WeakBytecodeDebugInfoStorage +import org.jetbrains.kotlin.idea.runInReadActionWithWriteActionPriority import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.psi.KtCodeFragment import org.jetbrains.kotlin.psi.KtElement @@ -119,7 +120,7 @@ class KotlinDebuggerCaches(project: Project) { return newCompiledData } - fun getOrComputeClassNames(psiElement: T, create: (T) -> ComputedClassNames): List { + fun getOrComputeClassNames(psiElement: T, create: (T) -> ComputedClassNames): List { val cache = getInstance(runReadAction { psiElement.project }) val classNamesCache = cache.cachedClassNames.value @@ -149,21 +150,16 @@ class KotlinDebuggerCaches(project: Project) { val cachedValue = typeMappersCache[key] if (cachedValue != null) return cachedValue - if (!isInLibrary) { - val newValue = createTypeMapperForSourceFile(file) - - typeMappersCache[file] = newValue - - return newValue + val newValue = if (!isInLibrary) { + createTypeMapperForSourceFile(file) } else { val element = getElementToCreateTypeMapperForLibraryFile(psiElement) - val newValue = createTypeMapperForLibraryFile(element, file) - - typeMappersCache[psiElement] = newValue - - return newValue + createTypeMapperForLibraryFile(element, file) } + + typeMappersCache[key] = newValue + return newValue } fun getOrReadDebugInfoFromBytecode( @@ -178,12 +174,12 @@ class KotlinDebuggerCaches(project: Project) { runReadAction { element as? KtElement ?: PsiTreeUtil.getParentOfType(element, KtElement::class.java)!! } private fun createTypeMapperForLibraryFile(element: KtElement, file: KtFile): KotlinTypeMapper = - runReadAction { + runInReadActionWithWriteActionPriority { createTypeMapper(file, element.analyzeAndGetResult()) } private fun createTypeMapperForSourceFile(file: KtFile): KotlinTypeMapper = - runReadAction { + runInReadActionWithWriteActionPriority { createTypeMapper(file, file.analyzeFullyAndGetResult().apply(AnalysisResult::throwIfError)) } @@ -238,14 +234,14 @@ class KotlinDebuggerCaches(project: Project) { data class Parameter(val callText: String, val type: KotlinType, val value: Value? = null) sealed class ComputedClassNames(val classNames: List, val shouldBeCached: Boolean) { - class CachedClassNames(classNames: List): ComputedClassNames(classNames, true) { - constructor(className: String?): this(className.toList()) + class CachedClassNames(classNames: List) : ComputedClassNames(classNames, true) { + constructor(className: String?) : this(className.toList()) } - class NonCachedClassNames(classNames: List): ComputedClassNames(classNames, false) { - constructor(className: String?): this(className.toList()) + class NonCachedClassNames(classNames: List) : ComputedClassNames(classNames, false) { + constructor(className: String?) : this(className.toList()) } } } -private fun String?.toList() = if (this == null) emptyList() else listOf(this) +private fun String?.toList() = if (this == null) emptyList() else listOf(this) \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluationBuilder.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluationBuilder.kt index f30c61faf52..78f7647c70f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluationBuilder.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluationBuilder.kt @@ -62,6 +62,7 @@ import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches.Compiled import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches.ParametersDescriptor import org.jetbrains.kotlin.idea.debugger.evaluate.compilingEvaluator.loadClasses import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.ExtractionResult +import org.jetbrains.kotlin.idea.runInReadActionWithWriteActionPriority import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.util.attachment.attachmentByPsiFile import org.jetbrains.kotlin.idea.util.attachment.mergeAttachments @@ -449,7 +450,7 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour // contextFile must be NotNull when analyzeInlineFunctions = true private fun KtFile.checkForErrors(analyzeInlineFunctions: Boolean = false, contextFile: KtFile? = null): ExtendedAnalysisResult { - return runReadAction { + return runInReadActionWithWriteActionPriority { try { AnalyzingUtils.checkForSyntacticErrors(this) } diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt index d8abe9472f4..a1844056c2b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.idea.intentions.InsertExplicitTypeArgumentsIntention import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.* import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.AnalysisResult.ErrorMessage import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.AnalysisResult.Status +import org.jetbrains.kotlin.idea.runInReadActionWithWriteActionPriority import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.util.attachment.attachmentByPsiFile import org.jetbrains.kotlin.idea.util.attachment.mergeAttachments @@ -156,7 +157,7 @@ private fun KtFile.findContextElement(): KtElement? { private var PsiElement.DEBUG_SMART_CAST: PsiElement? by CopyableUserDataProperty(Key.create("DEBUG_SMART_CAST")) private fun KtCodeFragment.markSmartCasts() { - val bindingContext = analyzeFullyAndGetResult().bindingContext + val bindingContext = runInReadActionWithWriteActionPriority { analyzeFullyAndGetResult() }.bindingContext val factory = KtPsiFactory(project) getContentElement()?.forEachDescendantOfType { expression ->