From d6c54b845b48a383fd1e45968e3e9e0f6b3e1608 Mon Sep 17 00:00:00 2001 From: Vladimir Dolzhenko Date: Thu, 29 Aug 2019 17:51:09 +0200 Subject: [PATCH] Use lazySync instead of lazyPub to avoid raise on creation LightClasses --- .../asJava/builder/LightClassDataProvider.kt | 9 +++------ .../kotlin/asJava/classes/KtLazyLightClass.kt | 9 +++++++-- .../classes/KtLightClassForSourceDeclaration.kt | 4 +++- .../jetbrains/kotlin/asJava/classes/implUtils.kt | 2 ++ .../lightClasses/LazyLightClassDataHolder.kt | 14 ++++++++------ 5 files changed, 23 insertions(+), 15 deletions(-) diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/LightClassDataProvider.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/LightClassDataProvider.kt index 84acd762fa0..e11c044f12d 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/LightClassDataProvider.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/LightClassDataProvider.kt @@ -56,13 +56,10 @@ class LightClassDataProviderForClassOrObject( } override fun compute(): CachedValueProvider.Result? { + val trackerService = KotlinModificationTrackerService.getInstance(classOrObject.project) return CachedValueProvider.Result.create( - computeLightClassData(), - if (classOrObject.isLocal()) { - KotlinModificationTrackerService.getInstance(classOrObject.project).modificationTracker - } else { - KotlinModificationTrackerService.getInstance(classOrObject.project).outOfBlockModificationTracker - } + computeLightClassData(), + if (classOrObject.isLocal) trackerService.modificationTracker else trackerService.outOfBlockModificationTracker ) } diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLazyLightClass.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLazyLightClass.kt index bd3c6f974d8..ec666ed69ae 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLazyLightClass.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLazyLightClass.kt @@ -19,12 +19,17 @@ package org.jetbrains.kotlin.asJava.classes import com.intellij.psi.PsiClass import com.intellij.psi.PsiManager 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 val lightClassData: LightClassData override val clsDelegate: PsiClass by lazyPub { lightClassData.clsDelegate } - override fun getOwnFields() = lightClassData.getOwnFields(this) - override fun getOwnMethods() = lightClassData.getOwnMethods(this) + private val _getOwnFields: List by lazySync { lightClassData.getOwnFields(this) } + override fun getOwnFields() = _getOwnFields + + private val _getOwnMethods: List by lazySync { lightClassData.getOwnMethods(this) } + override fun getOwnMethods() = _getOwnMethods } \ No newline at end of file diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt index 97ae5211c52..f21d2680998 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt @@ -97,7 +97,9 @@ abstract class KtLightClassForSourceDeclaration( abstract override fun getQualifiedName(): String? override val lightClassData: LightClassData - get() = findLightClassData() + get() = _findLightClassData + + private val _findLightClassData: LightClassData by lazySync { findLightClassData() } protected open fun findLightClassData() = getLightClassDataHolder().findDataForClassOrObject(classOrObject) diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/implUtils.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/implUtils.kt index 5d2f62ad1da..8663482fdd3 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/implUtils.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/implUtils.kt @@ -20,6 +20,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe // NOTE: avoid using blocking lazy in light classes, it leads to deadlocks fun lazyPub(initializer: () -> T) = lazy(LazyThreadSafetyMode.PUBLICATION, initializer) +fun lazySync(initializer: () -> T) = lazy(LazyThreadSafetyMode.SYNCHRONIZED, initializer) + fun LightElement.cannotModify(): Nothing { throw IncorrectOperationException("Modification not implemented.") } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/LazyLightClassDataHolder.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/LazyLightClassDataHolder.kt index ca991d14fbb..a113d426c3c 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/LazyLightClassDataHolder.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/LazyLightClassDataHolder.kt @@ -14,7 +14,7 @@ import com.intellij.psi.impl.java.stubs.PsiJavaFileStub import org.jetbrains.kotlin.asJava.LightClassBuilder import org.jetbrains.kotlin.asJava.builder.* 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.KtLightFieldImpl import org.jetbrains.kotlin.asJava.elements.KtLightMethod @@ -43,9 +43,11 @@ sealed class LazyLightClassDataHolder( 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 } } } @@ -56,7 +58,7 @@ sealed class LazyLightClassDataHolder( override val extraDiagnostics: Diagnostics get() = diagnosticsHolderProvider().getOrCompute(this) { - builder(exactContextProvider()).diagnostics + _builderExactContextProvider.diagnostics // 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 .takeUnless { it.isEmpty() } ?: Diagnostics.EMPTY @@ -100,9 +102,9 @@ sealed class LazyLightClassDataHolder( private inner class LazyLightClassData( findDelegate: (PsiJavaFileStub) -> PsiClass ) : 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 { if (dummyDelegate == null) return KtLightFieldImpl.fromClsFields(clsDelegate, containingClass)