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.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.util.isOrdinaryClass
import java.util.* import java.util.*
import javax.swing.Icon import javax.swing.Icon
@@ -359,7 +358,7 @@ abstract class KtLightClassForSourceDeclaration(
classOrObject is KtObjectDeclaration && classOrObject.isObjectLiteral() -> classOrObject is KtObjectDeclaration && classOrObject.isObjectLiteral() ->
KtLightClassForAnonymousDeclaration(classOrObject) KtLightClassForAnonymousDeclaration(classOrObject)
classOrObject.isLocal -> classOrObject.safeIsLocal() ->
KtLightClassForLocalDeclaration(classOrObject) KtLightClassForLocalDeclaration(classOrObject)
else -> else ->
@@ -372,9 +371,9 @@ abstract class KtLightClassForSourceDeclaration(
return InvalidLightClassDataHolder return InvalidLightClassDataHolder
} }
val containingScript = classOrObject.containingKtFile.script val containingScript = classOrObject.containingKtFile.safeScript()
return when { return when {
!classOrObject.isLocal && containingScript != null -> !classOrObject.safeIsLocal() && containingScript != null ->
KtLightClassForScript.getLightClassCachedValue(containingScript).value KtLightClassForScript.getLightClassCachedValue(containingScript).value
else -> else ->
getLightClassCachedValue(classOrObject).value getLightClassCachedValue(classOrObject).value
@@ -546,7 +545,7 @@ fun KtClassOrObject.shouldNotBeVisibleAsLightClass(): Boolean {
return true return true
} }
if (isLocal) { if (safeIsLocal()) {
if (containingFile.virtualFile == null) return true if (containingFile.virtualFile == null) return true
if (hasParseErrorsAround(this) || PsiUtilCore.hasErrorElementChild(this)) return true if (hasParseErrorsAround(this) || PsiUtilCore.hasErrorElementChild(this)) return true
} }
@@ -52,7 +52,7 @@ fun PsiReferenceList.addSuperTypeEntry(
internal fun KtClassOrObject.getExternalDependencies(): List<ModificationTracker> { internal fun KtClassOrObject.getExternalDependencies(): List<ModificationTracker> {
return with(KotlinModificationTrackerService.getInstance(project)) { return with(KotlinModificationTrackerService.getInstance(project)) {
if (!isLocal) return listOf(outOfBlockModificationTracker) if (!safeIsLocal()) return listOf(outOfBlockModificationTracker)
else when (val file = containingFile) { else when (val file = containingFile) {
is KtFile -> listOf(outOfBlockModificationTracker, fileModificationTracker(file)) is KtFile -> listOf(outOfBlockModificationTracker, fileModificationTracker(file))
else -> listOf(outOfBlockModificationTracker) else -> listOf(outOfBlockModificationTracker)
@@ -6,7 +6,9 @@
package org.jetbrains.kotlin.asJava.classes package org.jetbrains.kotlin.asJava.classes
import com.google.common.collect.Lists import com.google.common.collect.Lists
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Computable
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.impl.cache.ModifierFlags import com.intellij.psi.impl.cache.ModifierFlags
import com.intellij.psi.impl.cache.TypeInfo import com.intellij.psi.impl.cache.TypeInfo
@@ -184,10 +186,9 @@ fun createTypeFromCanonicalText(
} }
fun tryGetPredefinedName(klass: ClassDescriptor): String? { fun tryGetPredefinedName(klass: ClassDescriptor): String? {
val sourceClass = (klass.source as? KotlinSourceElement)?.psi as? KtClassOrObject 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() (sourceClass.nameAsName ?: SpecialNames.NO_NAME_PROVIDED).asString()
else null else null
} }
@@ -380,3 +381,14 @@ internal inline fun Project.applyCompilerPlugins(body: (UltraLightClassModifierE
internal fun <L : Any> L.invalidAccess(): Nothing = 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}") 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.builder.LightClassDataProviderForFileFacade
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject 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.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory.cast import org.jetbrains.kotlin.diagnostics.DiagnosticFactory.cast
import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.diagnostics.Errors.*
@@ -57,7 +58,7 @@ fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Diagnostic
fun doGetDiagnostics(): Diagnostics? { fun doGetDiagnostics(): Diagnostics? {
//TODO: enable this diagnostic when light classes for scripts are ready //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 var parent = element.parent
if (element is KtPropertyAccessor) { if (element is KtPropertyAccessor) {
@@ -129,7 +129,7 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
override fun createUltraLightClass(element: KtClassOrObject): KtUltraLightClass? { override fun createUltraLightClass(element: KtClassOrObject): KtUltraLightClass? {
if (element.shouldNotBeVisibleAsLightClass() || if (element.shouldNotBeVisibleAsLightClass() ||
element is KtEnumEntry || element is KtEnumEntry ||
element.containingKtFile.isScript() element.containingKtFile.safeIsScript()
) { ) {
return null return null
} }
@@ -139,7 +139,7 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
element is KtObjectDeclaration && element.isObjectLiteral() -> element is KtObjectDeclaration && element.isObjectLiteral() ->
KtUltraLightClassForAnonymousDeclaration(element, support) KtUltraLightClassForAnonymousDeclaration(element, support)
element.isLocal -> element.safeIsLocal() ->
KtUltraLightClassForLocalDeclaration(element, support) KtUltraLightClassForLocalDeclaration(element, support)
(element.hasModifier(KtTokens.INLINE_KEYWORD)) -> (element.hasModifier(KtTokens.INLINE_KEYWORD)) ->
@@ -220,4 +220,3 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
override fun analyzeWithContent(element: KtClassOrObject) = element.analyzeWithContent() override fun analyzeWithContent(element: KtClassOrObject) = element.analyzeWithContent()
} }