diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolInfoProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolInfoProvider.kt index a231b4c5f55..b01844fe05b 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolInfoProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolInfoProvider.kt @@ -8,23 +8,17 @@ package org.jetbrains.kotlin.analysis.api.fir.components import org.jetbrains.kotlin.analysis.api.components.KtSymbolInfoProvider import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession import org.jetbrains.kotlin.analysis.api.fir.symbols.* -import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirBackingFieldSymbol -import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSymbol -import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSyntheticJavaPropertySymbol -import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol -import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol import org.jetbrains.kotlin.analysis.api.symbols.KtReceiverParameterSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget import org.jetbrains.kotlin.fir.analysis.checkers.getAllowedAnnotationTargets -import org.jetbrains.kotlin.fir.declarations.FirProperty -import org.jetbrains.kotlin.fir.declarations.getDeprecationForCallSite -import org.jetbrains.kotlin.fir.declarations.getJvmNameFromAnnotation -import org.jetbrains.kotlin.fir.declarations.hasAnnotation +import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.load.java.JvmAbi @@ -41,6 +35,12 @@ internal class KtFirSymbolInfoProvider( override fun getDeprecation(symbol: KtSymbol): DeprecationInfo? { if (symbol is KtFirBackingFieldSymbol || symbol is KtFirPackageSymbol || symbol is KtReceiverParameterSymbol) return null require(symbol is KtFirSymbol<*>) { "${this::class}" } + + // Optimization: Avoid building `firSymbol` of `KtFirPsiJavaClassSymbol` if it definitely isn't deprecated. + if (symbol is KtFirPsiJavaClassSymbol && !symbol.mayHaveDeprecation()) { + return null + } + return when (val firSymbol = symbol.firSymbol) { is FirPropertySymbol -> { firSymbol.getDeprecationForCallSite(apiVersion, AnnotationUseSiteTarget.PROPERTY) @@ -51,6 +51,15 @@ internal class KtFirSymbolInfoProvider( } } + private fun KtFirPsiJavaClassSymbol.mayHaveDeprecation(): Boolean { + if (!hasAnnotations) return false + + // Check the simple names of the Java annotations. While presence of such an annotation name does not prove deprecation, it is a + // necessary condition for it. Type aliases are not a problem here: Java code cannot access Kotlin type aliases. (Currently, + // deprecation annotation type aliases do not work in Kotlin, either, but this might change in the future.) + return annotationSimpleNames.any { it != null && it in deprecationAnnotationSimpleNames } + } + override fun getDeprecation(symbol: KtSymbol, annotationUseSiteTarget: AnnotationUseSiteTarget?): DeprecationInfo? { require(symbol is KtFirSymbol<*>) return if (annotationUseSiteTarget != null) { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirPsiJavaClassSymbol.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirPsiJavaClassSymbol.kt index 5d9e04816ce..2ee56a5de8f 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirPsiJavaClassSymbol.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirPsiJavaClassSymbol.kt @@ -16,7 +16,6 @@ import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForD import org.jetbrains.kotlin.analysis.api.fir.utils.cached import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList import org.jetbrains.kotlin.analysis.api.impl.base.symbols.toKtClassKind -import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol @@ -25,19 +24,18 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.api.types.KtType +import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.firClassByPsiClassProvider +import org.jetbrains.kotlin.analysis.project.structure.getKtModule +import org.jetbrains.kotlin.analysis.utils.classIdIfNonLocal import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibility -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.analysis.project.structure.getKtModule -import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.firClassByPsiClassProvider -import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol -import org.jetbrains.kotlin.analysis.utils.classIdIfNonLocal -import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.java.classKind import org.jetbrains.kotlin.fir.java.modality +import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.Name /** * Implements [KtNamedClassOrObjectSymbol] for a Java class. The underlying [firSymbol] is built lazily and only when needed. Many simple @@ -105,7 +103,13 @@ internal class KtFirPsiJavaClassSymbol( } val hasTypeParameters: Boolean - get() = withValidityAssertion { javaClass.typeParameters.isNotEmpty() } + get() = withValidityAssertion { psi.typeParameters.isNotEmpty() } + + val annotationSimpleNames: List + get() = withValidityAssertion { psi.annotations.map { it.nameReferenceElement?.referenceName } } + + val hasAnnotations: Boolean + get() = withValidityAssertion { psi.annotations.isNotEmpty() } override val isData: Boolean get() = withValidityAssertion { false } override val isInline: Boolean get() = withValidityAssertion { false } @@ -152,8 +156,8 @@ internal class KtFirPsiJavaClassSymbol( } override val annotationsList: KtAnnotationsList by cached { - if (javaClass.annotations.isEmpty()) KtEmptyAnnotationsList(token) - else KtFirAnnotationListForDeclaration.create(firSymbol, analysisSession.useSiteSession, token) + if (hasAnnotations) KtFirAnnotationListForDeclaration.create(firSymbol, analysisSession.useSiteSession, token) + else KtEmptyAnnotationsList(token) } context(KtAnalysisSession) diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/deprecationUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/deprecationUtils.kt index c94a49df5c8..f211d6da00f 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/deprecationUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/deprecationUtils.kt @@ -178,6 +178,12 @@ private fun FirAnnotation.getDeprecationLevel(): DeprecationLevelValue? { return DeprecationLevelValue.values().find { it.name == targetName } } +val deprecationAnnotationSimpleNames: Set = setOf( + StandardClassIds.Annotations.Deprecated.shortClassName.asString(), + StandardClassIds.Annotations.Java.Deprecated.shortClassName.asString(), + StandardClassIds.Annotations.SinceKotlin.shortClassName.asString(), +) + private fun List.extractDeprecationAnnotationInfoPerUseSite( session: FirSession, fromJava: Boolean ): DeprecationAnnotationInfoPerUseSiteStorage {