diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/SymbolLightAnnotationForAnnotationCall.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/SymbolLightAnnotationForAnnotationCall.kt deleted file mode 100644 index 4dc95de781d..00000000000 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/SymbolLightAnnotationForAnnotationCall.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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 com.intellij.psi.PsiAnnotation -import com.intellij.psi.PsiAnnotationParameterList -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiModifierList -import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication -import org.jetbrains.kotlin.asJava.classes.lazyPub -import org.jetbrains.kotlin.light.classes.symbol.basicIsEquivalentTo -import org.jetbrains.kotlin.psi.KtCallElement - -internal class SymbolLightAnnotationForAnnotationCall( - private val annotationCall: KtAnnotationApplication, - parent: PsiModifierList, -) : SymbolLightAbstractAnnotation(parent) { - private val _parameterList: PsiAnnotationParameterList by lazyPub { - symbolLightAnnotationParameterList(annotationCall.arguments) - } - - override fun getParameterList(): PsiAnnotationParameterList = _parameterList - - override val kotlinOrigin: KtCallElement? = annotationCall.psi - - override fun getQualifiedName(): String? = annotationCall.classId?.asSingleFqName()?.asString() - - override fun getName(): String? = qualifiedName - - override fun equals(other: Any?): Boolean = - this === other || - (other is SymbolLightAnnotationForAnnotationCall && - kotlinOrigin == other.kotlinOrigin && - annotationCall == other.annotationCall) - - override fun hashCode(): Int = kotlinOrigin.hashCode() - - override fun isEquivalentTo(another: PsiElement?): Boolean = - basicIsEquivalentTo(this, another as? PsiAnnotation) -} diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/symbolAnnotationsUtils.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/symbolAnnotationsUtils.kt index c19dbb84484..f66cb9c770b 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/symbolAnnotationsUtils.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/symbolAnnotationsUtils.kt @@ -5,34 +5,24 @@ package org.jetbrains.kotlin.light.classes.symbol.annotations -import com.intellij.psi.* +import com.intellij.psi.PsiClassType +import com.intellij.psi.PsiElement import com.intellij.psi.impl.light.LightReferenceListBuilder -import org.jetbrains.annotations.NotNull -import org.jetbrains.annotations.Nullable import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.annotations.* import org.jetbrains.kotlin.analysis.api.annotations.KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue import org.jetbrains.kotlin.analysis.api.components.buildClassType import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol -import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode import org.jetbrains.kotlin.builtins.StandardNames -import org.jetbrains.kotlin.builtins.StandardNames.DEFAULT_VALUE_PARAMETER import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget -import org.jetbrains.kotlin.light.classes.symbol.NullabilityType import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase -import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightMethod -import org.jetbrains.kotlin.load.java.JvmAbi -import org.jetbrains.kotlin.load.java.JvmAnnotationNames -import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.JvmNames.JVM_OVERLOADS_CLASS_ID import org.jetbrains.kotlin.name.JvmNames.JVM_SYNTHETIC_ANNOTATION_CLASS_ID -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue -import java.lang.annotation.ElementType internal fun KtAnnotatedSymbol.hasJvmSyntheticAnnotation( annotationUseSiteTarget: AnnotationUseSiteTarget? = null, @@ -91,201 +81,6 @@ internal fun KtAnnotatedSymbol.findAnnotation( } } -internal fun NullabilityType.computeNullabilityAnnotation(parent: PsiModifierList): SymbolLightSimpleAnnotation? = when (this) { - NullabilityType.NotNull -> NotNull::class.java - NullabilityType.Nullable -> Nullable::class.java - else -> null -}?.let { - SymbolLightSimpleAnnotation(it.name, parent) -} - -context(KtAnalysisSession) -internal fun KtAnnotatedSymbol.computeAnnotations( - modifierList: PsiModifierList, - nullability: NullabilityType, - annotationUseSiteTarget: AnnotationUseSiteTarget?, - includeAnnotationsWithoutSite: Boolean = true, -): List { - val parent = modifierList.parent - val nullabilityAnnotation = nullability.computeNullabilityAnnotation(modifierList) - val parentIsAnnotation = (parent as? PsiClass)?.isAnnotationType == true - - val result = mutableListOf() - - if (parent is SymbolLightMethod<*>) { - if (parent.isDelegated || parent.isOverride()) { - result.add(SymbolLightSimpleAnnotation(java.lang.Override::class.java.name, modifierList)) - } - } - - val foundAnnotations = hashSetOf() - for (annotation in annotations) { - annotation.classId?.asFqNameString()?.let(foundAnnotations::add) - - val siteTarget = annotation.useSiteTarget - if (siteTarget == annotationUseSiteTarget || includeAnnotationsWithoutSite && siteTarget == null) { - result.add(SymbolLightAnnotationForAnnotationCall(annotation, modifierList)) - } - } - - if (parentIsAnnotation) { - for (annotation in annotations) { - val convertedAnnotation = annotation.tryConvertAsRetention(foundAnnotations, modifierList) - ?: annotation.tryConvertAsTarget(foundAnnotations, modifierList) - ?: annotation.tryConvertAsMustBeDocumented(foundAnnotations, modifierList) - ?: annotation.tryConvertAsRepeatable(foundAnnotations, modifierList, this) - ?: continue - - result += convertedAnnotation - } - - if (StandardClassIds.Annotations.Retention.asFqNameString() !in foundAnnotations) { - result += createRetentionAnnotation(modifierList) - } - } - - if (nullabilityAnnotation != null) { - result.add(nullabilityAnnotation) - } - - return result -} - -private fun KtAnnotationApplication.tryConvertAsRetention(foundAnnotations: Set, modifierList: PsiModifierList): PsiAnnotation? { - if (classId != StandardClassIds.Annotations.Retention) return null - if (JvmAnnotationNames.RETENTION_ANNOTATION.asString() in foundAnnotations) return null - - val argumentWithKotlinRetention = arguments.firstOrNull { - it.name == DEFAULT_VALUE_PARAMETER - }?.expression as? KtEnumEntryAnnotationValue - - val kotlinRetentionName = argumentWithKotlinRetention?.callableId?.callableName?.asString() - return createRetentionAnnotation(modifierList, kotlinRetentionName) -} - -private fun KtAnnotationApplication.tryConvertAsTarget( - foundAnnotations: Set, - modifierList: PsiModifierList -): PsiAnnotation? = tryConvertAs( - foundAnnotations = foundAnnotations, - modifierList = modifierList, - kotlinClassId = StandardClassIds.Annotations.Target, - javaQualifier = JvmAnnotationNames.TARGET_ANNOTATION.asString(), - argumentsComputer = fun(): List? { - val allowedKotlinTargets = arguments.firstOrNull()?.expression as? KtArrayAnnotationValue ?: return null - val javaTargetNames = allowedKotlinTargets.values.mapNotNullTo(linkedSetOf(), KtAnnotationValue::mapToJavaTarget) - return listOf( - KtNamedAnnotationValue( - name = DEFAULT_VALUE_PARAMETER, - expression = KtArrayAnnotationValue( - values = javaTargetNames.map { - KtEnumEntryAnnotationValue( - callableId = CallableId( - classId = StandardClassIds.Annotations.Java.ElementType, - callableName = Name.identifier(it), - ), - sourcePsi = null, - ) - }, - sourcePsi = null, - ) - ) - ) - } -) - -private fun KtAnnotationValue.mapToJavaTarget(): String? { - if (this !is KtEnumEntryAnnotationValue) return null - val callableId = callableId ?: return null - if (callableId.classId != StandardClassIds.AnnotationTarget) return null - return when (callableId.callableName.asString()) { - AnnotationTarget.CLASS.name -> ElementType.TYPE - AnnotationTarget.ANNOTATION_CLASS.name -> ElementType.ANNOTATION_TYPE - AnnotationTarget.FIELD.name -> ElementType.FIELD - AnnotationTarget.LOCAL_VARIABLE.name -> ElementType.LOCAL_VARIABLE - AnnotationTarget.VALUE_PARAMETER.name -> ElementType.PARAMETER - AnnotationTarget.CONSTRUCTOR.name -> ElementType.CONSTRUCTOR - AnnotationTarget.FUNCTION.name, AnnotationTarget.PROPERTY_GETTER.name, AnnotationTarget.PROPERTY_SETTER.name -> ElementType.METHOD - AnnotationTarget.TYPE_PARAMETER.name -> ElementType.TYPE_PARAMETER - AnnotationTarget.TYPE.name -> ElementType.TYPE_USE - else -> null - }?.name -} - -context(KtAnalysisSession) -private fun KtAnnotationApplication.tryConvertAsRepeatable( - foundAnnotations: Set, - modifierList: PsiModifierList, - ktAnnotatedSymbol: KtAnnotatedSymbol -): PsiAnnotation? = tryConvertAs( - foundAnnotations = foundAnnotations, - modifierList = modifierList, - kotlinClassId = StandardClassIds.Annotations.Repeatable, - javaQualifier = JvmAnnotationNames.REPEATABLE_ANNOTATION.asString(), - argumentsComputer = fun(): List? { - if (ktAnnotatedSymbol !is KtNamedClassOrObjectSymbol) return null - val annotationClassId = ktAnnotatedSymbol.classIdIfNonLocal ?: return null - - return listOf( - KtNamedAnnotationValue( - name = DEFAULT_VALUE_PARAMETER, - expression = KtNonLocalKClassAnnotationValue( - classId = annotationClassId.createNestedClassId(Name.identifier(JvmAbi.REPEATABLE_ANNOTATION_CONTAINER_NAME)), - sourcePsi = null, - ) - ) - ) - }, -) - -private fun KtAnnotationApplication.tryConvertAsMustBeDocumented( - foundAnnotations: Set, - modifierList: PsiModifierList, -): PsiAnnotation? = tryConvertAs( - foundAnnotations = foundAnnotations, - modifierList = modifierList, - kotlinClassId = StandardClassIds.Annotations.MustBeDocumented, - javaQualifier = JvmAnnotationNames.DOCUMENTED_ANNOTATION.asString(), -) - -private fun KtAnnotationApplication.tryConvertAs( - foundAnnotations: Set, - modifierList: PsiModifierList, - kotlinClassId: ClassId, - javaQualifier: String, - argumentsComputer: (() -> List?)? = null, -): PsiAnnotation? { - if (classId != kotlinClassId) return null - if (javaQualifier in foundAnnotations) return null - val arguments = if (argumentsComputer != null) { - argumentsComputer() ?: return null - } else { - emptyList() - } - - return SymbolLightSimpleAnnotation(fqName = javaQualifier, parent = modifierList, arguments = arguments) -} - -private fun createRetentionAnnotation( - modifierList: PsiModifierList, - retentionName: String? = null, -): PsiAnnotation = SymbolLightSimpleAnnotation( - fqName = JvmAnnotationNames.RETENTION_ANNOTATION.asString(), - parent = modifierList, - arguments = listOf( - KtNamedAnnotationValue( - name = DEFAULT_VALUE_PARAMETER, - expression = KtEnumEntryAnnotationValue( - callableId = CallableId( - StandardClassIds.Annotations.Java.RetentionPolicy, - Name.identifier(retentionName ?: AnnotationRetention.RUNTIME.name), - ), - sourcePsi = null, - ) - ) - ) -) - context(KtAnalysisSession) internal fun KtAnnotatedSymbol.computeThrowsList( builder: LightReferenceListBuilder, diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForFacade.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForFacade.kt index cbc71ba1dc0..19765a56ad0 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForFacade.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForFacade.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.analysis.api.scopes.KtScope import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility +import org.jetbrains.kotlin.analysis.api.symbols.pointers.symbolPointerOfType import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade import org.jetbrains.kotlin.asJava.classes.lazyPub @@ -25,12 +26,8 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.fileClasses.isJvmMultifileClassFile import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName import org.jetbrains.kotlin.idea.KotlinLanguage -import org.jetbrains.kotlin.light.classes.symbol.NullabilityType import org.jetbrains.kotlin.light.classes.symbol.analyzeForLightClasses -import org.jetbrains.kotlin.light.classes.symbol.annotations.SimpleAnnotationsBox -import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations -import org.jetbrains.kotlin.light.classes.symbol.annotations.hasInlineOnlyAnnotation -import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmFieldAnnotation +import org.jetbrains.kotlin.light.classes.symbol.annotations.* import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightField import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SimpleModifiersBox import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList @@ -67,21 +64,17 @@ class SymbolLightClassForFacade( SymbolLightClassModifierList( containingDeclaration = this, modifiersBox = SimpleModifiersBox(PsiModifier.PUBLIC, PsiModifier.FINAL), - annotationsBox = SimpleAnnotationsBox { modifierList -> - if (multiFileClass) { - emptyList() - } else { - withFileSymbols { fileSymbols -> - fileSymbols.flatMap { - it.computeAnnotations( - modifierList = modifierList, - nullability = NullabilityType.Unknown, - annotationUseSiteTarget = AnnotationUseSiteTarget.FILE, - includeAnnotationsWithoutSite = false, - ) - } - } - } + annotationsBox = if (multiFileClass) { + EmptyAnnotationsBox + } else { + LazyAnnotationsBox( + annotationsProvider = SymbolAnnotationsProvider( + ktModule = ktModule, + annotatedSymbolPointer = firstFileInFacade.symbolPointerOfType(), + annotationUseSiteTarget = AnnotationUseSiteTarget.FILE, + acceptAnnotationsWithoutSite = true, + ) + ) }, ) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForRepeatableAnnotationContainer.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForRepeatableAnnotationContainer.kt index e8259fcf252..12721c764a2 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForRepeatableAnnotationContainer.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForRepeatableAnnotationContainer.kt @@ -10,10 +10,7 @@ import kotlinx.collections.immutable.persistentHashSetOf import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.elements.KtLightField import org.jetbrains.kotlin.builtins.StandardNames -import org.jetbrains.kotlin.light.classes.symbol.NullabilityType -import org.jetbrains.kotlin.light.classes.symbol.annotations.SimpleAnnotationsBox -import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolLightSimpleAnnotation -import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations +import org.jetbrains.kotlin.light.classes.symbol.annotations.* import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightRepeatableAnnotationContainerMethod import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SimpleModifiersBox import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList @@ -43,19 +40,17 @@ internal class SymbolLightClassForRepeatableAnnotationContainer(private val cont // It is marked as Abstract because all the annotation classes are marked as Abstract // It is marked as Static because all nested interfaces are marked as Static modifiersBox = SimpleModifiersBox(PsiModifier.PUBLIC, PsiModifier.STATIC, PsiModifier.ABSTRACT), - annotationsBox = SimpleAnnotationsBox { psiModifierList -> - val annotations = withClassOrObjectSymbol { classOrObjectSymbol -> - classOrObjectSymbol.computeAnnotations( - modifierList = psiModifierList, - nullability = NullabilityType.Unknown, - annotationUseSiteTarget = null, - ) - }.filter { - it.qualifiedName in allowedAnnotations - } - - annotations + SymbolLightSimpleAnnotation(fqName = KOTLIN_JVM_INTERNAL_REPEATABLE_CONTAINER, parent = psiModifierList) - }, + annotationsBox = LazyAnnotationsBox( + annotationsProvider = SymbolAnnotationsProvider( + ktModule = ktModule, + annotatedSymbolPointer = classOrObjectSymbolPointer, + ), + additionalAnnotationsProvider = CompositeAdditionalAnnotationsProvider( + SimpleAdditionalAnnotationsProvider(KOTLIN_JVM_INTERNAL_REPEATABLE_CONTAINER), + AbstractClassAdditionalAnnotationsProvider, + ), + annotationFilter = SimpleAnnotationFilter(allowedAnnotations), + ), ) override fun computeOwnMethods(): List = listOf( @@ -74,13 +69,14 @@ internal class SymbolLightClassForRepeatableAnnotationContainer(private val cont override fun hashCode(): Int = containerOwner.hashCode() companion object { + private const val KOTLIN_JVM_INTERNAL_REPEATABLE_CONTAINER = "kotlin.jvm.internal.RepeatableContainer" + private val allowedAnnotations = persistentHashSetOf( CommonClassNames.JAVA_LANG_ANNOTATION_RETENTION, StandardNames.FqNames.retention.asString(), CommonClassNames.JAVA_LANG_ANNOTATION_TARGET, StandardNames.FqNames.target.asString(), + KOTLIN_JVM_INTERNAL_REPEATABLE_CONTAINER, ) - - private const val KOTLIN_JVM_INTERNAL_REPEATABLE_CONTAINER = "kotlin.jvm.internal.RepeatableContainer" } } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForEnumEntry.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForEnumEntry.kt index 8b4dafa25f6..fbb845f9fcb 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForEnumEntry.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForEnumEntry.kt @@ -8,13 +8,13 @@ package org.jetbrains.kotlin.light.classes.symbol.fields import com.intellij.psi.* import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol +import org.jetbrains.kotlin.analysis.api.symbols.pointers.symbolPointerOfType import org.jetbrains.kotlin.asJava.classes.cannotModify import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget -import org.jetbrains.kotlin.light.classes.symbol.NullabilityType import org.jetbrains.kotlin.light.classes.symbol.analyzeForLightClasses -import org.jetbrains.kotlin.light.classes.symbol.annotations.SimpleAnnotationsBox -import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations +import org.jetbrains.kotlin.light.classes.symbol.annotations.LazyAnnotationsBox +import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolAnnotationsProvider import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForClassOrObject import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForEnumEntry import org.jetbrains.kotlin.light.classes.symbol.isOriginEquivalentTo @@ -38,15 +38,14 @@ internal class SymbolLightFieldForEnumEntry( SymbolLightMemberModifierList( containingDeclaration = this, modifiersBox = SimpleModifiersBox(PsiModifier.STATIC, PsiModifier.FINAL, PsiModifier.PUBLIC), - annotationsBox = SimpleAnnotationsBox { modifierList -> - withEnumEntrySymbol { enumEntrySymbol -> - enumEntrySymbol.computeAnnotations( - modifierList, - nullability = NullabilityType.Unknown, // there is no need to add nullability annotations on enum entries - annotationUseSiteTarget = AnnotationUseSiteTarget.FIELD, - ) - } - }, + annotationsBox = LazyAnnotationsBox( + annotationsProvider = SymbolAnnotationsProvider( + ktModule = ktModule, + annotatedSymbolPointer = enumEntry.symbolPointerOfType(), + annotationUseSiteTarget = AnnotationUseSiteTarget.FIELD, + acceptAnnotationsWithoutSite = true, + ) + ), ) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForProperty.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForProperty.kt index ece79f53b40..6b8a3692797 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForProperty.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForProperty.kt @@ -19,8 +19,9 @@ import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.light.classes.symbol.* -import org.jetbrains.kotlin.light.classes.symbol.annotations.SimpleAnnotationsBox -import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations +import org.jetbrains.kotlin.light.classes.symbol.annotations.LazyAnnotationsBox +import org.jetbrains.kotlin.light.classes.symbol.annotations.NullabilityAnnotationsProvider +import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolAnnotationsProvider import org.jetbrains.kotlin.light.classes.symbol.annotations.hasDeprecatedAnnotation import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase import org.jetbrains.kotlin.light.classes.symbol.modifierLists.LazyModifiersBox @@ -147,21 +148,23 @@ internal class SymbolLightFieldForProperty private constructor( SymbolLightMemberModifierList( containingDeclaration = this, modifiersBox = LazyModifiersBox(initializerValue, ::computeModifiers), - annotationsBox = SimpleAnnotationsBox { modifierList -> - withPropertySymbol { propertySymbol -> - val nullability = if (!(propertySymbol is KtKotlinPropertySymbol && propertySymbol.isLateInit)) { - getTypeNullability(propertySymbol.returnType) - } else { - NullabilityType.Unknown + annotationsBox = LazyAnnotationsBox( + annotationsProvider = SymbolAnnotationsProvider( + ktModule = ktModule, + annotatedSymbolPointer = propertySymbolPointer, + annotationUseSiteTarget = AnnotationUseSiteTarget.FIELD, + acceptAnnotationsWithoutSite = true, + ), + additionalAnnotationsProvider = NullabilityAnnotationsProvider { + withPropertySymbol { propertySymbol -> + if (!(propertySymbol is KtKotlinPropertySymbol && propertySymbol.isLateInit)) { + getTypeNullability(propertySymbol.returnType) + } else { + NullabilityType.Unknown + } } - - propertySymbol.computeAnnotations( - modifierList = modifierList, - nullability = nullability, - annotationUseSiteTarget = AnnotationUseSiteTarget.FIELD, - ) } - }, + ), ) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt index 6e8352be856..cde9b9c7115 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt @@ -141,30 +141,6 @@ internal class SymbolLightAccessorMethod private constructor( } } - private fun computeAnnotations(modifierList: PsiModifierList): List = analyzeForLightClasses(ktModule) { - val nullabilityApplicable = isGetter && - !modifierList.hasModifierProperty(PsiModifier.PRIVATE) && - !(isParameter && containingClass.isAnnotationType) - - val propertySymbol = propertySymbol() - val nullabilityType = if (nullabilityApplicable) getTypeNullability(propertySymbol.returnType) else NullabilityType.Unknown - val annotationsFromProperty = propertySymbol.computeAnnotations( - modifierList = modifierList, - nullability = nullabilityType, - annotationUseSiteTarget = accessorSite, - includeAnnotationsWithoutSite = false, - ) - - val propertyAccessorSymbol = propertyAccessorSymbol() - val annotationsFromAccessor = propertyAccessorSymbol.computeAnnotations( - modifierList = modifierList, - nullability = NullabilityType.Unknown, - annotationUseSiteTarget = accessorSite, - ) - - annotationsFromProperty + annotationsFromAccessor - } - private fun computeModifiers(modifier: String): Map? = when (modifier) { in LazyModifiersBox.VISIBILITY_MODIFIERS -> LazyModifiersBox.computeVisibilityForMember(ktModule, propertyAccessorSymbolPointer) @@ -205,7 +181,34 @@ internal class SymbolLightAccessorMethod private constructor( SymbolLightMemberModifierList( containingDeclaration = this, modifiersBox = LazyModifiersBox(computer = ::computeModifiers), - annotationsBox = SimpleAnnotationsBox(::computeAnnotations), + annotationsBox = LazyAnnotationsBox( + annotationsProvider = CompositeAnnotationsProvider( + SymbolAnnotationsProvider( + ktModule = ktModule, + annotatedSymbolPointer = propertyAccessorSymbolPointer, + annotationUseSiteTarget = accessorSite, + acceptAnnotationsWithoutSite = true, + ), + SymbolAnnotationsProvider( + ktModule = ktModule, + annotatedSymbolPointer = containingPropertySymbolPointer, + annotationUseSiteTarget = accessorSite, + ), + ), + additionalAnnotationsProvider = NullabilityAnnotationsProvider { + val nullabilityApplicable = isGetter && + !(isParameter && containingClass.isAnnotationType) && + !modifierList.hasModifierProperty(PsiModifier.PRIVATE) + + if (nullabilityApplicable) { + analyzeForLightClasses(ktModule) { + getTypeNullability(propertySymbol().returnType) + } + } else { + NullabilityType.Unknown + } + } + ), ) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightConstructor.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightConstructor.kt index 3750ae8fdf0..50a01c4f5a9 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightConstructor.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightConstructor.kt @@ -9,9 +9,8 @@ import com.intellij.psi.* import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol import org.jetbrains.kotlin.asJava.classes.lazyPub -import org.jetbrains.kotlin.light.classes.symbol.NullabilityType -import org.jetbrains.kotlin.light.classes.symbol.annotations.SimpleAnnotationsBox -import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations +import org.jetbrains.kotlin.light.classes.symbol.annotations.LazyAnnotationsBox +import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolAnnotationsProvider import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForEnumEntry import org.jetbrains.kotlin.light.classes.symbol.modifierLists.LazyModifiersBox @@ -57,15 +56,12 @@ internal class SymbolLightConstructor( initialValue = initialValue, computer = ::computeModifiers, ), - annotationsBox = SimpleAnnotationsBox { modifierList -> - withFunctionSymbol { constructorSymbol -> - constructorSymbol.computeAnnotations( - modifierList = modifierList, - nullability = NullabilityType.Unknown, - annotationUseSiteTarget = null, - ) - } - }, + annotationsBox = LazyAnnotationsBox( + annotationsProvider = SymbolAnnotationsProvider( + ktModule = ktModule, + annotatedSymbolPointer = functionSymbolPointer, + ) + ), ) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightSimpleMethod.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightSimpleMethod.kt index 3894fbf4cbd..c0e4a4fdc72 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightSimpleMethod.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightSimpleMethod.kt @@ -17,10 +17,7 @@ import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.light.classes.symbol.* -import org.jetbrains.kotlin.light.classes.symbol.annotations.SimpleAnnotationsBox -import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations -import org.jetbrains.kotlin.light.classes.symbol.annotations.hasInlineOnlyAnnotation -import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmStaticAnnotation +import org.jetbrains.kotlin.light.classes.symbol.annotations.* import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase import org.jetbrains.kotlin.light.classes.symbol.modifierLists.LazyModifiersBox import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightMemberModifierList @@ -72,25 +69,6 @@ internal class SymbolLightSimpleMethod( override fun getTypeParameterList(): PsiTypeParameterList? = _typeParameterList override fun getTypeParameters(): Array = _typeParameterList?.typeParameters ?: PsiTypeParameter.EMPTY_ARRAY - private fun computeAnnotations( - modifierList: PsiModifierList, - ): List = withFunctionSymbol { functionSymbol -> - val nullability = when { - modifierList.hasModifierProperty(PsiModifier.PRIVATE) -> NullabilityType.Unknown - functionSymbol.isSuspend -> /* Any? */ NullabilityType.Nullable - else -> { - val returnType = functionSymbol.returnType - if (returnType.isVoidType) NullabilityType.Unknown else getTypeNullability(returnType) - } - } - - functionSymbol.computeAnnotations( - modifierList = modifierList, - nullability = nullability, - annotationUseSiteTarget = null, - ) - } - private fun computeModifiers(modifier: String): Map? = when (modifier) { in LazyModifiersBox.MODALITY_MODIFIERS -> { ifInlineOnly { return modifiersForInlineOnlyCase() } @@ -160,7 +138,29 @@ internal class SymbolLightSimpleMethod( SymbolLightMemberModifierList( containingDeclaration = this, modifiersBox = LazyModifiersBox(computer = ::computeModifiers), - annotationsBox = SimpleAnnotationsBox(::computeAnnotations), + annotationsBox = LazyAnnotationsBox( + annotationsProvider = SymbolAnnotationsProvider( + ktModule = ktModule, + annotatedSymbolPointer = functionSymbolPointer, + ), + additionalAnnotationsProvider = CompositeAdditionalAnnotationsProvider( + NullabilityAnnotationsProvider { + if (modifierList.hasModifierProperty(PsiModifier.PRIVATE)) { + NullabilityType.Unknown + } else { + withFunctionSymbol { functionSymbol -> + if (functionSymbol.isSuspend) { // Any? + NullabilityType.Nullable + } else { + val returnType = functionSymbol.returnType + if (returnType.isVoidType) NullabilityType.Unknown else getTypeNullability(returnType) + } + } + } + }, + MethodAdditionalAnnotationsProvider, + ), + ) ) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightParameter.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightParameter.kt index 537e87722d3..b073333bdd5 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightParameter.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightParameter.kt @@ -10,9 +10,9 @@ import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget -import org.jetbrains.kotlin.light.classes.symbol.NullabilityType -import org.jetbrains.kotlin.light.classes.symbol.annotations.SimpleAnnotationsBox -import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations +import org.jetbrains.kotlin.light.classes.symbol.annotations.LazyAnnotationsBox +import org.jetbrains.kotlin.light.classes.symbol.annotations.NullabilityAnnotationsProvider +import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolAnnotationsProvider import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightMethodBase import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList import org.jetbrains.kotlin.light.classes.symbol.withSymbol @@ -30,21 +30,17 @@ internal class SymbolLightParameter( private val _modifierList: PsiModifierList by lazyPub { SymbolLightClassModifierList( containingDeclaration = this, - annotationsBox = SimpleAnnotationsBox { modifierList -> - val annotationSite = isConstructorParameterSymbol.ifTrue { - AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER - } - - parameterSymbolPointer.withSymbol(ktModule) { parameterSymbol -> - val nullability = if (parameterSymbol.isVararg) NullabilityType.NotNull else super.nullabilityType - parameterSymbol.computeAnnotations( - modifierList = modifierList, - nullability = nullability, - annotationUseSiteTarget = annotationSite, - includeAnnotationsWithoutSite = true, - ) - } - }, + annotationsBox = LazyAnnotationsBox( + annotationsProvider = SymbolAnnotationsProvider( + ktModule = ktModule, + annotatedSymbolPointer = parameterSymbolPointer, + annotationUseSiteTarget = isConstructorParameterSymbol.ifTrue { + AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER + }, + acceptAnnotationsWithoutSite = true, + ), + additionalAnnotationsProvider = NullabilityAnnotationsProvider(::nullabilityType), + ), ) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightParameterCommon.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightParameterCommon.kt index 6c60d37daa4..9aab747b3e5 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightParameterCommon.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightParameterCommon.kt @@ -51,11 +51,13 @@ internal abstract class SymbolLightParameterCommon( KtLightIdentifier(this, parameterDeclaration) } - protected val nullabilityType: NullabilityType by lazyPub { + protected fun nullabilityType(): NullabilityType { + if (isVarArgs) return NullabilityType.NotNull + val nullabilityApplicable = !containingMethod.hasModifierProperty(PsiModifier.PRIVATE) && !containingMethod.containingClass.let { it.isAnnotationType || it.isEnum } - if (nullabilityApplicable) { + return if (nullabilityApplicable) { parameterSymbolPointer.withSymbol(ktModule) { getTypeNullability(it.returnType) } } else { NullabilityType.Unknown diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightSetterParameter.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightSetterParameter.kt index 4b56f54e688..219f87fc453 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightSetterParameter.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightSetterParameter.kt @@ -12,13 +12,12 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget -import org.jetbrains.kotlin.light.classes.symbol.NullabilityType -import org.jetbrains.kotlin.light.classes.symbol.analyzeForLightClasses -import org.jetbrains.kotlin.light.classes.symbol.annotations.SimpleAnnotationsBox -import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations +import org.jetbrains.kotlin.light.classes.symbol.annotations.CompositeAnnotationsProvider +import org.jetbrains.kotlin.light.classes.symbol.annotations.LazyAnnotationsBox +import org.jetbrains.kotlin.light.classes.symbol.annotations.NullabilityAnnotationsProvider +import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolAnnotationsProvider import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightMethodBase import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList -import org.jetbrains.kotlin.light.classes.symbol.restoreSymbolOrThrowIfDisposed import org.jetbrains.kotlin.light.classes.symbol.withSymbol import org.jetbrains.kotlin.name.SpecialNames @@ -44,24 +43,22 @@ internal class SymbolLightSetterParameter( private val _modifierList: PsiModifierList by lazyPub { SymbolLightClassModifierList( containingDeclaration = this, - annotationsBox = SimpleAnnotationsBox { modifierList -> - analyzeForLightClasses(ktModule) { - val annotationsFromSetter = parameterSymbolPointer.restoreSymbolOrThrowIfDisposed().computeAnnotations( - modifierList = modifierList, - nullability = NullabilityType.Unknown, + annotationsBox = LazyAnnotationsBox( + annotationsProvider = CompositeAnnotationsProvider( + SymbolAnnotationsProvider( + ktModule = ktModule, + annotatedSymbolPointer = parameterSymbolPointer, annotationUseSiteTarget = AnnotationUseSiteTarget.SETTER_PARAMETER, - ) - - val annotationsFromProperty = containingPropertySymbolPointer.restoreSymbolOrThrowIfDisposed().computeAnnotations( - modifierList = modifierList, - nullability = nullabilityType, + acceptAnnotationsWithoutSite = true, + ), + SymbolAnnotationsProvider( + ktModule = ktModule, + annotatedSymbolPointer = containingPropertySymbolPointer, annotationUseSiteTarget = AnnotationUseSiteTarget.SETTER_PARAMETER, - includeAnnotationsWithoutSite = false, - ) - - annotationsFromSetter + annotationsFromProperty - } - }, + ), + ), + additionalAnnotationsProvider = NullabilityAnnotationsProvider(::nullabilityType), + ), ) }