From ad4f6b25cadfbb7b245e4f98193563cab07fdae3 Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Wed, 25 Jan 2023 11:56:52 +0100 Subject: [PATCH] [SLC] AnnotationsBox: add an owner to signatures we shouldn't require the owner on initialization phase ^KT-56046 --- .../symbol/annotations/AnnotationsBox.kt | 9 +++--- .../annotations/DefaultAnnotationsProvider.kt | 3 +- .../symbol/annotations/LazyAnnotationsBox.kt | 16 ++++++----- .../annotations/SimpleAnnotationsBox.kt | 28 ++++++++++++++----- 4 files changed, 37 insertions(+), 19 deletions(-) diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/AnnotationsBox.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/AnnotationsBox.kt index f51cb1583a0..c9a4f1a5411 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/AnnotationsBox.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/AnnotationsBox.kt @@ -6,9 +6,10 @@ package org.jetbrains.kotlin.light.classes.symbol.annotations import com.intellij.psi.PsiAnnotation -import com.intellij.psi.PsiAnnotationOwner +import com.intellij.psi.PsiModifierList -internal sealed interface AnnotationsBox : PsiAnnotationOwner { - override fun getApplicableAnnotations(): Array = annotations - override fun addAnnotation(qualifiedName: String): PsiAnnotation = throw UnsupportedOperationException() +internal sealed interface AnnotationsBox { + fun annotations(owner: PsiModifierList): Array + fun findAnnotation(owner: PsiModifierList, qualifiedName: String): PsiAnnotation? + fun hasAnnotation(owner: PsiModifierList, qualifiedName: String): Boolean = findAnnotation(owner, qualifiedName) != null } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/DefaultAnnotationsProvider.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/DefaultAnnotationsProvider.kt index 7cc4793ab75..8be614e8140 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/DefaultAnnotationsProvider.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/DefaultAnnotationsProvider.kt @@ -268,9 +268,10 @@ private fun LazyAnnotationsBox.tryConvertToJavaAnnotation( argumentsComputer: SymbolLightJavaAnnotation.() -> List = { emptyList() }, ): PsiAnnotation? { if (qualifiedName != javaQualifier) return null - if (hasAnnotation(javaQualifier)) return null + if (hasAnnotation(owner, javaQualifier)) return null val originalLightAnnotation = findAnnotation( + owner, kotlinQualifier, withAdditionalAnnotations = false, ) as? SymbolLightLazyAnnotation ?: return null diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/LazyAnnotationsBox.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/LazyAnnotationsBox.kt index ec5d8b4e038..5041f5120df 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/LazyAnnotationsBox.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/LazyAnnotationsBox.kt @@ -13,7 +13,6 @@ import org.jetbrains.kotlin.utils.SmartList import java.util.concurrent.atomic.AtomicReference internal class LazyAnnotationsBox( - private val owner: PsiModifierList, private val annotationsProvider: AnnotationsProvider, private val additionalAnnotationsProvider: AdditionalAnnotationsProvider = DefaultAnnotationsProvider, ) : AnnotationsBox { @@ -21,7 +20,7 @@ internal class LazyAnnotationsBox( private var specialAnnotations: SmartList? = null private val monitor = Any() - override fun getAnnotations(): Array { + override fun annotations(owner: PsiModifierList): Array { annotationsArray.get()?.let { return it } val classIds = annotationsProvider.classIds() @@ -60,9 +59,12 @@ internal class LazyAnnotationsBox( annotationsArray.get() ?: error("Unexpected state") } - override fun findAnnotation(qualifiedName: String): PsiAnnotation? = findAnnotation(qualifiedName, withAdditionalAnnotations = true) + override fun findAnnotation( + owner: PsiModifierList, + qualifiedName: String, + ): PsiAnnotation? = findAnnotation(owner, qualifiedName, withAdditionalAnnotations = true) - fun findAnnotation(qualifiedName: String, withAdditionalAnnotations: Boolean): PsiAnnotation? { + fun findAnnotation(owner: PsiModifierList, qualifiedName: String, withAdditionalAnnotations: Boolean): PsiAnnotation? { annotationsArray.get()?.let { array -> return array.find { it.qualifiedName == qualifiedName } } @@ -84,7 +86,7 @@ internal class LazyAnnotationsBox( } if (specialAnnotation == null) { - return annotations.find { it.qualifiedName == qualifiedName } + return annotations(owner).find { it.qualifiedName == qualifiedName } } return synchronized(monitor) { @@ -108,7 +110,7 @@ internal class LazyAnnotationsBox( } } - override fun hasAnnotation(qualifiedName: String): Boolean { + override fun hasAnnotation(owner: PsiModifierList, qualifiedName: String): Boolean { annotationsArray.get()?.let { array -> return array.any { it.qualifiedName == qualifiedName } } @@ -117,7 +119,7 @@ internal class LazyAnnotationsBox( return if (specialAnnotationClassId != null) { specialAnnotationClassId in annotationsProvider } else { - annotations.any { it.qualifiedName == qualifiedName } + annotations(owner).any { it.qualifiedName == qualifiedName } } } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/SimpleAnnotationsBox.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/SimpleAnnotationsBox.kt index 4a94c9a84a0..300e95da8b4 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/SimpleAnnotationsBox.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/SimpleAnnotationsBox.kt @@ -6,14 +6,28 @@ package org.jetbrains.kotlin.light.classes.symbol.annotations import com.intellij.psi.PsiAnnotation -import org.jetbrains.kotlin.asJava.classes.lazyPub +import com.intellij.psi.PsiModifierList +import java.util.concurrent.atomic.AtomicReference -internal class SimpleAnnotationsBox(annotationsComputer: () -> Collection) : AnnotationsBox { - private val lazyAnnotation: Array by lazyPub { - val annotations = annotationsComputer() - if (annotations.isEmpty()) PsiAnnotation.EMPTY_ARRAY else annotations.toTypedArray() +internal class SimpleAnnotationsBox(private val annotationsComputer: (PsiModifierList) -> Collection) : AnnotationsBox { + private val annotations: AtomicReference?> = AtomicReference() + + private fun getOrComputeAnnotations(owner: PsiModifierList): Array { + annotations.get()?.let { return it } + + val nonCachedAnnotations = annotationsComputer(owner) + val resultArray = if (nonCachedAnnotations.isEmpty()) PsiAnnotation.EMPTY_ARRAY else nonCachedAnnotations.toTypedArray() + return if (annotations.compareAndSet(null, resultArray)) { + resultArray + } else { + getOrComputeAnnotations(owner) + } } - override fun getAnnotations(): Array = lazyAnnotation - override fun findAnnotation(qualifiedName: String): PsiAnnotation? = lazyAnnotation.find { it.qualifiedName == qualifiedName } + override fun annotations(owner: PsiModifierList): Array = getOrComputeAnnotations(owner) + + override fun findAnnotation( + owner: PsiModifierList, + qualifiedName: String, + ): PsiAnnotation? = getOrComputeAnnotations(owner).find { it.qualifiedName == qualifiedName } }