Use lazySync instead of lazyPub to avoid raise on creation LightClasses
This commit is contained in:
+3
-6
@@ -56,13 +56,10 @@ class LightClassDataProviderForClassOrObject(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun compute(): CachedValueProvider.Result<LightClassDataHolder.ForClass>? {
|
override fun compute(): CachedValueProvider.Result<LightClassDataHolder.ForClass>? {
|
||||||
|
val trackerService = KotlinModificationTrackerService.getInstance(classOrObject.project)
|
||||||
return CachedValueProvider.Result.create(
|
return CachedValueProvider.Result.create(
|
||||||
computeLightClassData(),
|
computeLightClassData(),
|
||||||
if (classOrObject.isLocal()) {
|
if (classOrObject.isLocal) trackerService.modificationTracker else trackerService.outOfBlockModificationTracker
|
||||||
KotlinModificationTrackerService.getInstance(classOrObject.project).modificationTracker
|
|
||||||
} else {
|
|
||||||
KotlinModificationTrackerService.getInstance(classOrObject.project).outOfBlockModificationTracker
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,12 +19,17 @@ package org.jetbrains.kotlin.asJava.classes
|
|||||||
import com.intellij.psi.PsiClass
|
import com.intellij.psi.PsiClass
|
||||||
import com.intellij.psi.PsiManager
|
import com.intellij.psi.PsiManager
|
||||||
import org.jetbrains.kotlin.asJava.builder.LightClassData
|
import org.jetbrains.kotlin.asJava.builder.LightClassData
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
|
|
||||||
abstract class KtLazyLightClass(manager: PsiManager) : KtLightClassBase(manager) {
|
abstract class KtLazyLightClass(manager: PsiManager) : KtLightClassBase(manager) {
|
||||||
abstract val lightClassData: LightClassData
|
abstract val lightClassData: LightClassData
|
||||||
|
|
||||||
override val clsDelegate: PsiClass by lazyPub { lightClassData.clsDelegate }
|
override val clsDelegate: PsiClass by lazyPub { lightClassData.clsDelegate }
|
||||||
|
|
||||||
override fun getOwnFields() = lightClassData.getOwnFields(this)
|
private val _getOwnFields: List<KtLightField> by lazySync { lightClassData.getOwnFields(this) }
|
||||||
override fun getOwnMethods() = lightClassData.getOwnMethods(this)
|
override fun getOwnFields() = _getOwnFields
|
||||||
|
|
||||||
|
private val _getOwnMethods: List<KtLightMethod> by lazySync { lightClassData.getOwnMethods(this) }
|
||||||
|
override fun getOwnMethods() = _getOwnMethods
|
||||||
}
|
}
|
||||||
+3
-1
@@ -97,7 +97,9 @@ abstract class KtLightClassForSourceDeclaration(
|
|||||||
abstract override fun getQualifiedName(): String?
|
abstract override fun getQualifiedName(): String?
|
||||||
|
|
||||||
override val lightClassData: LightClassData
|
override val lightClassData: LightClassData
|
||||||
get() = findLightClassData()
|
get() = _findLightClassData
|
||||||
|
|
||||||
|
private val _findLightClassData: LightClassData by lazySync { findLightClassData() }
|
||||||
|
|
||||||
protected open fun findLightClassData() = getLightClassDataHolder().findDataForClassOrObject(classOrObject)
|
protected open fun findLightClassData() = getLightClassDataHolder().findDataForClassOrObject(classOrObject)
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
|||||||
// NOTE: avoid using blocking lazy in light classes, it leads to deadlocks
|
// NOTE: avoid using blocking lazy in light classes, it leads to deadlocks
|
||||||
fun <T> lazyPub(initializer: () -> T) = lazy(LazyThreadSafetyMode.PUBLICATION, initializer)
|
fun <T> lazyPub(initializer: () -> T) = lazy(LazyThreadSafetyMode.PUBLICATION, initializer)
|
||||||
|
|
||||||
|
fun <T> lazySync(initializer: () -> T) = lazy(LazyThreadSafetyMode.SYNCHRONIZED, initializer)
|
||||||
|
|
||||||
fun LightElement.cannotModify(): Nothing {
|
fun LightElement.cannotModify(): Nothing {
|
||||||
throw IncorrectOperationException("Modification not implemented.")
|
throw IncorrectOperationException("Modification not implemented.")
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-6
@@ -14,7 +14,7 @@ import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
|
|||||||
import org.jetbrains.kotlin.asJava.LightClassBuilder
|
import org.jetbrains.kotlin.asJava.LightClassBuilder
|
||||||
import org.jetbrains.kotlin.asJava.builder.*
|
import org.jetbrains.kotlin.asJava.builder.*
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
import org.jetbrains.kotlin.asJava.classes.lazySync
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightFieldImpl
|
import org.jetbrains.kotlin.asJava.elements.KtLightFieldImpl
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
@@ -43,9 +43,11 @@ sealed class LazyLightClassDataHolder(
|
|||||||
cache.computeIfAbsent(lazyLightClassDataHolder, diagnostics)
|
cache.computeIfAbsent(lazyLightClassDataHolder, diagnostics)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val exactResultLazyValue = lazyPub { builder(exactContextProvider()).stub }
|
private val _builderExactContextProvider: LightClassBuilderResult by lazySync { builder(exactContextProvider()) }
|
||||||
|
|
||||||
private val lazyInexactStub by lazyPub {
|
private val exactResultLazyValue = lazySync { _builderExactContextProvider.stub }
|
||||||
|
|
||||||
|
private val lazyInexactStub by lazySync {
|
||||||
dummyContextProvider?.let { provider -> provider()?.let { context -> builder.invoke(context).stub } }
|
dummyContextProvider?.let { provider -> provider()?.let { context -> builder.invoke(context).stub } }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +58,7 @@ sealed class LazyLightClassDataHolder(
|
|||||||
|
|
||||||
override val extraDiagnostics: Diagnostics
|
override val extraDiagnostics: Diagnostics
|
||||||
get() = diagnosticsHolderProvider().getOrCompute(this) {
|
get() = diagnosticsHolderProvider().getOrCompute(this) {
|
||||||
builder(exactContextProvider()).diagnostics
|
_builderExactContextProvider.diagnostics
|
||||||
// Force lazy diagnostics computation because otherwise a lot of memory is retained by computation.
|
// Force lazy diagnostics computation because otherwise a lot of memory is retained by computation.
|
||||||
// NB: Laziness here is not crucial anyway since somebody already has requested diagnostics and we hope one will use them
|
// NB: Laziness here is not crucial anyway since somebody already has requested diagnostics and we hope one will use them
|
||||||
.takeUnless { it.isEmpty() } ?: Diagnostics.EMPTY
|
.takeUnless { it.isEmpty() } ?: Diagnostics.EMPTY
|
||||||
@@ -100,9 +102,9 @@ sealed class LazyLightClassDataHolder(
|
|||||||
private inner class LazyLightClassData(
|
private inner class LazyLightClassData(
|
||||||
findDelegate: (PsiJavaFileStub) -> PsiClass
|
findDelegate: (PsiJavaFileStub) -> PsiClass
|
||||||
) : LightClassData {
|
) : LightClassData {
|
||||||
override val clsDelegate: PsiClass by lazyPub { findDelegate(javaFileStub) }
|
override val clsDelegate: PsiClass by lazySync { findDelegate(javaFileStub) }
|
||||||
|
|
||||||
private val dummyDelegate: PsiClass? by lazyPub { inexactStub?.let(findDelegate) }
|
private val dummyDelegate: PsiClass? by lazySync { inexactStub?.let(findDelegate) }
|
||||||
|
|
||||||
override fun getOwnFields(containingClass: KtLightClass): List<KtLightField> {
|
override fun getOwnFields(containingClass: KtLightClass): List<KtLightField> {
|
||||||
if (dummyDelegate == null) return KtLightFieldImpl.fromClsFields(clsDelegate, containingClass)
|
if (dummyDelegate == null) return KtLightFieldImpl.fromClsFields(clsDelegate, containingClass)
|
||||||
|
|||||||
Reference in New Issue
Block a user