From d76e902b213ab68fcf9841cc8b2fa26b7461d97d Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Tue, 24 Jan 2023 15:07:32 +0100 Subject: [PATCH] [SLC] extract AnnotationsProvider ^KT-56046 --- .../symbol/annotations/AnnotationsProvider.kt | 17 +++++++ .../annotations/DefaultAnnotationsProvider.kt | 5 +- .../symbol/annotations/LazyAnnotationsBox.kt | 30 +++--------- .../annotations/SymbolAnnotationsProvider.kt | 47 +++++++++++++++++++ .../annotations/SymbolLightLazyAnnotation.kt | 33 ++++--------- 5 files changed, 79 insertions(+), 53 deletions(-) create mode 100644 analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/AnnotationsProvider.kt create mode 100644 analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/SymbolAnnotationsProvider.kt diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/AnnotationsProvider.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/AnnotationsProvider.kt new file mode 100644 index 00000000000..b6ff102d3d4 --- /dev/null +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/AnnotationsProvider.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.light.classes.symbol.annotations + +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication +import org.jetbrains.kotlin.name.ClassId + +interface AnnotationsProvider { + fun classIds(): Collection + operator fun get(classId: ClassId): Collection + operator fun contains(classId: ClassId): Boolean + fun isTheSameAs(other: Any?): Boolean + fun ownerClassId(): ClassId? +} 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 d7cf7406411..a588961018f 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 @@ -10,7 +10,6 @@ import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import com.intellij.psi.PsiModifierList import org.jetbrains.kotlin.analysis.api.annotations.* -import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightMethod import org.jetbrains.kotlin.load.java.JvmAbi @@ -189,9 +188,7 @@ private fun SymbolLightLazyAnnotation.tryConvertToRepeatableJavaAnnotation( ) private fun SymbolLightJavaAnnotation.computeRepeatableJavaAnnotationArguments(): List { - val annotationClassId = originalLightAnnotation.withAnnotatedSymbol { ktAnnotatedSymbol -> - (ktAnnotatedSymbol as? KtClassLikeSymbol)?.classIdIfNonLocal - } ?: return emptyList() + val annotationClassId = originalLightAnnotation.annotationsProvider.ownerClassId() ?: return emptyList() return listOf( KtNamedAnnotationValue( 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 c60e8a3a078..ea84597edf7 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 @@ -8,28 +8,16 @@ package org.jetbrains.kotlin.light.classes.symbol.annotations import com.intellij.psi.PsiAnnotation import com.intellij.psi.PsiAnnotationOwner import com.intellij.psi.PsiModifierList -import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.annotations.annotationClassIds -import org.jetbrains.kotlin.analysis.api.annotations.annotationsByClassId -import org.jetbrains.kotlin.analysis.api.annotations.hasAnnotation -import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol -import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer -import org.jetbrains.kotlin.analysis.project.structure.KtModule -import org.jetbrains.kotlin.light.classes.symbol.withSymbol import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.utils.SmartList import java.util.concurrent.atomic.AtomicReference internal class LazyAnnotationsBox( - private val annotatedSymbolPointer: KtSymbolPointer, - private val ktModule: KtModule, private val owner: PsiModifierList, + private val annotationsProvider: AnnotationsProvider, private val additionalAnnotationsProvider: AdditionalAnnotationsProvider = DefaultAnnotationsProvider, ) : PsiAnnotationOwner { - private inline fun withAnnotatedSymbol(crossinline action: context(KtAnalysisSession) (KtAnnotatedSymbol) -> T): T = - annotatedSymbolPointer.withSymbol(ktModule, action) - private val annotationsArray: AtomicReference?> = AtomicReference() private var specialAnnotations: SmartList? = null private val monitor = Any() @@ -37,12 +25,9 @@ internal class LazyAnnotationsBox( override fun getAnnotations(): Array { annotationsArray.get()?.let { return it } - val classIds = withAnnotatedSymbol { ktAnnotatedSymbol -> - ktAnnotatedSymbol.annotationClassIds - } - + val classIds = annotationsProvider.classIds() val annotations = classIds.withIndex().mapTo(SmartList()) { (index, classId) -> - SymbolLightLazyAnnotation(classId, annotatedSymbolPointer, ktModule, index, owner) + SymbolLightLazyAnnotation(classId, annotationsProvider, index, owner) } val valueToReturn = if (annotations.isEmpty()) { @@ -87,14 +72,11 @@ internal class LazyAnnotationsBox( val specialAnnotationClassId = specialAnnotationsList[qualifiedName] val specialAnnotation = if (specialAnnotationClassId != null) { - val annotationApplication = withAnnotatedSymbol { ktAnnotatedSymbol -> - ktAnnotatedSymbol.annotationsByClassId(specialAnnotationClassId).firstOrNull() - } ?: return null + val annotationApplication = annotationsProvider[specialAnnotationClassId].firstOrNull() ?: return null SymbolLightLazyAnnotation( specialAnnotationClassId, - annotatedSymbolPointer, - ktModule, + annotationsProvider, annotationApplication, owner, ) @@ -136,7 +118,7 @@ internal class LazyAnnotationsBox( val specialAnnotationClassId = specialAnnotationsList[qualifiedName] return if (specialAnnotationClassId != null) { - withAnnotatedSymbol { ktAnnotatedSymbol -> ktAnnotatedSymbol.hasAnnotation(specialAnnotationClassId) } + specialAnnotationClassId in annotationsProvider } else { annotations.any { it.qualifiedName == qualifiedName } } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/SymbolAnnotationsProvider.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/SymbolAnnotationsProvider.kt new file mode 100644 index 00000000000..cbfc64cdd58 --- /dev/null +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/SymbolAnnotationsProvider.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.light.classes.symbol.annotations + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication +import org.jetbrains.kotlin.analysis.api.annotations.annotationClassIds +import org.jetbrains.kotlin.analysis.api.annotations.annotationsByClassId +import org.jetbrains.kotlin.analysis.api.annotations.hasAnnotation +import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol +import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer +import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.light.classes.symbol.withSymbol +import org.jetbrains.kotlin.name.ClassId + +internal class SymbolAnnotationsProvider( + private val ktModule: KtModule, + private val annotatedSymbolPointer: KtSymbolPointer +) : AnnotationsProvider { + private inline fun withAnnotatedSymbol(crossinline action: context(KtAnalysisSession) (KtAnnotatedSymbol) -> T): T = + annotatedSymbolPointer.withSymbol(ktModule, action) + + override fun classIds(): Collection = withAnnotatedSymbol { annotatedSymbol -> + annotatedSymbol.annotationClassIds + } + + override fun get(classId: ClassId): Collection = withAnnotatedSymbol { annotatedSymbol -> + annotatedSymbol.annotationsByClassId(classId) + } + + override fun contains(classId: ClassId): Boolean = withAnnotatedSymbol { annotatedSymbol -> + annotatedSymbol.hasAnnotation(classId) + } + + override fun isTheSameAs(other: Any?): Boolean = other === this || + other is SymbolAnnotationsProvider<*> && + other.ktModule == ktModule && + annotatedSymbolPointer.pointsToTheSameSymbolAs(other.annotatedSymbolPointer) + + override fun ownerClassId(): ClassId? = withAnnotatedSymbol { annotatedSymbol -> + (annotatedSymbol as? KtClassLikeSymbol)?.classIdIfNonLocal + } +} diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/SymbolLightLazyAnnotation.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/SymbolLightLazyAnnotation.kt index 84457ae4cc9..fd8ea414c90 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/SymbolLightLazyAnnotation.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/SymbolLightLazyAnnotation.kt @@ -7,22 +7,15 @@ package org.jetbrains.kotlin.light.classes.symbol.annotations import com.intellij.psi.PsiAnnotationParameterList import com.intellij.psi.PsiModifierList -import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication -import org.jetbrains.kotlin.analysis.api.annotations.annotationsByClassId -import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol -import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer -import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.asJava.classes.lazyPub -import org.jetbrains.kotlin.light.classes.symbol.withSymbol import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtCallElement internal class SymbolLightLazyAnnotation private constructor( private val classId: ClassId, - private val annotatedSymbolPointer: KtSymbolPointer, - private val ktModule: KtModule, + val annotationsProvider: AnnotationsProvider, private val index: Int?, specialAnnotationApplication: KtAnnotationApplication?, owner: PsiModifierList, @@ -34,23 +27,18 @@ internal class SymbolLightLazyAnnotation private constructor( private val fqName: FqName = classId.asSingleFqName() val annotationApplication: Lazy = specialAnnotationApplication?.let(::lazyOf) ?: lazyPub { - withAnnotatedSymbol { ktAnnotatedSymbol -> - val applications = ktAnnotatedSymbol.annotationsByClassId(classId) - applications.find { it.index == index } - ?: error("expected index: $index, actual indices: ${applications.map { it.index }}") - } + val applications = annotationsProvider[classId] + applications.find { it.index == index } ?: error("expected index: $index, actual indices: ${applications.map { it.index }}") } constructor( classId: ClassId, - annotatedSymbolPointer: KtSymbolPointer, - ktModule: KtModule, + annotationsProvider: AnnotationsProvider, index: Int, owner: PsiModifierList, ) : this( classId = classId, - annotatedSymbolPointer = annotatedSymbolPointer, - ktModule = ktModule, + annotationsProvider = annotationsProvider, index = index, specialAnnotationApplication = null, owner = owner, @@ -58,22 +46,17 @@ internal class SymbolLightLazyAnnotation private constructor( constructor( classId: ClassId, - annotatedSymbolPointer: KtSymbolPointer, - ktModule: KtModule, + annotationsProvider: AnnotationsProvider, annotationApplication: KtAnnotationApplication, owner: PsiModifierList, ) : this( classId = classId, - annotatedSymbolPointer = annotatedSymbolPointer, - ktModule = ktModule, + annotationsProvider = annotationsProvider, index = null, specialAnnotationApplication = annotationApplication, owner = owner, ) - inline fun withAnnotatedSymbol(crossinline action: context(KtAnalysisSession) (KtAnnotatedSymbol) -> T): T = - annotatedSymbolPointer.withSymbol(ktModule, action) - override val kotlinOrigin: KtCallElement? get() = annotationApplication.value.psi override fun getQualifiedName(): String = fqName.asString() @@ -88,7 +71,7 @@ internal class SymbolLightLazyAnnotation private constructor( other is SymbolLightLazyAnnotation && other.fqName == fqName && other.index == index && - other.ktModule == ktModule && + annotationsProvider.isTheSameAs(other.annotationsProvider) && other.parent == parent override fun hashCode(): Int = fqName.hashCode()