Run full resolve in debugger with write action priority (KT-14602)

#KT-14602 Fixed
This commit is contained in:
Nikolay Krasko
2016-12-06 13:36:08 +03:00
parent 45532e480f
commit fc5b493fd3
5 changed files with 52 additions and 22 deletions
@@ -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 <T> runReadAction(action: () -> T): T {
@@ -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 <T : Any> 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!!
}
@@ -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 <T: PsiElement> getOrComputeClassNames(psiElement: T, create: (T) -> ComputedClassNames): List<String> {
fun <T : PsiElement> getOrComputeClassNames(psiElement: T, create: (T) -> ComputedClassNames): List<String> {
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<String>, val shouldBeCached: Boolean) {
class CachedClassNames(classNames: List<String>): ComputedClassNames(classNames, true) {
constructor(className: String?): this(className.toList())
class CachedClassNames(classNames: List<String>) : ComputedClassNames(classNames, true) {
constructor(className: String?) : this(className.toList())
}
class NonCachedClassNames(classNames: List<String>): ComputedClassNames(classNames, false) {
constructor(className: String?): this(className.toList())
class NonCachedClassNames(classNames: List<String>) : 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)
@@ -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)
}
@@ -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<KtExpression> { expression ->