diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt index 560696f0133..95da95f1b95 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt @@ -12,7 +12,12 @@ import org.jetbrains.kotlin.analysis.api.annotations.KtNamedAnnotationValue import org.jetbrains.kotlin.analysis.api.fir.annotations.mapAnnotationParameters import org.jetbrains.kotlin.analysis.api.fir.evaluate.FirAnnotationValueConverter import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol +import org.jetbrains.kotlin.builtins.StandardNames +import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget +import org.jetbrains.kotlin.fir.FirAnnotationContainer import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.getAnnotationsByClassId +import org.jetbrains.kotlin.fir.declarations.getStringArgument import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic @@ -31,6 +36,7 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDiagnosticWithSymbol import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeHiddenCandidateError import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.name.JvmNames import org.jetbrains.kotlin.psi.KtCallElement import org.jetbrains.kotlin.util.OperatorNameConventions @@ -116,3 +122,11 @@ internal fun FirAnnotation.toKtAnnotationInfo( */ internal val FirResolvedQualifier.isImplicitDispatchReceiver: Boolean get() = source?.kind == KtFakeSourceElementKind.ImplicitReceiver + +fun FirAnnotationContainer.getJvmNameFromAnnotation(session: FirSession, target: AnnotationUseSiteTarget? = null): String? { + val annotationCalls = getAnnotationsByClassId(JvmNames.Annotations.JvmName, session) + return annotationCalls.firstNotNullOfOrNull { call -> + call.getStringArgument(StandardNames.NAME) + ?.takeIf { target == null || call.useSiteTarget == target } + } +} diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/firAnnotationUtils.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/firAnnotationUtils.kt index d9279e6bf2f..dcda8a7ce60 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/firAnnotationUtils.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/firAnnotationUtils.kt @@ -5,12 +5,7 @@ package org.jetbrains.kotlin.analysis.api.fir.annotations -import org.jetbrains.kotlin.analysis.api.annotations.AnnotationUseSiteTargetFilter -import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationInfo -import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationWithArgumentsInfo -import org.jetbrains.kotlin.analysis.api.annotations.KtArrayAnnotationValue -import org.jetbrains.kotlin.analysis.api.annotations.KtEnumEntryAnnotationValue -import org.jetbrains.kotlin.analysis.api.annotations.KtNamedAnnotationValue +import org.jetbrains.kotlin.analysis.api.annotations.* import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationApplication import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationInfo import org.jetbrains.kotlin.analysis.utils.errors.withClassEntry @@ -18,23 +13,15 @@ import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget import org.jetbrains.kotlin.fir.FirAnnotationContainer import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.containingClassLookupTag -import org.jetbrains.kotlin.fir.declarations.FirResolvePhase -import org.jetbrains.kotlin.fir.declarations.resolvePhase -import org.jetbrains.kotlin.fir.declarations.resolved -import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId -import org.jetbrains.kotlin.fir.declarations.toAnnotationClassIdSafe +import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol -import org.jetbrains.kotlin.fir.resolve.transformers.plugin.CompilerRequiredAnnotationsHelper import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.resolvedAnnotationsWithArguments import org.jetbrains.kotlin.fir.symbols.resolvedAnnotationsWithClassIds import org.jetbrains.kotlin.fir.symbols.resolvedCompilerRequiredAnnotations import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry -import org.jetbrains.kotlin.name.CallableId -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.name.StandardClassIds +import org.jetbrains.kotlin.name.* import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment import java.lang.annotation.ElementType @@ -65,7 +52,7 @@ internal fun annotationsByClassId( .mapIndexedToAnnotationApplication(useSiteTargetFilter, useSiteSession, classId) { index, annotation -> annotation.asKtAnnotationApplicationForTargetAnnotation(useSiteSession, index) } - } else if (classId == StandardClassIds.Annotations.Java.Target && firSymbol.fir.resolvePhase < FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING) { + } else if (classId == JvmNames.Annotations.Java.Target && firSymbol.fir.resolvePhase < FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING) { annotationContainer.resolvedAnnotationsWithClassIds(firSymbol) .mapIndexedToAnnotationApplication(useSiteTargetFilter, useSiteSession, classId) { index, annotation -> annotation.asKtAnnotationApplicationForJavaTargetAnnotation(useSiteSession, index) @@ -140,7 +127,7 @@ private fun FirAnnotation.asKtAnnotationApplicationForJavaTargetAnnotation( ): KtAnnotationApplicationWithArgumentsInfo = asKtAnnotationApplicationForAnnotationWithEnumArgument( useSiteSession = useSiteSession, index = index, - expectedEnumClassId = StandardClassIds.Annotations.Java.ElementType, + expectedEnumClassId = JvmNames.Annotations.Java.ElementType, annotationParameterName = StandardClassIds.Annotations.ParameterNames.value, nameMapper = { ElementType.values().firstOrNull { enumValue -> enumValue.name == it }?.name }, ) @@ -193,7 +180,7 @@ internal fun hasAnnotation( useSiteSession: FirSession, annotationContainer: FirAnnotationContainer = firSymbol.fir, ): Boolean { - return if (firSymbol.isFromCompilerRequiredAnnotationsPhase(classId)) { + return if (firSymbol.isFromCompilerRequiredAnnotationsPhase(classId, useSiteSession)) { // this loop by index is required to avoid possible ConcurrentModificationException val annotations = annotationContainer.resolvedCompilerRequiredAnnotations(firSymbol) for (index in annotations.indices) { @@ -211,5 +198,7 @@ internal fun hasAnnotation( } } -private fun FirBasedSymbol<*>.isFromCompilerRequiredAnnotationsPhase(classId: ClassId): Boolean = - fir.resolvePhase < FirResolvePhase.TYPES && classId in CompilerRequiredAnnotationsHelper.REQUIRED_ANNOTATIONS +private fun FirBasedSymbol<*>.isFromCompilerRequiredAnnotationsPhase(classId: ClassId, session: FirSession): Boolean { + val requiredAnnotations = session.annotationPlatformSupport.requiredAnnotations + return fir.resolvePhase < FirResolvePhase.TYPES && classId in requiredAnnotations +} \ No newline at end of file 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 99e263585af..ca70da1af6c 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 @@ -7,6 +7,7 @@ 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.getJvmNameFromAnnotation import org.jetbrains.kotlin.analysis.api.fir.symbols.* import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol @@ -23,6 +24,7 @@ import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.load.java.JvmAbi +import org.jetbrains.kotlin.name.JvmNames import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo @@ -61,6 +63,7 @@ internal class KtFirSymbolInfoProvider( // 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.) + val deprecationAnnotationSimpleNames = analysisSession.useSiteSession.annotationPlatformSupport.deprecationAnnotationsSimpleNames return annotationSimpleNames.any { it != null && it in deprecationAnnotationSimpleNames } } @@ -127,7 +130,7 @@ internal class KtFirSymbolInfoProvider( } private fun getJvmName(property: FirProperty, isSetter: Boolean): Name { - if (property.backingField?.symbol?.hasAnnotation(StandardClassIds.Annotations.JvmField, analysisSession.useSiteSession) == true) { + if (property.backingField?.symbol?.hasAnnotation(JvmNames.Annotations.JvmField, analysisSession.useSiteSession) == true) { return property.name } return Name.identifier(getJvmNameAsString(property, isSetter)) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyBodiesCalculator.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyBodiesCalculator.kt index c0b540e1926..a86dee341ff 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyBodiesCalculator.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyBodiesCalculator.kt @@ -19,12 +19,11 @@ import org.jetbrains.kotlin.fir.declarations.utils.getExplicitBackingField import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.FirLazyDelegatedConstructorCall import org.jetbrains.kotlin.fir.extensions.registeredPluginAnnotations -import org.jetbrains.kotlin.fir.resolve.transformers.plugin.CompilerRequiredAnnotationsHelper +import org.jetbrains.kotlin.fir.declarations.annotationPlatformSupport import org.jetbrains.kotlin.fir.scopes.kotlinScopeProvider import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.transformSingle -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* internal object FirLazyBodiesCalculator { @@ -319,15 +318,12 @@ private abstract class FirLazyAnnotationTransformer : FirTransformer = CompilerRequiredAnnotationsHelper.REQUIRED_ANNOTATIONS - .mapTo(mutableSetOf()) { it.shortClassName } - private fun canBeCompilerAnnotation(annotationCall: FirAnnotationCall, session: FirSession): Boolean { val annotationTypeRef = annotationCall.annotationTypeRef if (annotationTypeRef !is FirUserTypeRef) return false if (session.registeredPluginAnnotations.annotations.isNotEmpty()) return true val name = annotationTypeRef.qualifier.last().name - return name in COMPILER_ANNOTATION_NAMES + return name in session.annotationPlatformSupport.requiredAnnotationsShortClassNames } override fun transformResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef, data: FirLazyAnnotationTransformerData): FirTypeRef { diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirCompilerAnnotationsLazyResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirCompilerAnnotationsLazyResolver.kt index da1d8df6ca0..1503757ac4d 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirCompilerAnnotationsLazyResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirCompilerAnnotationsLazyResolver.kt @@ -33,6 +33,7 @@ import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase import org.jetbrains.kotlin.fir.types.FirUserTypeRef import org.jetbrains.kotlin.analysis.low.level.api.fir.util.forEachDependentDeclaration import org.jetbrains.kotlin.analysis.low.level.api.fir.util.isScriptDependentDeclaration +import org.jetbrains.kotlin.fir.declarations.annotationPlatformSupport internal object LLFirCompilerAnnotationsLazyResolver : LLFirLazyResolver(FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS) { override fun resolve( @@ -197,8 +198,9 @@ private class LLFirCompilerRequiredAnnotationsTargetResolver( fun balanceAnnotations(target: FirElementWithResolveState) { if (target !is FirProperty) return val backingField = target.backingField ?: return - val updatedAnnotations = transformer.annotationTransformer.extractBackingFieldAnnotationsFromProperty( + val updatedAnnotations = transformer.session.annotationPlatformSupport.extractBackingFieldAnnotationsFromProperty( target, + transformer.session, annotationMap[target].orEmpty(), annotationMap[backingField].orEmpty(), ) ?: return diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/AbstractClassAdditionalAnnotationsProvider.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/AbstractClassAdditionalAnnotationsProvider.kt index 324b4c876bf..9130257446a 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/AbstractClassAdditionalAnnotationsProvider.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/AbstractClassAdditionalAnnotationsProvider.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.builtins.StandardNames 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.JvmNames import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds import java.lang.annotation.ElementType @@ -143,7 +144,7 @@ private fun javaRetentionArguments(kotlinRetentionName: String?): List = listOf( - StandardClassIds.Annotations.JvmRecord, + JvmNames.Annotations.JvmRecord, ).associateBy { it.asFqNameString() } /** 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 42471c8dc3a..82e923018fe 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 @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.JvmNames 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.StandardClassIds @@ -52,7 +53,7 @@ internal fun KtAnnotatedSymbol.hasJvmSyntheticAnnotation( internal fun KtAnnotatedSymbol.getJvmNameFromAnnotation( useSiteTargetFilter: AnnotationUseSiteTargetFilter = AnyAnnotationUseSiteTargetFilter, ): String? { - val annotation = findAnnotation(StandardClassIds.Annotations.JvmName, useSiteTargetFilter) + val annotation = findAnnotation(JvmNames.Annotations.JvmName, useSiteTargetFilter) return annotation?.let { (it.arguments.firstOrNull()?.expression as? KtConstantAnnotationValue)?.constantValue?.value as? String } @@ -70,7 +71,7 @@ internal fun KtAnnotatedSymbol.isHiddenOrSynthetic( useSiteTargetFilter: AnnotationUseSiteTargetFilter = annotationUseSiteTarget.toFilter(), ) = isHiddenByDeprecation(this, annotationUseSiteTarget) || hasJvmSyntheticAnnotation(useSiteTargetFilter) -internal fun KtAnnotatedSymbol.hasJvmFieldAnnotation(): Boolean = hasAnnotation(StandardClassIds.Annotations.JvmField) +internal fun KtAnnotatedSymbol.hasJvmFieldAnnotation(): Boolean = hasAnnotation(JvmNames.Annotations.JvmField) internal fun KtAnnotatedSymbol.hasPublishedApiAnnotation( useSiteTargetFilter: AnnotationUseSiteTargetFilter = AnyAnnotationUseSiteTargetFilter, @@ -84,7 +85,7 @@ internal fun KtAnnotatedSymbol.hasJvmOverloadsAnnotation(): Boolean = hasAnnotat internal fun KtAnnotatedSymbol.hasJvmStaticAnnotation( useSiteTargetFilter: AnnotationUseSiteTargetFilter = AnyAnnotationUseSiteTargetFilter, -): Boolean = hasAnnotation(StandardClassIds.Annotations.JvmStatic, useSiteTargetFilter) +): Boolean = hasAnnotation(JvmNames.Annotations.JvmStatic, useSiteTargetFilter) internal fun KtAnnotatedSymbol.hasInlineOnlyAnnotation(): Boolean = hasAnnotation(StandardClassIds.Annotations.InlineOnly) @@ -109,7 +110,7 @@ internal fun KtAnnotatedSymbol.computeThrowsList( builder.addReference(java.lang.NullPointerException::class.qualifiedName) } - val annoApp = findAnnotation(StandardClassIds.Annotations.Throws, useSiteTargetFilter) ?: return + val annoApp = findAnnotation(JvmNames.Annotations.Throws, useSiteTargetFilter) ?: return fun handleAnnotationValue(annotationValue: KtAnnotationValue) = when (annotationValue) { is KtArrayAnnotationValue -> { diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt index e094419e2c1..fdd3a125bf7 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt @@ -49,6 +49,7 @@ import org.jetbrains.kotlin.light.classes.symbol.isJvmField import org.jetbrains.kotlin.light.classes.symbol.mapType import org.jetbrains.kotlin.light.classes.symbol.methods.* import org.jetbrains.kotlin.load.java.JvmAbi +import org.jetbrains.kotlin.name.JvmNames import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClass @@ -565,7 +566,7 @@ internal fun KtSymbolWithMembers.createInnerClasses( if (containingClass is SymbolLightClassForAnnotationClass && this is KtNamedClassOrObjectSymbol && hasAnnotation(StandardClassIds.Annotations.Repeatable) && - !hasAnnotation(StandardClassIds.Annotations.Java.Repeatable) + !hasAnnotation(JvmNames.Annotations.Java.Repeatable) ) { result.add(SymbolLightClassForRepeatableAnnotationContainer(containingClass)) } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java index 63e600177f0..8c3e31760c2 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.config.JVMConfigurationKeys; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.*; +import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor; import org.jetbrains.kotlin.incremental.components.NoLookupLocation; import org.jetbrains.kotlin.load.java.JvmAnnotationNames; diff --git a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsRuntimeAnnotationChecker.kt b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsRuntimeAnnotationChecker.kt index 7bfd539a26a..966126dc8ac 100644 --- a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsRuntimeAnnotationChecker.kt +++ b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsRuntimeAnnotationChecker.kt @@ -9,10 +9,10 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker -import org.jetbrains.kotlin.fir.analysis.checkers.getExplicitAnnotationRetention import org.jetbrains.kotlin.fir.analysis.js.checkers.isEffectivelyExternal import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.getExplicitAnnotationRetention object FirJsRuntimeAnnotationChecker : FirBasicDeclarationChecker() { override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJvmAnnotationHelper.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJvmAnnotationHelper.kt index c27f309a036..cb88cf50661 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJvmAnnotationHelper.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJvmAnnotationHelper.kt @@ -15,13 +15,13 @@ import org.jetbrains.kotlin.fir.isNewPlaceForBodyGeneration import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol -import org.jetbrains.kotlin.name.StandardClassIds +import org.jetbrains.kotlin.name.JvmNames fun FirBasedSymbol.isCompiledToJvmDefault( session: FirSession, jvmDefaultMode: JvmDefaultMode, ): Boolean where D : FirAnnotationContainer, D : FirDeclaration { - if (getAnnotationByClassId(StandardClassIds.Annotations.JvmDefault, session) != null) return true + if (getAnnotationByClassId(JvmNames.Annotations.JvmDefault, session) != null) return true val container = getContainingClassSymbol(session) if (container !is FirRegularClassSymbol || container.origin.fromSource) return jvmDefaultMode.forAllMethodsWithBody diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJvmAnnotationsPlatformSpecificSupportComponent.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJvmAnnotationsPlatformSpecificSupportComponent.kt new file mode 100644 index 00000000000..8d80b5fa835 --- /dev/null +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJvmAnnotationsPlatformSpecificSupportComponent.kt @@ -0,0 +1,76 @@ +/* + * 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.fir.analysis.jvm.checkers + +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.getAnnotationRetention +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.AnnotationsPosition +import org.jetbrains.kotlin.fir.languageVersionSettings +import org.jetbrains.kotlin.fir.declarations.FirAnnotationsPlatformSpecificSupportComponent +import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.JvmNames +import org.jetbrains.kotlin.name.StandardClassIds + +object FirJvmAnnotationsPlatformSpecificSupportComponent : FirAnnotationsPlatformSpecificSupportComponent() { + override val requiredAnnotationsWithArguments: Set = setOf( + StandardClassIds.Annotations.Deprecated, + StandardClassIds.Annotations.Target, + JvmNames.Annotations.Java.Target, + ) + + override val requiredAnnotations: Set = requiredAnnotationsWithArguments + setOf( + JvmNames.Annotations.Java.Deprecated, + StandardClassIds.Annotations.DeprecatedSinceKotlin, + StandardClassIds.Annotations.SinceKotlin, + StandardClassIds.Annotations.WasExperimental, + JvmNames.Annotations.JvmRecord, + ) + + override val volatileAnnotations: Set = setOf( + StandardClassIds.Annotations.Volatile, + JvmNames.Annotations.JvmVolatile, + ) + + override val deprecationAnnotationsWithOverridesPropagation: Map = mapOf( + StandardClassIds.Annotations.Deprecated to true, + JvmNames.Annotations.Java.Deprecated to false, + StandardClassIds.Annotations.SinceKotlin to true, + ) + + override fun symbolContainsRepeatableAnnotation(symbol: FirClassLikeSymbol<*>, session: FirSession): Boolean { + if (symbol.getAnnotationByClassId(StandardClassIds.Annotations.Repeatable, session) != null) return true + if (symbol.getAnnotationByClassId(JvmNames.Annotations.Java.Repeatable, session) != null || + symbol.getAnnotationByClassId(JvmNames.Annotations.JvmRepeatable, session) != null + ) { + return session.languageVersionSettings.supportsFeature(LanguageFeature.RepeatableAnnotations) || + symbol.getAnnotationRetention(session) == AnnotationRetention.SOURCE && symbol.origin is FirDeclarationOrigin.Java + } + return false + } + + override fun extractBackingFieldAnnotationsFromProperty( + property: FirProperty, + session: FirSession, + propertyAnnotations: List, + backingFieldAnnotations: List, + ): AnnotationsPosition? { + if (propertyAnnotations.isEmpty() || property.backingField == null) return null + + val (newBackingFieldAnnotations, newPropertyAnnotations) = propertyAnnotations.partition { + it.toAnnotationClassIdSafe(session) == JvmNames.Annotations.Java.Deprecated + } + + if (newBackingFieldAnnotations.isEmpty()) return null + return AnnotationsPosition( + propertyAnnotations = newPropertyAnnotations, + backingFieldAnnotations = backingFieldAnnotations + newBackingFieldAnnotations, + ) + } +} diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJvmPrimaryConstructorSuperTypeCheckerPlatformComponent.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJvmPrimaryConstructorSuperTypeCheckerPlatformComponent.kt new file mode 100644 index 00000000000..e6bd337f21e --- /dev/null +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJvmPrimaryConstructorSuperTypeCheckerPlatformComponent.kt @@ -0,0 +1,16 @@ +/* + * 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.fir.analysis.jvm.checkers + +import org.jetbrains.kotlin.fir.analysis.checkers.FirPrimaryConstructorSuperTypeCheckerPlatformComponent +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.JvmNames +import org.jetbrains.kotlin.name.StandardClassIds + +object FirJvmPrimaryConstructorSuperTypeCheckerPlatformComponent : FirPrimaryConstructorSuperTypeCheckerPlatformComponent() { + override val supertypesThatDontNeedInitializationInSubtypesConstructors: Set = + setOf(StandardClassIds.Enum, JvmNames.Java.Record) +} diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmNameChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmNameChecker.kt index 58a04a1a3d7..c9f91123b80 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmNameChecker.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmNameChecker.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.resolve.getContainingClass import org.jetbrains.kotlin.fir.types.classId import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.resolvedType +import org.jetbrains.kotlin.name.JvmNames import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds @@ -58,7 +59,7 @@ object FirJvmNameChecker : FirBasicDeclarationChecker() { private fun FirDeclaration.findJvmNameAnnotation(): FirAnnotation? { return annotations.firstOrNull { - it.annotationTypeRef.coneType.classId == StandardClassIds.Annotations.JvmName + it.annotationTypeRef.coneType.classId == JvmNames.Annotations.JvmName } } diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmRecordChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmRecordChecker.kt index 7890d7d204b..6e1306c7c5b 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmRecordChecker.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmRecordChecker.kt @@ -24,14 +24,14 @@ import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.classId import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneTypeSafe +import org.jetbrains.kotlin.name.JvmNames import org.jetbrains.kotlin.name.JvmNames.JVM_RECORD_ANNOTATION_CLASS_ID -import org.jetbrains.kotlin.name.StandardClassIds object FirJvmRecordChecker : FirRegularClassChecker() { override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) { declaration.superTypeRefs.firstOrNull()?.let { typeRef -> // compiler automatically adds java.lang.Record supertype, so we should check only for explicit type declarations - if (typeRef.source != null && typeRef.coneTypeSafe()?.fullyExpandedClassId(context.session) == StandardClassIds.Java.Record) { + if (typeRef.source != null && typeRef.coneTypeSafe()?.fullyExpandedClassId(context.session) == JvmNames.Java.Record) { reporter.reportOn(typeRef.source, FirJvmErrors.ILLEGAL_JAVA_LANG_RECORD_SUPERTYPE, context) return } diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmRedundantRepeatableChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmRedundantRepeatableChecker.kt index f2bf7f9b841..4c12353d124 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmRedundantRepeatableChecker.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmRedundantRepeatableChecker.kt @@ -13,15 +13,15 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.unexpandedClassId import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.JvmNames import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Repeatable -import org.jetbrains.kotlin.name.StandardClassIds.Annotations.JvmRepeatable -import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Java +import org.jetbrains.kotlin.name.JvmNames.Annotations.JvmRepeatable object FirJvmRedundantRepeatableChecker : FirBasicDeclarationChecker() { override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { val kotlinRepeatable = declaration.getAnnotationByClassId(Repeatable, context.session) val javaRepeatable = declaration.getAnnotationByClassId(JvmRepeatable, context.session) - ?: declaration.getAnnotationByClassId(Java.Repeatable, context.session) + ?: declaration.getAnnotationByClassId(JvmNames.Annotations.Java.Repeatable, context.session) if (kotlinRepeatable != null && javaRepeatable != null) { reporter.reportOn( diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmStaticChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmStaticChecker.kt index 873ae06d038..66aa5f666bc 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmStaticChecker.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmStaticChecker.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.JvmNames import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.StandardClassIds @@ -42,14 +43,14 @@ object FirJvmStaticChecker : FirBasicDeclarationChecker() { return } - val declarationAnnotation = declaration.findAnnotation(StandardClassIds.Annotations.JvmStatic, context.session) + val declarationAnnotation = declaration.findAnnotation(JvmNames.Annotations.JvmStatic, context.session) if (declarationAnnotation != null) { checkAnnotated(declaration, context, reporter, declaration.source) } fun checkIfAnnotated(it: FirDeclaration) { - if (!it.hasAnnotation(StandardClassIds.Annotations.JvmStatic, context.session)) { + if (!it.hasAnnotation(JvmNames.Annotations.JvmStatic, context.session)) { return } val targetSource = it.source ?: declaration.source @@ -201,7 +202,7 @@ object FirJvmStaticChecker : FirBasicDeclarationChecker() { targetSource: KtSourceElement?, ) { if (declaration !is FirProperty) return - if (declaration.isConst || declaration.backingField?.hasAnnotationNamedAs(StandardClassIds.Annotations.JvmField, context.session) == true) { + if (declaration.isConst || declaration.backingField?.hasAnnotationNamedAs(JvmNames.Annotations.JvmField, context.session) == true) { reporter.reportOn(targetSource, FirJvmErrors.JVM_STATIC_ON_CONST_OR_JVM_FIELD, context) } } diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirRepeatableAnnotationChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirRepeatableAnnotationChecker.kt index 7de0df3fca3..e8eacf2ab44 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirRepeatableAnnotationChecker.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirRepeatableAnnotationChecker.kt @@ -12,14 +12,13 @@ import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.analysis.checkers.containsRepeatableAnnotation +import org.jetbrains.kotlin.fir.analysis.checkers.* import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker -import org.jetbrains.kotlin.fir.analysis.checkers.getAllowedAnnotationTargets -import org.jetbrains.kotlin.fir.analysis.checkers.getAnnotationRetention -import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.annotationPlatformSupport +import org.jetbrains.kotlin.fir.declarations.getAnnotationRetention import org.jetbrains.kotlin.fir.declarations.utils.classId import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.languageVersionSettings @@ -33,6 +32,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.JvmNames import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds @@ -58,7 +58,7 @@ object FirRepeatableAnnotationChecker : FirBasicDeclarationChecker() { existingTargetsForAnnotation.any { (it == null) != (useSiteTarget == null) } if (duplicateAnnotation && - annotationClass.containsRepeatableAnnotation(session) && + session.annotationPlatformSupport.symbolContainsRepeatableAnnotation(annotationClass, session) && annotationClass.getAnnotationRetention(session) != AnnotationRetention.SOURCE ) { if (session.languageVersionSettings.supportsFeature(LanguageFeature.RepeatableAnnotations)) { @@ -83,7 +83,7 @@ object FirRepeatableAnnotationChecker : FirBasicDeclarationChecker() { } if (declaration is FirRegularClass) { - val javaRepeatable = annotations.getAnnotationByClassId(StandardClassIds.Annotations.Java.Repeatable, session) + val javaRepeatable = annotations.getAnnotationByClassId(JvmNames.Annotations.Java.Repeatable, session) if (javaRepeatable != null) { checkJavaRepeatableAnnotationDeclaration(javaRepeatable, declaration, context, reporter) } else { @@ -97,7 +97,7 @@ object FirRepeatableAnnotationChecker : FirBasicDeclarationChecker() { private fun FirClassLikeSymbol<*>.resolveContainerAnnotation(session: FirSession): ClassId? { val repeatableAnnotation = getAnnotationByClassId(StandardClassIds.Annotations.Repeatable, session) - ?: getAnnotationByClassId(StandardClassIds.Annotations.Java.Repeatable, session) + ?: getAnnotationByClassId(JvmNames.Annotations.Java.Repeatable, session) ?: return null return repeatableAnnotation.resolveContainerAnnotation() } diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJavaAnnotationsChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJavaAnnotationsChecker.kt index 6c9e7e54a87..b9ebeed0a78 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJavaAnnotationsChecker.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJavaAnnotationsChecker.kt @@ -26,16 +26,17 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.coneTypeSafe import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.JvmNames import org.jetbrains.kotlin.name.StandardClassIds.Annotations object FirJavaAnnotationsChecker : FirAnnotationChecker() { private val javaToKotlinNameMap: Map = mapOf( - Annotations.Java.Target to Annotations.Target, - Annotations.Java.Retention to Annotations.Retention, - Annotations.Java.Deprecated to Annotations.Deprecated, - Annotations.Java.Documented to Annotations.MustBeDocumented, + JvmNames.Annotations.Java.Target to Annotations.Target, + JvmNames.Annotations.Java.Retention to Annotations.Retention, + JvmNames.Annotations.Java.Deprecated to Annotations.Deprecated, + JvmNames.Annotations.Java.Documented to Annotations.MustBeDocumented, ) override fun check(expression: FirAnnotation, context: CheckerContext, reporter: DiagnosticReporter) { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirAnnotationHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirAnnotationHelpers.kt index e4a9eafbcb3..50cf2e9abcb 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirAnnotationHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirAnnotationHelpers.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.fir.analysis.checkers -import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget import org.jetbrains.kotlin.diagnostics.DiagnosticReporter @@ -15,11 +14,10 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors -import org.jetbrains.kotlin.fir.analysis.getRetention import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.annotationPlatformSupport import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor import org.jetbrains.kotlin.fir.expressions.* -import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.references.FirFromMissingDependenciesNamedReference import org.jetbrains.kotlin.fir.references.resolved import org.jetbrains.kotlin.fir.resolve.fullyExpandedType @@ -121,26 +119,7 @@ fun FirAnnotation.isRepeatable(session: FirSession): Boolean { if (annotationClassId.isLocal) return false val annotationClass = session.symbolProvider.getClassLikeSymbolByClassId(annotationClassId) ?: return false - return annotationClass.containsRepeatableAnnotation(session) -} - -fun FirClassLikeSymbol<*>.containsRepeatableAnnotation(session: FirSession): Boolean { - if (getAnnotationByClassId(StandardClassIds.Annotations.Repeatable, session) != null) return true - if (getAnnotationByClassId(StandardClassIds.Annotations.Java.Repeatable, session) != null || - getAnnotationByClassId(StandardClassIds.Annotations.JvmRepeatable, session) != null - ) { - return session.languageVersionSettings.supportsFeature(LanguageFeature.RepeatableAnnotations) || - getAnnotationRetention(session) == AnnotationRetention.SOURCE && origin is FirDeclarationOrigin.Java - } - return false -} - -fun FirClassLikeSymbol<*>.getExplicitAnnotationRetention(session: FirSession): AnnotationRetention? { - return getAnnotationByClassId(StandardClassIds.Annotations.Retention, session)?.getRetention() -} - -fun FirClassLikeSymbol<*>.getAnnotationRetention(session: FirSession): AnnotationRetention { - return getExplicitAnnotationRetention(session) ?: AnnotationRetention.RUNTIME + return session.annotationPlatformSupport.symbolContainsRepeatableAnnotation(annotationClass, session) } fun FirAnnotationContainer.getDefaultUseSiteTarget( diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirPrimaryConstructorSuperTypeCheckerPlatformComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirPrimaryConstructorSuperTypeCheckerPlatformComponent.kt new file mode 100644 index 00000000000..16885497355 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirPrimaryConstructorSuperTypeCheckerPlatformComponent.kt @@ -0,0 +1,21 @@ +/* + * 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.fir.analysis.checkers + +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.FirSessionComponent +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.StandardClassIds + +abstract class FirPrimaryConstructorSuperTypeCheckerPlatformComponent : FirSessionComponent { + abstract val supertypesThatDontNeedInitializationInSubtypesConstructors: Set + + object Default : FirPrimaryConstructorSuperTypeCheckerPlatformComponent() { + override val supertypesThatDontNeedInitializationInSubtypesConstructors: Set = setOf(StandardClassIds.Enum) + } +} + +val FirSession.primaryConstructorSuperTypePlatformSupport by FirSession.sessionComponentAccessor() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationClassDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationClassDeclarationChecker.kt index 4ef5e6dad0f..1213e0330e8 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationClassDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationClassDeclarationChecker.kt @@ -18,8 +18,8 @@ import org.jetbrains.kotlin.fir.analysis.checkers.* import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.* import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLE_IN_ANNOTATION_PARAMETER -import org.jetbrains.kotlin.fir.analysis.getRetention -import org.jetbrains.kotlin.fir.analysis.getRetentionAnnotation +import org.jetbrains.kotlin.fir.declarations.getRetention +import org.jetbrains.kotlin.fir.declarations.getRetentionAnnotation import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isLocal import org.jetbrains.kotlin.fir.declarations.utils.isSynthetic diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOptInAnnotationClassChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOptInAnnotationClassChecker.kt index c69d281d660..18bb2627780 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOptInAnnotationClassChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOptInAnnotationClassChecker.kt @@ -12,8 +12,8 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.diagnostics.reportOn -import org.jetbrains.kotlin.fir.analysis.getRetention -import org.jetbrains.kotlin.fir.analysis.getRetentionAnnotation +import org.jetbrains.kotlin.fir.declarations.getRetention +import org.jetbrains.kotlin.fir.declarations.getRetentionAnnotation import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId import org.jetbrains.kotlin.resolve.checkers.OptInDescription diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPrimaryConstructorSuperTypeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPrimaryConstructorSuperTypeChecker.kt index 32165f37129..c05d1840d82 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPrimaryConstructorSuperTypeChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPrimaryConstructorSuperTypeChecker.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.checkers.SourceNavigator import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.primaryConstructorSuperTypePlatformSupport import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass @@ -22,7 +23,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.impl.FirImplicitAnyTypeRef import org.jetbrains.kotlin.fir.types.toRegularClassSymbol -import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull /** Checker on super type declarations in the primary constructor of a class declaration. */ @@ -80,7 +80,9 @@ object FirPrimaryConstructorSuperTypeChecker : FirClassChecker() { } val delegatedCallSource = delegatedConstructorCall.source ?: return if (delegatedCallSource.kind !is KtFakeSourceElementKind) return - if (superClassSymbol.classId == StandardClassIds.Enum || superClassSymbol.classId == StandardClassIds.Java.Record) return + val supertypesToSkip = context.session.primaryConstructorSuperTypePlatformSupport + .supertypesThatDontNeedInitializationInSubtypesConstructors + if (superClassSymbol.classId in supertypesToSkip) return if (delegatedCallSource.elementType != KtNodeTypes.SUPER_TYPE_CALL_ENTRY) { reporter.reportOn(constructedTypeRef.source, FirErrors.SUPERTYPE_NOT_INITIALIZED, context) } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirVolatileAnnotationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirVolatileAnnotationChecker.kt index 50bcad90b55..56c0a467530 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirVolatileAnnotationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirVolatileAnnotationChecker.kt @@ -7,24 +7,19 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.KtRealSourceElementKind import org.jetbrains.kotlin.diagnostics.DiagnosticReporter -import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory0 import org.jetbrains.kotlin.diagnostics.reportOn -import org.jetbrains.kotlin.fir.FirAnnotationContainer import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.declarations.annotationPlatformSupport import org.jetbrains.kotlin.fir.declarations.FirProperty -import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassIds -import org.jetbrains.kotlin.fir.symbols.SymbolInternals -import org.jetbrains.kotlin.name.StandardClassIds object FirVolatileAnnotationChecker : FirPropertyChecker() { - private val VOLATILE_CLASS_IDS = listOf(StandardClassIds.Annotations.Volatile, StandardClassIds.Annotations.JvmVolatile) - override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) { if (declaration.source?.kind != KtRealSourceElementKind) return - val fieldAnnotation = declaration.backingField?.annotations?.getAnnotationByClassIds(VOLATILE_CLASS_IDS, context.session) + val volatileAnnotations = context.session.annotationPlatformSupport.volatileAnnotations + val fieldAnnotation = declaration.backingField?.annotations?.getAnnotationByClassIds(volatileAnnotations, context.session) ?: return if (!declaration.isVar) { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirInlinedLambdaNonSourceAnnotationsChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirInlinedLambdaNonSourceAnnotationsChecker.kt index 4fbb92b197c..f4404e4e10c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirInlinedLambdaNonSourceAnnotationsChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirInlinedLambdaNonSourceAnnotationsChecker.kt @@ -9,10 +9,10 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirAnonymousFunctionChecker -import org.jetbrains.kotlin.fir.analysis.checkers.getAnnotationRetention import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction import org.jetbrains.kotlin.fir.declarations.InlineStatus +import org.jetbrains.kotlin.fir.declarations.getAnnotationRetention import org.jetbrains.kotlin.fir.declarations.toAnnotationClassLikeSymbol object FirInlinedLambdaNonSourceAnnotationsChecker : FirAnonymousFunctionChecker() { diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt index 80fc2e1a3a6..4f79f25da0a 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt @@ -12,15 +12,19 @@ import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.analysis.CheckersComponent import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper import org.jetbrains.kotlin.fir.analysis.checkers.FirInlineCheckerPlatformSpecificComponent +import org.jetbrains.kotlin.fir.analysis.checkers.FirPrimaryConstructorSuperTypeCheckerPlatformComponent import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirNameConflictsTracker import org.jetbrains.kotlin.fir.analysis.jvm.FirJvmOverridesBackwardCompatibilityHelper +import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJvmAnnotationsPlatformSpecificSupportComponent import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJvmInlineCheckerComponent +import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJvmPrimaryConstructorSuperTypeCheckerPlatformComponent import org.jetbrains.kotlin.fir.caches.FirCachesFactory import org.jetbrains.kotlin.fir.caches.FirThreadUnsafeCachesFactory import org.jetbrains.kotlin.fir.declarations.FirDeclarationOverloadabilityHelper import org.jetbrains.kotlin.fir.declarations.FirTypeSpecificityComparatorProvider import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProviderImpl +import org.jetbrains.kotlin.fir.declarations.FirAnnotationsPlatformSpecificSupportComponent import org.jetbrains.kotlin.fir.deserialization.FirDeserializationExtension import org.jetbrains.kotlin.fir.extensions.* import org.jetbrains.kotlin.fir.java.FirJavaVisibilityChecker @@ -83,6 +87,8 @@ fun FirSession.registerCommonComponents(languageVersionSettings: LanguageVersion register(FirEnumEntriesSupport::class, FirEnumEntriesSupport(this)) register(FirOverrideChecker::class, FirStandardOverrideChecker(this)) register(FirDeclarationOverloadabilityHelper::class, FirDeclarationOverloadabilityHelperImpl(this)) + register(FirAnnotationsPlatformSpecificSupportComponent::class, FirAnnotationsPlatformSpecificSupportComponent.Default) + register(FirPrimaryConstructorSuperTypeCheckerPlatformComponent::class, FirPrimaryConstructorSuperTypeCheckerPlatformComponent.Default) } @OptIn(SessionConfiguration::class) @@ -134,6 +140,8 @@ fun FirSession.registerCommonJavaComponents( register(FirDeserializationExtension::class, FirJvmDeserializationExtension(this)) register(FirEnumEntriesSupport::class, FirJvmEnumEntriesSupport(this)) register(CompilerRequiredAnnotationEnhancementProvider::class, JavaCompilerRequiredAnnotationEnhancementProvider) + register(FirAnnotationsPlatformSpecificSupportComponent::class, FirJvmAnnotationsPlatformSpecificSupportComponent) + register(FirPrimaryConstructorSuperTypeCheckerPlatformComponent::class, FirJvmPrimaryConstructorSuperTypeCheckerPlatformComponent) } // -------------------------- Resolve components -------------------------- diff --git a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt index 3ca7184bfd7..bdc684bf15c 100644 --- a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt +++ b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.backend.FirMetadataSource import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.fir.java.hasJvmFieldAnnotation import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.ScopeSession diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index 75b39e6c837..ee57dbaadfd 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -41,14 +41,14 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.load.kotlin.FacadeClassSource -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.* import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerAbiStability import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.utils.threadLocal import java.util.concurrent.ConcurrentHashMap +import org.jetbrains.kotlin.fir.java.hasJvmFieldAnnotation @OptIn(LeakedDeclarationCaches::class) class Fir2IrDeclarationStorage( diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt index fb4a40cf12c..671535cc862 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.expressions.FirConstExpression import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub +import org.jetbrains.kotlin.fir.java.hasJvmFieldAnnotation import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyProperty import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt index fd2c76b8962..22ae4961fd7 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt @@ -8,8 +8,11 @@ package org.jetbrains.kotlin.fir.java import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.FirProperty +import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind +import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirArrayLiteral import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.builder.buildArgumentList @@ -25,6 +28,7 @@ import org.jetbrains.kotlin.load.java.structure.JavaAnnotation import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.load.java.structure.JavaModifierListOwner import org.jetbrains.kotlin.load.java.structure.JavaWildcardType +import org.jetbrains.kotlin.name.JvmNames import org.jetbrains.kotlin.types.ConstantValueKind internal val JavaModifierListOwner.modality: Modality @@ -132,3 +136,9 @@ fun extractNullabilityAnnotationOnBoundedWildcard(wildcardType: JavaWildcardType require(wildcardType.bound != null) { "Nullability annotations on unbounded wildcards aren't supported" } return wildcardType.annotations.find { annotation -> RXJAVA3_ANNOTATIONS.any { annotation.classId?.asSingleFqName() == it } } } + +fun FirProperty.hasJvmFieldAnnotation(session: FirSession): Boolean = + backingField?.annotations?.any { it.isJvmFieldAnnotation(session) } == true + +fun FirAnnotation.isJvmFieldAnnotation(session: FirSession): Boolean = + toAnnotationClassId(session) == JvmNames.Annotations.JvmField diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JvmSupertypeUpdater.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JvmSupertypeUpdater.kt index c8a9e283777..528551f9dd0 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JvmSupertypeUpdater.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JvmSupertypeUpdater.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef import org.jetbrains.kotlin.fir.visitors.FirTransformer +import org.jetbrains.kotlin.name.JvmNames import org.jetbrains.kotlin.name.StandardClassIds class JvmSupertypeUpdater(private val session: FirSession) : PlatformSupertypeUpdater() { @@ -32,7 +33,7 @@ class JvmSupertypeUpdater(private val session: FirSession) : PlatformSupertypeUp override fun updateSupertypesIfNeeded(firClass: FirClass, scopeSession: ScopeSession) { if (firClass !is FirRegularClass || !firClass.isData || - !firClass.hasAnnotationSafe(StandardClassIds.Annotations.JvmRecord, session) + !firClass.hasAnnotationSafe(JvmNames.Annotations.JvmRecord, session) ) return var anyFound = false var hasExplicitSuperClass = false @@ -61,7 +62,7 @@ class JvmSupertypeUpdater(private val session: FirSession) : PlatformSupertypeUp private class DelegatedConstructorCallTransformer(private val session: FirSession) : FirTransformer() { companion object { - val recordType = StandardClassIds.Java.Record.constructClassLikeType(emptyArray(), isNullable = false) + val recordType = JvmNames.Java.Record.constructClassLikeType(emptyArray(), isNullable = false) } override fun transformElement(element: E, data: ScopeSession): E { @@ -103,7 +104,7 @@ class JvmSupertypeUpdater(private val session: FirSession) : PlatformSupertypeUp if (recordConstructorSymbol != null) { val newReference = buildResolvedNamedReference { - name = StandardClassIds.Java.Record.shortClassName + name = JvmNames.Java.Record.shortClassName resolvedSymbol = recordConstructorSymbol } delegatedConstructorCall.replaceCalleeReference(newReference) diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/JavaCompilerRequiredAnnotationEnhancementProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/JavaCompilerRequiredAnnotationEnhancementProvider.kt index 71fe61aa3f5..e925f572584 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/JavaCompilerRequiredAnnotationEnhancementProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/JavaCompilerRequiredAnnotationEnhancementProvider.kt @@ -10,12 +10,13 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.resolve.transformers.plugin.CompilerRequiredAnnotationEnhancementProvider import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol +import org.jetbrains.kotlin.name.JvmNames import org.jetbrains.kotlin.name.StandardClassIds object JavaCompilerRequiredAnnotationEnhancementProvider : CompilerRequiredAnnotationEnhancementProvider() { override fun enhance(enumSymbol: FirClassSymbol<*>, enumEntrySymbol: FirEnumEntrySymbol, session: FirSession): FirEnumEntrySymbol { val firRegularClass = enumSymbol.fir as? FirRegularClass ?: return enumEntrySymbol - if (enumSymbol.classId != StandardClassIds.Annotations.Java.ElementType) return enumEntrySymbol + if (enumSymbol.classId != JvmNames.Annotations.Java.ElementType) return enumEntrySymbol return FirSignatureEnhancement(firRegularClass, session) { emptyList() }.enhancedProperty( enumEntrySymbol, diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/javaAnnotationsMapping.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/javaAnnotationsMapping.kt index 8293c086990..c983dc6355f 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/javaAnnotationsMapping.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/javaAnnotationsMapping.kt @@ -38,10 +38,7 @@ import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.FirVisitor import org.jetbrains.kotlin.load.java.structure.* import org.jetbrains.kotlin.load.java.structure.impl.JavaElementImpl -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.name.SpecialNames -import org.jetbrains.kotlin.name.StandardClassIds +import org.jetbrains.kotlin.name.* import org.jetbrains.kotlin.toKtPsiSourceElement import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty @@ -68,7 +65,7 @@ internal fun JavaAnnotationOwner.convertAnnotationsToFir( internal object DeprecatedInJavaDocAnnotation : JavaAnnotation { override val arguments: Collection get() = emptyList() - override val classId: ClassId get() = StandardClassIds.Annotations.Java.Deprecated + override val classId: ClassId get() = JvmStandardClassIds.Annotations.Java.Deprecated override fun resolve(): JavaClass? = null } @@ -255,15 +252,15 @@ private fun fillAnnotationArgumentMapping( } internal fun JavaAnnotation.isJavaDeprecatedAnnotation(): Boolean { - return classId == StandardClassIds.Annotations.Java.Deprecated + return classId == JvmStandardClassIds.Annotations.Java.Deprecated } private fun JavaAnnotation.toFirAnnotationCall(session: FirSession): FirAnnotation = buildAnnotation { val lookupTag = when (classId) { - StandardClassIds.Annotations.Java.Target -> StandardClassIds.Annotations.Target - StandardClassIds.Annotations.Java.Retention -> StandardClassIds.Annotations.Retention - StandardClassIds.Annotations.Java.Documented -> StandardClassIds.Annotations.MustBeDocumented - StandardClassIds.Annotations.Java.Deprecated -> StandardClassIds.Annotations.Deprecated + JvmNames.Annotations.Java.Target -> StandardClassIds.Annotations.Target + JvmNames.Annotations.Java.Retention -> StandardClassIds.Annotations.Retention + JvmNames.Annotations.Java.Documented -> StandardClassIds.Annotations.MustBeDocumented + JvmNames.Annotations.Java.Deprecated -> StandardClassIds.Annotations.Deprecated else -> classId }?.toLookupTag() annotationTypeRef = if (lookupTag != null) { @@ -288,7 +285,7 @@ private fun JavaAnnotation.toFirAnnotationCall(session: FirSession): FirAnnotati override val mapping: Map by lazy { when { - classId == StandardClassIds.Annotations.Java.Target -> { + classId == JvmNames.Annotations.Java.Target -> { when (val argument = arguments.firstOrNull()) { is JavaArrayAnnotationArgument -> argument.getElements().mapJavaTargetArguments(session) is JavaEnumValueAnnotationArgument -> listOf(argument).mapJavaTargetArguments(session) @@ -298,13 +295,13 @@ private fun JavaAnnotation.toFirAnnotationCall(session: FirSession): FirAnnotati } } - classId == StandardClassIds.Annotations.Java.Retention -> { + classId == JvmNames.Annotations.Java.Retention -> { arguments.firstOrNull()?.mapJavaRetentionArgument(session)?.let { mapOf(StandardClassIds.Annotations.ParameterNames.retentionValue to it) } } - classId == StandardClassIds.Annotations.Java.Deprecated -> { + classId == JvmNames.Annotations.Java.Deprecated -> { mapOf( StandardClassIds.Annotations.ParameterNames.deprecatedMessage to "Deprecated in Java".createConstantOrError( session, diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationUtils.kt index 03e416ea255..6a7d3fa24c1 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationUtils.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.fir.declarations -import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.fir.FirAnnotationContainer import org.jetbrains.kotlin.fir.FirSession @@ -70,13 +69,6 @@ fun List.nonSourceAnnotations(session: FirSession): List = annotations.nonSourceAnnotations(session) -@Suppress("NOTHING_TO_INLINE") -inline fun FirProperty.hasJvmFieldAnnotation(session: FirSession): Boolean = - backingField?.annotations?.any { it.isJvmFieldAnnotation(session) } == true - -fun FirAnnotation.isJvmFieldAnnotation(session: FirSession): Boolean = - toAnnotationClassId(session) == StandardClassIds.Annotations.JvmField - fun FirAnnotation.useSiteTargetsFromMetaAnnotation(session: FirSession): Set { return toAnnotationClass(session) ?.annotations @@ -186,18 +178,6 @@ fun List.getAnnotationByClassIds(classIds: Collection, s } } -inline fun List.mapAnnotationsWithClassIdTo( - classId: ClassId, - destination: MutableCollection, - func: (FirAnnotation) -> T -) { - for (annotation in this) { - if (annotation.annotationTypeRef.coneTypeSafe()?.lookupTag?.classId == classId) { - destination.add(func(annotation)) - } - } -} - fun FirExpression.unwrapVarargValue(): List { return when (this) { is FirVarargArgumentsExpression -> arguments @@ -243,14 +223,6 @@ fun FirGetClassCall.getTargetType(): ConeKotlinType? { return resolvedType.typeArguments.getOrNull(0)?.type } -fun FirAnnotationContainer.getJvmNameFromAnnotation(session: FirSession, target: AnnotationUseSiteTarget? = null): String? { - val annotationCalls = getAnnotationsByClassId(StandardClassIds.Annotations.JvmName, session) - return annotationCalls.firstNotNullOfOrNull { call -> - call.getStringArgument(StandardNames.NAME) - ?.takeIf { target == null || call.useSiteTarget == target } - } -} - val FirAnnotation.resolved: Boolean get() { if (annotationTypeRef !is FirResolvedTypeRef) return false diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationsPlatformSpecificSupportComponent.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationsPlatformSpecificSupportComponent.kt new file mode 100644 index 00000000000..f1e7fe5e34a --- /dev/null +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationsPlatformSpecificSupportComponent.kt @@ -0,0 +1,93 @@ +/* + * 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.fir.declarations + +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.FirSessionComponent +import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.StandardClassIds + +/** + * @see org.jetbrains.kotlin.light.classes.symbol.annotations.GranularAnnotationsBox.Companion + */ +abstract class FirAnnotationsPlatformSpecificSupportComponent : FirSessionComponent { + abstract val requiredAnnotationsWithArguments: Set + abstract val requiredAnnotations: Set + abstract val volatileAnnotations: Set + + val requiredAnnotationsShortClassNames: Set by lazy { + requiredAnnotations.mapTo(mutableSetOf()) { it.shortClassName } + } + + /** + * Maps deprecation annotation ClassIds to the flag + * which is true iff the corresponding annotation must + * be propagated to overrides. + */ + abstract val deprecationAnnotationsWithOverridesPropagation: Map + + private val deprecationAnnotations: Set by lazy { + deprecationAnnotationsWithOverridesPropagation.keys + } + + val deprecationAnnotationsSimpleNames: Set by lazy { + deprecationAnnotations.mapTo(mutableSetOf()) { it.shortClassName.asString() } + } + + abstract fun symbolContainsRepeatableAnnotation(symbol: FirClassLikeSymbol<*>, session: FirSession): Boolean + + abstract fun extractBackingFieldAnnotationsFromProperty( + property: FirProperty, + session: FirSession, + propertyAnnotations: List = property.annotations, + backingFieldAnnotations: List = property.backingField?.annotations.orEmpty(), + ): AnnotationsPosition? + + object Default : FirAnnotationsPlatformSpecificSupportComponent() { + override val requiredAnnotationsWithArguments = setOf( + StandardClassIds.Annotations.Deprecated, + StandardClassIds.Annotations.Target, + ) + + override val requiredAnnotations = requiredAnnotationsWithArguments + setOf( + StandardClassIds.Annotations.DeprecatedSinceKotlin, + StandardClassIds.Annotations.SinceKotlin, + StandardClassIds.Annotations.WasExperimental, + ) + + override val volatileAnnotations = setOf( + StandardClassIds.Annotations.Volatile, + ) + + override val deprecationAnnotationsWithOverridesPropagation = mapOf( + StandardClassIds.Annotations.Deprecated to true, + StandardClassIds.Annotations.SinceKotlin to true, + ) + + override fun symbolContainsRepeatableAnnotation(symbol: FirClassLikeSymbol<*>, session: FirSession): Boolean { + return symbol.getAnnotationByClassId(StandardClassIds.Annotations.Repeatable, session) != null + } + + override fun extractBackingFieldAnnotationsFromProperty( + property: FirProperty, + session: FirSession, + propertyAnnotations: List, + backingFieldAnnotations: List, + ): AnnotationsPosition? { + return null + } + } +} + +val FirSession.annotationPlatformSupport by FirSession.sessionComponentAccessor() + +class AnnotationsPosition( + val backingFieldAnnotations: List, + val propertyAnnotations: List, +) diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/analysis/FirRetentionAnnotationHelpers.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirRetentionAnnotationHelpers.kt similarity index 78% rename from compiler/fir/semantics/src/org/jetbrains/kotlin/fir/analysis/FirRetentionAnnotationHelpers.kt rename to compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirRetentionAnnotationHelpers.kt index 10b5bdb5cfe..d4c34b8b6c8 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/analysis/FirRetentionAnnotationHelpers.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirRetentionAnnotationHelpers.kt @@ -3,15 +3,14 @@ * 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.fir.analysis +package org.jetbrains.kotlin.fir.declarations import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.references.toResolvedEnumEntrySymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol -import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.StandardClassIds fun FirRegularClass.getRetention(session: FirSession): AnnotationRetention { @@ -41,6 +40,10 @@ private fun FirRegularClassSymbol.getRetentionAnnotation(session: FirSession): F return getAnnotationByClassId(StandardClassIds.Annotations.Retention, session) } -private fun FirRegularClassSymbol.getAnnotationByClassId(classId: ClassId, session: FirSession): FirAnnotation? { - return resolvedAnnotationsWithArguments.firstOrNull { it.toAnnotationClassId(session) == classId } -} \ No newline at end of file +fun FirClassLikeSymbol<*>.getExplicitAnnotationRetention(session: FirSession): AnnotationRetention? { + return getAnnotationByClassId(StandardClassIds.Annotations.Retention, session)?.getRetention() +} + +fun FirClassLikeSymbol<*>.getAnnotationRetention(session: FirSession): AnnotationRetention { + return getExplicitAnnotationRetention(session) ?: AnnotationRetention.RUNTIME +} 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 5931a5c302a..a68ba68e75e 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 @@ -21,9 +21,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol -import org.jetbrains.kotlin.fir.types.ConeKotlinType -import org.jetbrains.kotlin.fir.types.forEachType -import org.jetbrains.kotlin.fir.types.toSymbol +import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds @@ -123,7 +121,7 @@ fun FirAnnotationContainer.extractDeprecationInfoPerUseSite( versionRequirements = this.versionRequirements } return buildDeprecationAnnotationInfoPerUseSiteStorage { - add((customAnnotations ?: annotations).extractDeprecationAnnotationInfoPerUseSite(fromJava, versionRequirements)) + add((customAnnotations ?: annotations).extractDeprecationAnnotationInfoPerUseSite(fromJava, session, versionRequirements)) if (this@extractDeprecationInfoPerUseSite is FirProperty) { add( getDeprecationsAnnotationInfoByUseSiteFromAccessors( @@ -179,7 +177,7 @@ fun List.getDeprecationsProviderFromAnnotations( fromJava: Boolean, versionRequirements: List? = null, ): DeprecationsProvider { - val deprecationAnnotationByUseSite = extractDeprecationAnnotationInfoPerUseSite(fromJava, versionRequirements) + val deprecationAnnotationByUseSite = extractDeprecationAnnotationInfoPerUseSite(fromJava, session, versionRequirements) return deprecationAnnotationByUseSite.toDeprecationsProvider(session.firCachesFactory) } @@ -252,29 +250,26 @@ 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( fromJava: Boolean, + session: FirSession, versionRequirements: List?, ): DeprecationAnnotationInfoPerUseSiteStorage { // NB: We can't expand typealiases (`toAnnotationClassId`), because it // requires `lookupTag.tySymbol()`, but we can have cycles in annotations. // See the commit message for an example. - @Suppress("RemoveExplicitTypeArguments") - val annotations = buildList> { - mapAnnotationsWithClassIdTo(StandardClassIds.Annotations.Deprecated, this) { it to false } - mapAnnotationsWithClassIdTo(StandardClassIds.Annotations.Java.Deprecated, this) { it to true } - mapAnnotationsWithClassIdTo(StandardClassIds.Annotations.SinceKotlin, this) { it to false } - } + val annotations = session.annotationPlatformSupport.deprecationAnnotationsWithOverridesPropagation + .flatMap { (classId, shouldPropagateToOverrides) -> + this.filter { + it.unexpandedClassId == classId + }.map { + it to shouldPropagateToOverrides + } + } return buildDeprecationAnnotationInfoPerUseSiteStorage { - for ((deprecated, fromJavaAnnotation) in annotations) { + for ((deprecated, shouldPropagateToOverrides) in annotations) { if (deprecated.unexpandedClassId == StandardClassIds.Annotations.SinceKotlin) { val sinceKotlinSingleArgument = deprecated.findArgumentByName(ParameterNames.sinceKotlinVersion) val apiVersion = ((sinceKotlinSingleArgument as? FirConstExpression<*>)?.value as? String) @@ -287,7 +282,7 @@ private fun List.extractDeprecationAnnotationInfoPerUseSite( } } else { val deprecationLevel = deprecated.getDeprecationLevel() ?: DeprecationLevelValue.WARNING - val propagatesToOverride = !fromJavaAnnotation && !fromJava + val propagatesToOverride = shouldPropagateToOverrides && !fromJava val deprecatedSinceKotlin = this@extractDeprecationAnnotationInfoPerUseSite.firstOrNull { it.unexpandedClassId == StandardClassIds.Annotations.DeprecatedSinceKotlin } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContextImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContextImpl.kt index 79dfdb2b905..dc8bcbaf179 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContextImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContextImpl.kt @@ -9,7 +9,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.* -import org.jetbrains.kotlin.fir.analysis.getRetention +import org.jetbrains.kotlin.fir.declarations.getRetention import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isActual import org.jetbrains.kotlin.fir.expressions.FirAnnotation diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt index ac5d69e9ca6..081f135948f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt @@ -9,6 +9,7 @@ import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.annotationPlatformSupport import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedQualifier import org.jetbrains.kotlin.fir.extensions.* @@ -21,8 +22,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.ScopeClassDeclaration import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformerDispatcher import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer -import org.jetbrains.kotlin.fir.resolve.transformers.plugin.CompilerRequiredAnnotationsHelper.REQUIRED_ANNOTATIONS -import org.jetbrains.kotlin.fir.resolve.transformers.plugin.CompilerRequiredAnnotationsHelper.REQUIRED_ANNOTATIONS_WITH_ARGUMENTS import org.jetbrains.kotlin.fir.resolve.transformers.withClassDeclarationCleanup import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.createImportingScopes @@ -40,38 +39,10 @@ import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.FirQualifierPartImpl import org.jetbrains.kotlin.fir.types.impl.FirTypeArgumentListImpl import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer -import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Deprecated -import org.jetbrains.kotlin.name.StandardClassIds.Annotations.DeprecatedSinceKotlin -import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Java -import org.jetbrains.kotlin.name.StandardClassIds.Annotations.JvmRecord -import org.jetbrains.kotlin.name.StandardClassIds.Annotations.SinceKotlin -import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Target -import org.jetbrains.kotlin.name.StandardClassIds.Annotations.WasExperimental import org.jetbrains.kotlin.util.PrivateForInline import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled -/** - * @see org.jetbrains.kotlin.light.classes.symbol.annotations.GranularAnnotationsBox.Companion - */ -object CompilerRequiredAnnotationsHelper { - internal val REQUIRED_ANNOTATIONS_WITH_ARGUMENTS: Set = setOf( - Deprecated, - Target, - Java.Target, - ) - - val REQUIRED_ANNOTATIONS: Set = REQUIRED_ANNOTATIONS_WITH_ARGUMENTS + setOf( - Java.Deprecated, - DeprecatedSinceKotlin, - SinceKotlin, - WasExperimental, - JvmRecord, - ) -} - @OptIn(PrivateForInline::class) abstract class AbstractFirSpecificAnnotationResolveTransformer( @property:PrivateForInline val session: FirSession, @@ -79,10 +50,6 @@ abstract class AbstractFirSpecificAnnotationResolveTransformer( @property:PrivateForInline val computationSession: CompilerRequiredAnnotationsComputationSession, containingDeclarations: List = emptyList() ) : FirDefaultTransformer() { - companion object { - private val REQUIRED_ANNOTATION_NAMES: Set = REQUIRED_ANNOTATIONS.mapTo(mutableSetOf()) { it.shortClassName } - } - inner class FirEnumAnnotationArgumentsTransformerDispatcher : FirAbstractBodyResolveTransformerDispatcher( session, FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS, @@ -244,7 +211,9 @@ abstract class AbstractFirSpecificAnnotationResolveTransformer( annotationCall.replaceAnnotationTypeRef(transformedAnnotationType) annotationCall.replaceAnnotationResolvePhase(FirAnnotationResolvePhase.CompilerRequiredAnnotations) - if (transformedAnnotationType.coneTypeSafe()?.lookupTag?.classId in REQUIRED_ANNOTATIONS_WITH_ARGUMENTS) { + val requiredAnnotationsWithArguments = session.annotationPlatformSupport.requiredAnnotationsWithArguments + + if (transformedAnnotationType.coneTypeSafe()?.lookupTag?.classId in requiredAnnotationsWithArguments) { argumentsTransformer.transformAnnotation(annotationCall, ResolutionMode.ContextDependent) } } @@ -261,13 +230,13 @@ abstract class AbstractFirSpecificAnnotationResolveTransformer( fun shouldRunAnnotationResolve(typeRef: FirUserTypeRef): Boolean { val name = typeRef.qualifier.last().name if (metaAnnotationsFromPlugins.isNotEmpty()) return true - return name in REQUIRED_ANNOTATION_NAMES || annotationsFromPlugins.any { it.shortName() == name } + return name in session.annotationPlatformSupport.requiredAnnotationsShortClassNames || annotationsFromPlugins.any { it.shortName() == name } } private fun FirResolvedTypeRef.requiredToSave(): Boolean { val classId = type.classId ?: return false return when { - classId in REQUIRED_ANNOTATIONS -> true + classId in session.annotationPlatformSupport.requiredAnnotations -> true classId.asSingleFqName() in annotationsFromPlugins -> true metaAnnotationsFromPlugins.isEmpty() -> false else -> type.markedWithMetaAnnotation(session, metaAnnotationsFromPlugins) @@ -424,31 +393,11 @@ abstract class AbstractFirSpecificAnnotationResolveTransformer( } private fun FirProperty.moveJavaDeprecatedAnnotationToBackingField() { - val newPosition = extractBackingFieldAnnotationsFromProperty(this) ?: return + val newPosition = session.annotationPlatformSupport.extractBackingFieldAnnotationsFromProperty(this, session) ?: return this.replaceAnnotations(newPosition.propertyAnnotations) backingField?.replaceAnnotations(newPosition.backingFieldAnnotations) } - fun extractBackingFieldAnnotationsFromProperty( - property: FirProperty, - propertyAnnotations: List = property.annotations, - backingFieldAnnotations: List = property.backingField?.annotations.orEmpty(), - ): AnnotationsPosition? { - if (propertyAnnotations.isEmpty() || property.backingField == null) return null - - val (newBackingFieldAnnotations, newPropertyAnnotations) = propertyAnnotations.partition { - it.toAnnotationClassIdSafe(session) == Java.Deprecated - } - - if (newBackingFieldAnnotations.isEmpty()) return null - return AnnotationsPosition( - propertyAnnotations = newPropertyAnnotations, - backingFieldAnnotations = backingFieldAnnotations + newBackingFieldAnnotations, - ) - } - - class AnnotationsPosition(val backingFieldAnnotations: List, val propertyAnnotations: List) - override fun transformSimpleFunction( simpleFunction: FirSimpleFunction, data: Nothing? diff --git a/core/compiler.common.jvm/src/org/jetbrains/kotlin/name/JvmNames.kt b/core/compiler.common.jvm/src/org/jetbrains/kotlin/name/JvmNames.kt index f9309b1e116..f84cfe4c5ba 100644 --- a/core/compiler.common.jvm/src/org/jetbrains/kotlin/name/JvmNames.kt +++ b/core/compiler.common.jvm/src/org/jetbrains/kotlin/name/JvmNames.kt @@ -6,6 +6,8 @@ package org.jetbrains.kotlin.name object JvmNames { + val BASE_JVM_PACKAGE = StandardClassIds.BASE_KOTLIN_PACKAGE.child(Name.identifier("jvm")) + @JvmField val JVM_NAME: FqName = FqName("kotlin.jvm.JvmName") @@ -67,4 +69,37 @@ object JvmNames { val TRANSIENT_ANNOTATION_CLASS_ID = ClassId.topLevel(TRANSIENT_ANNOTATION_FQ_NAME) const val MULTIFILE_PART_NAME_DELIMITER = "__" + + object Annotations { + val JvmStatic = "JvmStatic".jvmId() + val JvmName = "JvmName".jvmId() + val JvmField = "JvmField".jvmId() + val JvmDefault = "JvmDefault".jvmId() + val JvmRepeatable = "JvmRepeatable".jvmId() + val JvmRecord = "JvmRecord".jvmId() + val JvmVolatile = "Volatile".jvmId() + val Throws = "Throws".jvmId() + + object Java { + val Deprecated = "Deprecated".javaLangId() + val Repeatable = "Repeatable".javaAnnotationId() + val Retention = "Retention".javaAnnotationId() + val Documented = "Documented".javaAnnotationId() + val Target = "Target".javaAnnotationId() + val ElementType = "ElementType".javaAnnotationId() + val RetentionPolicy = "RetentionPolicy".javaAnnotationId() + } + } + + object Java { + val Record = "Record".javaLangId() + } } + +private fun String.jvmId() = ClassId(JvmNames.BASE_JVM_PACKAGE, Name.identifier(this)) + +private val JAVA_LANG_PACKAGE = FqName("java.lang") +private val JAVA_LANG_ANNOTATION_PACKAGE = JAVA_LANG_PACKAGE.child(Name.identifier("annotation")) + +private fun String.javaLangId() = ClassId(JAVA_LANG_PACKAGE, Name.identifier(this)) +private fun String.javaAnnotationId() = ClassId(JAVA_LANG_ANNOTATION_PACKAGE, Name.identifier(this)) diff --git a/core/compiler.common/src/org/jetbrains/kotlin/name/StandardClassIds.kt b/core/compiler.common/src/org/jetbrains/kotlin/name/StandardClassIds.kt index 3739b8d6e6b..6827ba572f8 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/name/StandardClassIds.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/name/StandardClassIds.kt @@ -166,15 +166,6 @@ object StandardClassIds { val Repeatable = "Repeatable".annotationId() val MustBeDocumented = "MustBeDocumented".annotationId() - val JvmStatic = "JvmStatic".jvmId() - val JvmName = "JvmName".jvmId() - val JvmField = "JvmField".jvmId() - val JvmDefault = "JvmDefault".jvmId() - val JvmRepeatable = "JvmRepeatable".jvmId() - val JvmRecord = "JvmRecord".jvmId() - val JvmVolatile = "Volatile".jvmId() - val Throws = "Throws".jvmId() - val Volatile = "Volatile".concurrentId() val Test = "Test".testId() @@ -199,16 +190,6 @@ object StandardClassIds { val OptionalExpectation = "OptionalExpectation".baseId() val ImplicitlyActualizedByJvmDeclaration = "ImplicitlyActualizedByJvmDeclaration".jvmId() - object Java { - val Deprecated = "Deprecated".javaLangId() - val Repeatable = "Repeatable".javaAnnotationId() - val Retention = "Retention".javaAnnotationId() - val Documented = "Documented".javaAnnotationId() - val Target = "Target".javaAnnotationId() - val ElementType = "ElementType".javaAnnotationId() - val RetentionPolicy = "RetentionPolicy".javaAnnotationId() - } - object ParameterNames { val value = Name.identifier("value") @@ -241,10 +222,6 @@ object StandardClassIds { val contract = "contract".callableId(BASE_CONTRACTS_PACKAGE) } - object Java { - val Record = "Record".javaLangId() - } - object Collections { val baseCollectionToMutableEquivalent: Map = mapOf( StandardClassIds.Iterable to StandardClassIds.MutableIterable, @@ -283,10 +260,4 @@ private fun String.testId() = ClassId(StandardClassIds.BASE_TEST_PACKAGE, Name.i private fun String.callableId(packageName: FqName) = CallableId(packageName, Name.identifier(this)) private fun String.callableId(classId: ClassId) = CallableId(classId, Name.identifier(this)) -private val JAVA_LANG_PACKAGE = FqName("java.lang") -private val JAVA_LANG_ANNOTATION_PACKAGE = JAVA_LANG_PACKAGE.child(Name.identifier("annotation")) - -private fun String.javaLangId() = ClassId(JAVA_LANG_PACKAGE, Name.identifier(this)) -private fun String.javaAnnotationId() = ClassId(JAVA_LANG_ANNOTATION_PACKAGE, Name.identifier(this)) - private fun Map.inverseMap(): Map = entries.associate { (k, v) -> v to k } diff --git a/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationLoweringExtension.kt b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationLoweringExtension.kt index 9303d082067..edd834cb21d 100644 --- a/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationLoweringExtension.kt +++ b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationLoweringExtension.kt @@ -23,10 +23,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid -import org.jetbrains.kotlin.name.CallableId -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.name.StandardClassIds +import org.jetbrains.kotlin.name.* import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlinx.serialization.compiler.backend.ir.* import org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializationJvmIrIntrinsicSupport @@ -66,7 +63,7 @@ class SerializationPluginContext(baseContext: IrPluginContext, val metadataPlugi referenceFunctions(CallableId(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, Name.identifier("intArrayOf"))).first() // Kotlin stdlib declarations - internal val jvmFieldClassSymbol = referenceClass(StandardClassIds.Annotations.JvmField)!! + internal val jvmFieldClassSymbol = referenceClass(JvmNames.Annotations.JvmField)!! internal val lazyModeClass = referenceClass(ClassId.topLevel(SerializationDependencies.LAZY_MODE_FQ))!!.owner internal val lazyModePublicationEnumEntry = diff --git a/plugins/kotlinx-serialization/kotlinx-serialization.k1/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt b/plugins/kotlinx-serialization/kotlinx-serialization.k1/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt index ba96198aa9b..6fd6d90e0ee 100644 --- a/plugins/kotlinx-serialization/kotlinx-serialization.k1/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt +++ b/plugins/kotlinx-serialization/kotlinx-serialization.k1/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.* import org.jetbrains.kotlin.descriptors.impl.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation +import org.jetbrains.kotlin.name.JvmNames import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor @@ -507,7 +508,7 @@ object KSerializerDescriptorResolver { else this.makeNullable() fun createWriteSelfFunctionDescriptor(thisClass: ClassDescriptor): SimpleFunctionDescriptor { - val jvmStaticClass = thisClass.module.findClassAcrossModuleDependencies(StandardClassIds.Annotations.JvmStatic)!! + val jvmStaticClass = thisClass.module.findClassAcrossModuleDependencies(JvmNames.Annotations.JvmStatic)!! val jvmStaticAnnotation = AnnotationDescriptorImpl(jvmStaticClass.defaultType, mapOf(), jvmStaticClass.source) val annotations = Annotations.create(listOfNotNull(jvmStaticAnnotation, thisClass.jsExportIgnore())) diff --git a/plugins/kotlinx-serialization/kotlinx-serialization.k2/src/org/jetbrains/kotlinx/serialization/compiler/fir/SerializationFirDeclarationsForMetadataProvider.kt b/plugins/kotlinx-serialization/kotlinx-serialization.k2/src/org/jetbrains/kotlinx/serialization/compiler/fir/SerializationFirDeclarationsForMetadataProvider.kt index 24a4ecfbd1a..68f1651ebb1 100644 --- a/plugins/kotlinx-serialization/kotlinx-serialization.k2/src/org/jetbrains/kotlinx/serialization/compiler/fir/SerializationFirDeclarationsForMetadataProvider.kt +++ b/plugins/kotlinx-serialization/kotlinx-serialization.k2/src/org/jetbrains/kotlinx/serialization/compiler/fir/SerializationFirDeclarationsForMetadataProvider.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.JvmNames import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.platform.jvm.isJvm @@ -107,7 +108,7 @@ class SerializationFirDeclarationsForMetadataProvider(session: FirSession) : Fir private fun createJvmStaticAnnotation(): FirAnnotation? { val jvmStatic = - session.symbolProvider.getClassLikeSymbolByClassId(StandardClassIds.Annotations.JvmStatic) as? FirRegularClassSymbol + session.symbolProvider.getClassLikeSymbolByClassId(JvmNames.Annotations.JvmStatic) as? FirRegularClassSymbol ?: return null val jvmStaticCtor = jvmStatic.declarationSymbols.firstIsInstanceOrNull() ?: return null diff --git a/plugins/kotlinx-serialization/kotlinx-serialization.k2/src/org/jetbrains/kotlinx/serialization/compiler/fir/checkers/FirSerializationPluginClassChecker.kt b/plugins/kotlinx-serialization/kotlinx-serialization.k2/src/org/jetbrains/kotlinx/serialization/compiler/fir/checkers/FirSerializationPluginClassChecker.kt index 535d284a71e..9df2c40129d 100644 --- a/plugins/kotlinx-serialization/kotlinx-serialization.k2/src/org/jetbrains/kotlinx/serialization/compiler/fir/checkers/FirSerializationPluginClassChecker.kt +++ b/plugins/kotlinx-serialization/kotlinx-serialization.k2/src/org/jetbrains/kotlinx/serialization/compiler/fir/checkers/FirSerializationPluginClassChecker.kt @@ -11,12 +11,12 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies import org.jetbrains.kotlin.diagnostics.reportOn -import org.jetbrains.kotlin.fir.analysis.checkers.containsRepeatableAnnotation import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirClassChecker import org.jetbrains.kotlin.fir.analysis.checkers.isSingleFieldValueClass import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.annotationPlatformSupport import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.dispatchReceiverClassLookupTagOrNull import org.jetbrains.kotlin.fir.expressions.* @@ -79,7 +79,7 @@ object FirSerializationPluginClassChecker : FirClassChecker() { context(CheckerContext) private fun checkInheritableSerialInfoNotRepeatable(classSymbol: FirClassSymbol, reporter: DiagnosticReporter) { if (classSymbol.classKind != ClassKind.ANNOTATION_CLASS) return - if (!classSymbol.containsRepeatableAnnotation(session)) return + if (!session.annotationPlatformSupport.symbolContainsRepeatableAnnotation(classSymbol, session)) return val anno = classSymbol.resolvedAnnotationsWithClassIds .find { it.toAnnotationClassId(session) == SerializationAnnotations.inheritableSerialInfoClassId } ?: return diff --git a/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/FirParcelizePropertyChecker.kt b/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/FirParcelizePropertyChecker.kt index ac713150fe3..88348301953 100644 --- a/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/FirParcelizePropertyChecker.kt +++ b/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/FirParcelizePropertyChecker.kt @@ -15,7 +15,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirPropertyChecker import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirRegularClass -import org.jetbrains.kotlin.fir.declarations.hasJvmFieldAnnotation +import org.jetbrains.kotlin.fir.java.hasJvmFieldAnnotation import org.jetbrains.kotlin.fir.declarations.utils.fromPrimaryConstructor import org.jetbrains.kotlin.fir.declarations.utils.hasBackingField import org.jetbrains.kotlin.fir.declarations.utils.isCompanion