Revert "Use lazySync instead of lazyPub to avoid raise on creation LightClasses"

The commit causes deadlock in 183 branch in KotlinLintTestGenerated test.

This reverts commit d6c54b84
This commit is contained in:
Nikolay Krasko
2019-09-03 12:42:56 +03:00
parent d0c02a1a34
commit 63f43d9b2e
5 changed files with 15 additions and 23 deletions
@@ -56,10 +56,13 @@ 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) trackerService.modificationTracker else trackerService.outOfBlockModificationTracker if (classOrObject.isLocal()) {
KotlinModificationTrackerService.getInstance(classOrObject.project).modificationTracker
} else {
KotlinModificationTrackerService.getInstance(classOrObject.project).outOfBlockModificationTracker
}
) )
} }
@@ -19,17 +19,12 @@ 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 }
private val _getOwnFields: List<KtLightField> by lazySync { lightClassData.getOwnFields(this) } override fun getOwnFields() = lightClassData.getOwnFields(this)
override fun getOwnFields() = _getOwnFields override fun getOwnMethods() = lightClassData.getOwnMethods(this)
private val _getOwnMethods: List<KtLightMethod> by lazySync { lightClassData.getOwnMethods(this) }
override fun getOwnMethods() = _getOwnMethods
} }
@@ -97,9 +97,7 @@ 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,8 +20,6 @@ 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.")
} }
@@ -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.lazySync import org.jetbrains.kotlin.asJava.classes.lazyPub
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,11 +43,9 @@ sealed class LazyLightClassDataHolder(
cache.computeIfAbsent(lazyLightClassDataHolder, diagnostics) cache.computeIfAbsent(lazyLightClassDataHolder, diagnostics)
} }
private val _builderExactContextProvider: LightClassBuilderResult by lazySync { builder(exactContextProvider()) } private val exactResultLazyValue = lazyPub { builder(exactContextProvider()).stub }
private val exactResultLazyValue = lazySync { _builderExactContextProvider.stub } private val lazyInexactStub by lazyPub {
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 } }
} }
@@ -58,7 +56,7 @@ sealed class LazyLightClassDataHolder(
override val extraDiagnostics: Diagnostics override val extraDiagnostics: Diagnostics
get() = diagnosticsHolderProvider().getOrCompute(this) { get() = diagnosticsHolderProvider().getOrCompute(this) {
_builderExactContextProvider.diagnostics builder(exactContextProvider()).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
@@ -102,9 +100,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 lazySync { findDelegate(javaFileStub) } override val clsDelegate: PsiClass by lazyPub { findDelegate(javaFileStub) }
private val dummyDelegate: PsiClass? by lazySync { inexactStub?.let(findDelegate) } private val dummyDelegate: PsiClass? by lazyPub { 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)