Wrap KtClassOrObject.isLocal, KtFile.isScript with runReadAction in LightClasses

#EA-211576 Fixed

(cherry picked from commit 75a59d4bced714af51abd7e354bc873313b28051)
This commit is contained in:
Vladimir Dolzhenko
2019-10-26 09:42:49 +02:00
parent 96768cbf2d
commit 00055fc20a
5 changed files with 25 additions and 14 deletions
@@ -53,7 +53,6 @@ import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.util.isOrdinaryClass
import java.util.*
import javax.swing.Icon
@@ -359,7 +358,7 @@ abstract class KtLightClassForSourceDeclaration(
classOrObject is KtObjectDeclaration && classOrObject.isObjectLiteral() ->
KtLightClassForAnonymousDeclaration(classOrObject)
classOrObject.isLocal ->
classOrObject.safeIsLocal() ->
KtLightClassForLocalDeclaration(classOrObject)
else ->
@@ -372,9 +371,9 @@ abstract class KtLightClassForSourceDeclaration(
return InvalidLightClassDataHolder
}
val containingScript = classOrObject.containingKtFile.script
val containingScript = classOrObject.containingKtFile.safeScript()
return when {
!classOrObject.isLocal && containingScript != null ->
!classOrObject.safeIsLocal() && containingScript != null ->
KtLightClassForScript.getLightClassCachedValue(containingScript).value
else ->
getLightClassCachedValue(classOrObject).value
@@ -546,7 +545,7 @@ fun KtClassOrObject.shouldNotBeVisibleAsLightClass(): Boolean {
return true
}
if (isLocal) {
if (safeIsLocal()) {
if (containingFile.virtualFile == null) return true
if (hasParseErrorsAround(this) || PsiUtilCore.hasErrorElementChild(this)) return true
}
@@ -581,4 +580,4 @@ private fun hasParseErrorsAround(psi: PsiElement): Boolean {
}
return false
}
}
@@ -52,7 +52,7 @@ fun PsiReferenceList.addSuperTypeEntry(
internal fun KtClassOrObject.getExternalDependencies(): List<ModificationTracker> {
return with(KotlinModificationTrackerService.getInstance(project)) {
if (!isLocal) return listOf(outOfBlockModificationTracker)
if (!safeIsLocal()) return listOf(outOfBlockModificationTracker)
else when (val file = containingFile) {
is KtFile -> listOf(outOfBlockModificationTracker, fileModificationTracker(file))
else -> listOf(outOfBlockModificationTracker)
@@ -6,7 +6,9 @@
package org.jetbrains.kotlin.asJava.classes
import com.google.common.collect.Lists
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Computable
import com.intellij.psi.*
import com.intellij.psi.impl.cache.ModifierFlags
import com.intellij.psi.impl.cache.TypeInfo
@@ -184,10 +186,9 @@ fun createTypeFromCanonicalText(
}
fun tryGetPredefinedName(klass: ClassDescriptor): String? {
val sourceClass = (klass.source as? KotlinSourceElement)?.psi as? KtClassOrObject
return if (sourceClass?.isLocal == true)
return if (sourceClass?.safeIsLocal() == true)
(sourceClass.nameAsName ?: SpecialNames.NO_NAME_PROVIDED).asString()
else null
}
@@ -380,3 +381,14 @@ internal inline fun Project.applyCompilerPlugins(body: (UltraLightClassModifierE
internal fun <L : Any> L.invalidAccess(): Nothing =
error("Cls delegate shouldn't be loaded for not too complex ultra-light classes! Qualified name: ${javaClass.name}")
inline fun <T> runReadAction(crossinline runnable: () -> T): T {
return ApplicationManager.getApplication().runReadAction(Computable { runnable() })
}
inline fun KtClassOrObject.safeIsLocal(): Boolean = runReadAction { this.isLocal }
inline fun KtFile.safeIsScript() = runReadAction { this.isScript() }
inline fun KtFile.safeScript() = runReadAction { this.script }
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder
import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForFileFacade
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject
import org.jetbrains.kotlin.asJava.classes.safeIsScript
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory.cast
import org.jetbrains.kotlin.diagnostics.Errors.*
@@ -57,7 +58,7 @@ fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Diagnostic
fun doGetDiagnostics(): Diagnostics? {
//TODO: enable this diagnostic when light classes for scripts are ready
if ((element.containingFile as? KtFile)?.isScript() == true) return null
if ((element.containingFile as? KtFile)?.safeIsScript() == true) return null
var parent = element.parent
if (element is KtPropertyAccessor) {
@@ -129,7 +129,7 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
override fun createUltraLightClass(element: KtClassOrObject): KtUltraLightClass? {
if (element.shouldNotBeVisibleAsLightClass() ||
element is KtEnumEntry ||
element.containingKtFile.isScript()
element.containingKtFile.safeIsScript()
) {
return null
}
@@ -139,7 +139,7 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
element is KtObjectDeclaration && element.isObjectLiteral() ->
KtUltraLightClassForAnonymousDeclaration(element, support)
element.isLocal ->
element.safeIsLocal() ->
KtUltraLightClassForLocalDeclaration(element, support)
(element.hasModifier(KtTokens.INLINE_KEYWORD)) ->
@@ -219,5 +219,4 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
override fun analyze(element: KtElement) = element.analyze(BodyResolveMode.PARTIAL)
override fun analyzeWithContent(element: KtClassOrObject) = element.analyzeWithContent()
}
}