diff --git a/idea/src/org/jetbrains/kotlin/idea/ProgressUtil.kt b/idea/src/org/jetbrains/kotlin/idea/ProgressUtil.kt index a6a37a68aba..f956f593b05 100644 --- a/idea/src/org/jetbrains/kotlin/idea/ProgressUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/ProgressUtil.kt @@ -39,6 +39,18 @@ fun runInReadActionWithWriteActionPriorityWithPCE(f: () -> T): T { return r!! } +fun runInReadActionWithWriteActionPriority(f: () -> T): T? { + var r: T? = null + val complete = ProgressIndicatorUtils.runInReadActionWithWriteActionPriority { + r = f() + } + + if (!complete) return null + return r +} + + + fun Project.runSynchronouslyWithProgress(progressTitle: String, canBeCanceled: Boolean, action: () -> T): T? { var result: T? = null ProgressManager.getInstance().runProcessWithProgressSynchronously({ result = action() }, progressTitle, canBeCanceled, this) diff --git a/idea/src/org/jetbrains/kotlin/idea/injection/KotlinLanguageInjector.kt b/idea/src/org/jetbrains/kotlin/idea/injection/KotlinLanguageInjector.kt index ba6881b19f5..18ee5f0cf4e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/injection/KotlinLanguageInjector.kt +++ b/idea/src/org/jetbrains/kotlin/idea/injection/KotlinLanguageInjector.kt @@ -38,6 +38,7 @@ import org.intellij.plugins.intelliLang.util.AnnotationUtilEx import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.references.KtReference +import org.jetbrains.kotlin.idea.runInReadActionWithWriteActionPriority import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* @@ -85,9 +86,20 @@ class KotlinLanguageInjector( // Cache is up-to-date kotlinCachedInjection.baseInjection else -> { - val computedInjection = computeBaseInjection(ktHost, support, registrar) ?: ABSENT_KOTLIN_INJECTION - ktHost.cachedInjectionWithModification = KotlinCachedInjection(modificationCount, computedInjection) - computedInjection + fun computeAndCache(): BaseInjection { + val computedInjection = computeBaseInjection(ktHost, support, registrar) ?: ABSENT_KOTLIN_INJECTION + ktHost.cachedInjectionWithModification = KotlinCachedInjection(modificationCount, computedInjection) + return computedInjection + } + + if (ApplicationManager.getApplication().isReadAccessAllowed && ProgressManager.getInstance().progressIndicator == null) { + // The action cannot be canceled by caller and by internal checkCanceled() calls. + // Force creating new indicator that is canceled on write action start, otherwise there might be lags in typing. + runInReadActionWithWriteActionPriority(::computeAndCache) ?: kotlinCachedInjection?.baseInjection ?: ABSENT_KOTLIN_INJECTION + } + else { + computeAndCache() + } } }