[SLC] extract AnnotationsProvider
^KT-56046
This commit is contained in:
committed by
Space Team
parent
4dbce37c0f
commit
d76e902b21
+17
@@ -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<ClassId>
|
||||||
|
operator fun get(classId: ClassId): Collection<KtAnnotationApplication>
|
||||||
|
operator fun contains(classId: ClassId): Boolean
|
||||||
|
fun isTheSameAs(other: Any?): Boolean
|
||||||
|
fun ownerClassId(): ClassId?
|
||||||
|
}
|
||||||
+1
-4
@@ -10,7 +10,6 @@ import com.intellij.psi.PsiClass
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiModifierList
|
import com.intellij.psi.PsiModifierList
|
||||||
import org.jetbrains.kotlin.analysis.api.annotations.*
|
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.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightMethod
|
import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightMethod
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
@@ -189,9 +188,7 @@ private fun SymbolLightLazyAnnotation.tryConvertToRepeatableJavaAnnotation(
|
|||||||
)
|
)
|
||||||
|
|
||||||
private fun SymbolLightJavaAnnotation.computeRepeatableJavaAnnotationArguments(): List<KtNamedAnnotationValue> {
|
private fun SymbolLightJavaAnnotation.computeRepeatableJavaAnnotationArguments(): List<KtNamedAnnotationValue> {
|
||||||
val annotationClassId = originalLightAnnotation.withAnnotatedSymbol { ktAnnotatedSymbol ->
|
val annotationClassId = originalLightAnnotation.annotationsProvider.ownerClassId() ?: return emptyList()
|
||||||
(ktAnnotatedSymbol as? KtClassLikeSymbol)?.classIdIfNonLocal
|
|
||||||
} ?: return emptyList()
|
|
||||||
|
|
||||||
return listOf(
|
return listOf(
|
||||||
KtNamedAnnotationValue(
|
KtNamedAnnotationValue(
|
||||||
|
|||||||
+6
-24
@@ -8,28 +8,16 @@ package org.jetbrains.kotlin.light.classes.symbol.annotations
|
|||||||
import com.intellij.psi.PsiAnnotation
|
import com.intellij.psi.PsiAnnotation
|
||||||
import com.intellij.psi.PsiAnnotationOwner
|
import com.intellij.psi.PsiAnnotationOwner
|
||||||
import com.intellij.psi.PsiModifierList
|
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.ClassId
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
import java.util.concurrent.atomic.AtomicReference
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
|
|
||||||
internal class LazyAnnotationsBox(
|
internal class LazyAnnotationsBox(
|
||||||
private val annotatedSymbolPointer: KtSymbolPointer<KtAnnotatedSymbol>,
|
|
||||||
private val ktModule: KtModule,
|
|
||||||
private val owner: PsiModifierList,
|
private val owner: PsiModifierList,
|
||||||
|
private val annotationsProvider: AnnotationsProvider,
|
||||||
private val additionalAnnotationsProvider: AdditionalAnnotationsProvider = DefaultAnnotationsProvider,
|
private val additionalAnnotationsProvider: AdditionalAnnotationsProvider = DefaultAnnotationsProvider,
|
||||||
) : PsiAnnotationOwner {
|
) : PsiAnnotationOwner {
|
||||||
private inline fun <T> withAnnotatedSymbol(crossinline action: context(KtAnalysisSession) (KtAnnotatedSymbol) -> T): T =
|
|
||||||
annotatedSymbolPointer.withSymbol(ktModule, action)
|
|
||||||
|
|
||||||
private val annotationsArray: AtomicReference<Array<PsiAnnotation>?> = AtomicReference()
|
private val annotationsArray: AtomicReference<Array<PsiAnnotation>?> = AtomicReference()
|
||||||
private var specialAnnotations: SmartList<PsiAnnotation>? = null
|
private var specialAnnotations: SmartList<PsiAnnotation>? = null
|
||||||
private val monitor = Any()
|
private val monitor = Any()
|
||||||
@@ -37,12 +25,9 @@ internal class LazyAnnotationsBox(
|
|||||||
override fun getAnnotations(): Array<PsiAnnotation> {
|
override fun getAnnotations(): Array<PsiAnnotation> {
|
||||||
annotationsArray.get()?.let { return it }
|
annotationsArray.get()?.let { return it }
|
||||||
|
|
||||||
val classIds = withAnnotatedSymbol { ktAnnotatedSymbol ->
|
val classIds = annotationsProvider.classIds()
|
||||||
ktAnnotatedSymbol.annotationClassIds
|
|
||||||
}
|
|
||||||
|
|
||||||
val annotations = classIds.withIndex().mapTo(SmartList<PsiAnnotation>()) { (index, classId) ->
|
val annotations = classIds.withIndex().mapTo(SmartList<PsiAnnotation>()) { (index, classId) ->
|
||||||
SymbolLightLazyAnnotation(classId, annotatedSymbolPointer, ktModule, index, owner)
|
SymbolLightLazyAnnotation(classId, annotationsProvider, index, owner)
|
||||||
}
|
}
|
||||||
|
|
||||||
val valueToReturn = if (annotations.isEmpty()) {
|
val valueToReturn = if (annotations.isEmpty()) {
|
||||||
@@ -87,14 +72,11 @@ internal class LazyAnnotationsBox(
|
|||||||
|
|
||||||
val specialAnnotationClassId = specialAnnotationsList[qualifiedName]
|
val specialAnnotationClassId = specialAnnotationsList[qualifiedName]
|
||||||
val specialAnnotation = if (specialAnnotationClassId != null) {
|
val specialAnnotation = if (specialAnnotationClassId != null) {
|
||||||
val annotationApplication = withAnnotatedSymbol { ktAnnotatedSymbol ->
|
val annotationApplication = annotationsProvider[specialAnnotationClassId].firstOrNull() ?: return null
|
||||||
ktAnnotatedSymbol.annotationsByClassId(specialAnnotationClassId).firstOrNull()
|
|
||||||
} ?: return null
|
|
||||||
|
|
||||||
SymbolLightLazyAnnotation(
|
SymbolLightLazyAnnotation(
|
||||||
specialAnnotationClassId,
|
specialAnnotationClassId,
|
||||||
annotatedSymbolPointer,
|
annotationsProvider,
|
||||||
ktModule,
|
|
||||||
annotationApplication,
|
annotationApplication,
|
||||||
owner,
|
owner,
|
||||||
)
|
)
|
||||||
@@ -136,7 +118,7 @@ internal class LazyAnnotationsBox(
|
|||||||
|
|
||||||
val specialAnnotationClassId = specialAnnotationsList[qualifiedName]
|
val specialAnnotationClassId = specialAnnotationsList[qualifiedName]
|
||||||
return if (specialAnnotationClassId != null) {
|
return if (specialAnnotationClassId != null) {
|
||||||
withAnnotatedSymbol { ktAnnotatedSymbol -> ktAnnotatedSymbol.hasAnnotation(specialAnnotationClassId) }
|
specialAnnotationClassId in annotationsProvider
|
||||||
} else {
|
} else {
|
||||||
annotations.any { it.qualifiedName == qualifiedName }
|
annotations.any { it.qualifiedName == qualifiedName }
|
||||||
}
|
}
|
||||||
|
|||||||
+47
@@ -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<T : KtAnnotatedSymbol>(
|
||||||
|
private val ktModule: KtModule,
|
||||||
|
private val annotatedSymbolPointer: KtSymbolPointer<T>
|
||||||
|
) : AnnotationsProvider {
|
||||||
|
private inline fun <T> withAnnotatedSymbol(crossinline action: context(KtAnalysisSession) (KtAnnotatedSymbol) -> T): T =
|
||||||
|
annotatedSymbolPointer.withSymbol(ktModule, action)
|
||||||
|
|
||||||
|
override fun classIds(): Collection<ClassId> = withAnnotatedSymbol { annotatedSymbol ->
|
||||||
|
annotatedSymbol.annotationClassIds
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun get(classId: ClassId): Collection<KtAnnotationApplication> = 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
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-25
@@ -7,22 +7,15 @@ package org.jetbrains.kotlin.light.classes.symbol.annotations
|
|||||||
|
|
||||||
import com.intellij.psi.PsiAnnotationParameterList
|
import com.intellij.psi.PsiAnnotationParameterList
|
||||||
import com.intellij.psi.PsiModifierList
|
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.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.asJava.classes.lazyPub
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.withSymbol
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.KtCallElement
|
import org.jetbrains.kotlin.psi.KtCallElement
|
||||||
|
|
||||||
internal class SymbolLightLazyAnnotation private constructor(
|
internal class SymbolLightLazyAnnotation private constructor(
|
||||||
private val classId: ClassId,
|
private val classId: ClassId,
|
||||||
private val annotatedSymbolPointer: KtSymbolPointer<KtAnnotatedSymbol>,
|
val annotationsProvider: AnnotationsProvider,
|
||||||
private val ktModule: KtModule,
|
|
||||||
private val index: Int?,
|
private val index: Int?,
|
||||||
specialAnnotationApplication: KtAnnotationApplication?,
|
specialAnnotationApplication: KtAnnotationApplication?,
|
||||||
owner: PsiModifierList,
|
owner: PsiModifierList,
|
||||||
@@ -34,23 +27,18 @@ internal class SymbolLightLazyAnnotation private constructor(
|
|||||||
private val fqName: FqName = classId.asSingleFqName()
|
private val fqName: FqName = classId.asSingleFqName()
|
||||||
|
|
||||||
val annotationApplication: Lazy<KtAnnotationApplication> = specialAnnotationApplication?.let(::lazyOf) ?: lazyPub {
|
val annotationApplication: Lazy<KtAnnotationApplication> = specialAnnotationApplication?.let(::lazyOf) ?: lazyPub {
|
||||||
withAnnotatedSymbol { ktAnnotatedSymbol ->
|
val applications = annotationsProvider[classId]
|
||||||
val applications = ktAnnotatedSymbol.annotationsByClassId(classId)
|
applications.find { it.index == index } ?: error("expected index: $index, actual indices: ${applications.map { it.index }}")
|
||||||
applications.find { it.index == index }
|
|
||||||
?: error("expected index: $index, actual indices: ${applications.map { it.index }}")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
classId: ClassId,
|
classId: ClassId,
|
||||||
annotatedSymbolPointer: KtSymbolPointer<KtAnnotatedSymbol>,
|
annotationsProvider: AnnotationsProvider,
|
||||||
ktModule: KtModule,
|
|
||||||
index: Int,
|
index: Int,
|
||||||
owner: PsiModifierList,
|
owner: PsiModifierList,
|
||||||
) : this(
|
) : this(
|
||||||
classId = classId,
|
classId = classId,
|
||||||
annotatedSymbolPointer = annotatedSymbolPointer,
|
annotationsProvider = annotationsProvider,
|
||||||
ktModule = ktModule,
|
|
||||||
index = index,
|
index = index,
|
||||||
specialAnnotationApplication = null,
|
specialAnnotationApplication = null,
|
||||||
owner = owner,
|
owner = owner,
|
||||||
@@ -58,22 +46,17 @@ internal class SymbolLightLazyAnnotation private constructor(
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
classId: ClassId,
|
classId: ClassId,
|
||||||
annotatedSymbolPointer: KtSymbolPointer<KtAnnotatedSymbol>,
|
annotationsProvider: AnnotationsProvider,
|
||||||
ktModule: KtModule,
|
|
||||||
annotationApplication: KtAnnotationApplication,
|
annotationApplication: KtAnnotationApplication,
|
||||||
owner: PsiModifierList,
|
owner: PsiModifierList,
|
||||||
) : this(
|
) : this(
|
||||||
classId = classId,
|
classId = classId,
|
||||||
annotatedSymbolPointer = annotatedSymbolPointer,
|
annotationsProvider = annotationsProvider,
|
||||||
ktModule = ktModule,
|
|
||||||
index = null,
|
index = null,
|
||||||
specialAnnotationApplication = annotationApplication,
|
specialAnnotationApplication = annotationApplication,
|
||||||
owner = owner,
|
owner = owner,
|
||||||
)
|
)
|
||||||
|
|
||||||
inline fun <T> withAnnotatedSymbol(crossinline action: context(KtAnalysisSession) (KtAnnotatedSymbol) -> T): T =
|
|
||||||
annotatedSymbolPointer.withSymbol(ktModule, action)
|
|
||||||
|
|
||||||
override val kotlinOrigin: KtCallElement? get() = annotationApplication.value.psi
|
override val kotlinOrigin: KtCallElement? get() = annotationApplication.value.psi
|
||||||
|
|
||||||
override fun getQualifiedName(): String = fqName.asString()
|
override fun getQualifiedName(): String = fqName.asString()
|
||||||
@@ -88,7 +71,7 @@ internal class SymbolLightLazyAnnotation private constructor(
|
|||||||
other is SymbolLightLazyAnnotation &&
|
other is SymbolLightLazyAnnotation &&
|
||||||
other.fqName == fqName &&
|
other.fqName == fqName &&
|
||||||
other.index == index &&
|
other.index == index &&
|
||||||
other.ktModule == ktModule &&
|
annotationsProvider.isTheSameAs(other.annotationsProvider) &&
|
||||||
other.parent == parent
|
other.parent == parent
|
||||||
|
|
||||||
override fun hashCode(): Int = fqName.hashCode()
|
override fun hashCode(): Int = fqName.hashCode()
|
||||||
|
|||||||
Reference in New Issue
Block a user