[FIR] Move duplicating names and classIds to StandardClassIds

This commit is contained in:
Dmitriy Novozhilov
2021-09-14 11:37:20 +03:00
committed by teamcityserver
parent 4793674eae
commit 5c2a3bb78e
18 changed files with 163 additions and 151 deletions
@@ -45,7 +45,7 @@ internal class ConeTypeIdeRenderer(
private fun StringBuilder.renderAnnotationList(annotations: List<FirAnnotation>?) { private fun StringBuilder.renderAnnotationList(annotations: List<FirAnnotation>?) {
if (annotations != null) { if (annotations != null) {
val filteredExtensionIfNeeded = annotations.applyIf(filterExtensionFunctionType) { val filteredExtensionIfNeeded = annotations.applyIf(filterExtensionFunctionType) {
annotations.filterNot { it.toAnnotationClassId() == StandardClassIds.extensionFunctionType } annotations.filterNot { it.toAnnotationClassId() == StandardClassIds.Annotations.ExtensionFunctionType }
} }
renderAnnotations(this@ConeTypeIdeRenderer, filteredExtensionIfNeeded, session) renderAnnotations(this@ConeTypeIdeRenderer, filteredExtensionIfNeeded, session)
} }
@@ -8,13 +8,13 @@ package org.jetbrains.kotlin.fir.analysis.jvm.checkers
import org.jetbrains.kotlin.config.JvmDefaultMode import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.fir.FirAnnotationContainer import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.getAnnotationByFqName import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.name.JvmNames.JVM_DEFAULT_FQ_NAME import org.jetbrains.kotlin.name.StandardClassIds
fun <D> FirBasedSymbol<out D>.isCompiledToJvmDefault(jvmDefaultMode: JvmDefaultMode): Boolean where D : FirAnnotationContainer, D : FirDeclaration { fun <D> FirBasedSymbol<out D>.isCompiledToJvmDefault(jvmDefaultMode: JvmDefaultMode): Boolean where D : FirAnnotationContainer, D : FirDeclaration {
// TODO: Fix support for all cases // TODO: Fix support for all cases
if (getAnnotationByFqName(JVM_DEFAULT_FQ_NAME) != null) return true if (getAnnotationByClassId(StandardClassIds.Annotations.JvmDefault) != null) return true
return jvmDefaultMode.forAllMethodsWithBody return jvmDefaultMode.forAllMethodsWithBody
} }
@@ -62,7 +62,7 @@ object FirJvmNameChecker : FirBasicDeclarationChecker() {
private fun FirAnnotatedDeclaration.findJvmNameAnnotation(): FirAnnotation? { private fun FirAnnotatedDeclaration.findJvmNameAnnotation(): FirAnnotation? {
return annotations.firstOrNull { return annotations.firstOrNull {
it.annotationTypeRef.coneType.classId == StandardClassIds.JvmName it.annotationTypeRef.coneType.classId == StandardClassIds.Annotations.JvmName
} }
} }
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
@@ -43,14 +42,14 @@ object FirJvmStaticChecker : FirAnnotatedDeclarationChecker() {
return return
} }
val declarationAnnotation = declaration.findAnnotation(StandardClassIds.JvmStatic) val declarationAnnotation = declaration.findAnnotation(StandardClassIds.Annotations.JvmStatic)
if (declarationAnnotation != null) { if (declarationAnnotation != null) {
checkAnnotated(declaration, context, reporter, declaration.source) checkAnnotated(declaration, context, reporter, declaration.source)
} }
fun checkIfAnnotated(it: FirAnnotatedDeclaration) { fun checkIfAnnotated(it: FirAnnotatedDeclaration) {
if (!it.hasAnnotation(StandardClassIds.JvmStatic)) { if (!it.hasAnnotation(StandardClassIds.Annotations.JvmStatic)) {
return return
} }
val targetSource = it.source ?: declaration.source val targetSource = it.source ?: declaration.source
@@ -203,7 +202,7 @@ object FirJvmStaticChecker : FirAnnotatedDeclarationChecker() {
) { ) {
if ( if (
declaration is FirProperty && declaration.isConst || declaration is FirProperty && declaration.isConst ||
declaration.hasAnnotationNamedAs(StandardClassIds.JvmField) declaration.hasAnnotationNamedAs(StandardClassIds.Annotations.JvmField)
) { ) {
reporter.reportOn(targetSource, FirJvmErrors.JVM_STATIC_ON_CONST_OR_JVM_FIELD, context) reporter.reportOn(targetSource, FirJvmErrors.JVM_STATIC_ON_CONST_OR_JVM_FIELD, context)
} }
@@ -5,14 +5,17 @@
package org.jetbrains.kotlin.fir.analysis.jvm.checkers.declaration package org.jetbrains.kotlin.fir.analysis.jvm.checkers.declaration
import org.jetbrains.kotlin.builtins.StandardNames //import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.* import org.jetbrains.kotlin.fir.analysis.checkers.containsRepeatableAnnotation
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirAnnotatedDeclarationChecker import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirAnnotatedDeclarationChecker
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.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
@@ -33,10 +36,9 @@ import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
object FirRepeatableAnnotationChecker : FirAnnotatedDeclarationChecker() { object FirRepeatableAnnotationChecker : FirAnnotatedDeclarationChecker() {
private val REPEATABLE_PARAMETER_NAME = Name.identifier("value")
private val JAVA_REPEATABLE_ANNOTATION = ClassId.fromString("java/lang/annotation/Repeatable")
private val REPEATABLE_ANNOTATION_CONTAINER_NAME = Name.identifier(JvmAbi.REPEATABLE_ANNOTATION_CONTAINER_NAME) private val REPEATABLE_ANNOTATION_CONTAINER_NAME = Name.identifier(JvmAbi.REPEATABLE_ANNOTATION_CONTAINER_NAME)
override fun check(declaration: FirAnnotatedDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(declaration: FirAnnotatedDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -84,13 +86,13 @@ object FirRepeatableAnnotationChecker : FirAnnotatedDeclarationChecker() {
} }
if (declaration is FirRegularClass) { if (declaration is FirRegularClass) {
val javaRepeatable = annotations.find { it.classId == JAVA_REPEATABLE_ANNOTATION } val javaRepeatable = annotations.find { it.classId == StandardClassIds.Annotations.Java.Repeatable }
if (javaRepeatable != null) { if (javaRepeatable != null) {
withSuppressedDiagnostics(javaRepeatable, context) { withSuppressedDiagnostics(javaRepeatable, context) {
checkJavaRepeatableAnnotationDeclaration(javaRepeatable, declaration, context, reporter) checkJavaRepeatableAnnotationDeclaration(javaRepeatable, declaration, context, reporter)
} }
} else { } else {
val kotlinRepeatable = annotations.find { it.classId == StandardNames.FqNames.repeatableClassId } val kotlinRepeatable = annotations.find { it.classId == StandardClassIds.Annotations.Repeatable }
if (kotlinRepeatable != null) { if (kotlinRepeatable != null) {
withSuppressedDiagnostics(kotlinRepeatable, context) { withSuppressedDiagnostics(kotlinRepeatable, context) {
checkKotlinRepeatableAnnotationDeclaration(kotlinRepeatable, declaration, context, reporter) checkKotlinRepeatableAnnotationDeclaration(kotlinRepeatable, declaration, context, reporter)
@@ -101,13 +103,14 @@ object FirRepeatableAnnotationChecker : FirAnnotatedDeclarationChecker() {
} }
private fun FirClassLikeSymbol<*>.resolveContainerAnnotation(): ClassId? { private fun FirClassLikeSymbol<*>.resolveContainerAnnotation(): ClassId? {
val repeatableAnnotation = val repeatableAnnotation = getAnnotationByClassId(StandardClassIds.Annotations.Repeatable)
getAnnotationByClassId(StandardNames.FqNames.repeatableClassId) ?: getAnnotationByClassId(JAVA_REPEATABLE_ANNOTATION) ?: return null ?: getAnnotationByClassId(StandardClassIds.Annotations.Java.Repeatable)
?: return null
return repeatableAnnotation.resolveContainerAnnotation() return repeatableAnnotation.resolveContainerAnnotation()
} }
private fun FirAnnotation.resolveContainerAnnotation(): ClassId? { private fun FirAnnotation.resolveContainerAnnotation(): ClassId? {
val value = findArgumentByName(REPEATABLE_PARAMETER_NAME) ?: return null val value = findArgumentByName(StandardClassIds.Annotations.ParameterNames.value) ?: return null
val classCallArgument = (value as? FirGetClassCall)?.argument ?: return null val classCallArgument = (value as? FirGetClassCall)?.argument ?: return null
if (classCallArgument is FirResolvedQualifier) { if (classCallArgument is FirResolvedQualifier) {
return classCallArgument.classId return classCallArgument.classId
@@ -125,7 +128,8 @@ object FirRepeatableAnnotationChecker : FirAnnotatedDeclarationChecker() {
reporter: DiagnosticReporter reporter: DiagnosticReporter
) { ) {
val containerClassId = javaRepeatable.resolveContainerAnnotation() ?: return val containerClassId = javaRepeatable.resolveContainerAnnotation() ?: return
val containerClassSymbol = context.session.symbolProvider.getClassLikeSymbolByClassId(containerClassId) as? FirRegularClassSymbol ?: return val containerClassSymbol =
context.session.symbolProvider.getClassLikeSymbolByClassId(containerClassId) as? FirRegularClassSymbol ?: return
checkRepeatableAnnotationContainer(annotationClass, containerClassSymbol, javaRepeatable.source, context, reporter) checkRepeatableAnnotationContainer(annotationClass, containerClassSymbol, javaRepeatable.source, context, reporter)
} }
@@ -166,7 +170,7 @@ object FirRepeatableAnnotationChecker : FirAnnotatedDeclarationChecker() {
?: return ?: return
val valueParameterSymbols = containerCtor.valueParameterSymbols val valueParameterSymbols = containerCtor.valueParameterSymbols
val parameterName = JavaClassConverter.VALUE_METHOD_NAME val parameterName = StandardClassIds.Annotations.ParameterNames.value
val value = valueParameterSymbols.find { it.name == parameterName } val value = valueParameterSymbols.find { it.name == parameterName }
if (value == null || !value.resolvedReturnTypeRef.isArrayType || if (value == null || !value.resolvedReturnTypeRef.isArrayType ||
value.resolvedReturnTypeRef.type.typeArguments.single().type != annotationClass.defaultType() value.resolvedReturnTypeRef.type.typeArguments.single().type != annotationClass.defaultType()
@@ -32,16 +32,10 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.StandardClassIds.Annotations.ParameterNames
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.UseSiteTargetsList import org.jetbrains.kotlin.resolve.UseSiteTargetsList
private val RETENTION_PARAMETER_NAME = Name.identifier("value")
private val TARGET_PARAMETER_NAME = Name.identifier("allowedTargets")
private val JAVA_REPEATABLE_ANNOTATION = FqName("java.lang.annotation.Repeatable")
private val JAVA_REPEATABLE_ANNOTATION_CLASS_ID = ClassId.topLevel(JAVA_REPEATABLE_ANNOTATION)
private val JVM_REPEATABLE_ANNOTATION_CLASS_ID = ClassId.fromString("kotlin/jvm/JvmRepeatable")
@OptIn(SymbolInternals::class) @OptIn(SymbolInternals::class)
fun FirAnnotation.getRetention(session: FirSession): AnnotationRetention { fun FirAnnotation.getRetention(session: FirSession): AnnotationRetention {
@@ -58,7 +52,7 @@ fun FirRegularClass.getRetention(): AnnotationRetention {
} }
fun FirAnnotation.getRetention(): AnnotationRetention { fun FirAnnotation.getRetention(): AnnotationRetention {
val retentionArgument = findArgumentByName(RETENTION_PARAMETER_NAME) as? FirQualifiedAccessExpression val retentionArgument = findArgumentByName(ParameterNames.retentionValue) as? FirQualifiedAccessExpression
?: return AnnotationRetention.RUNTIME ?: return AnnotationRetention.RUNTIME
val retentionName = (retentionArgument.calleeReference as? FirResolvedNamedReference)?.name?.asString() val retentionName = (retentionArgument.calleeReference as? FirResolvedNamedReference)?.name?.asString()
?: return AnnotationRetention.RUNTIME ?: return AnnotationRetention.RUNTIME
@@ -81,7 +75,7 @@ fun FirRegularClass.getAllowedAnnotationTargets(): Set<KotlinTarget> {
fun FirClassLikeSymbol<*>.getAllowedAnnotationTargets(): Set<KotlinTarget> { fun FirClassLikeSymbol<*>.getAllowedAnnotationTargets(): Set<KotlinTarget> {
val targetAnnotation = getTargetAnnotation() ?: return defaultAnnotationTargets val targetAnnotation = getTargetAnnotation() ?: return defaultAnnotationTargets
val arguments = targetAnnotation.findArgumentByName(TARGET_PARAMETER_NAME)?.unfoldArrayOrVararg().orEmpty() val arguments = targetAnnotation.findArgumentByName(ParameterNames.targetAllowedTargets)?.unfoldArrayOrVararg().orEmpty()
return arguments.mapNotNullTo(mutableSetOf()) { argument -> return arguments.mapNotNullTo(mutableSetOf()) { argument ->
val targetExpression = argument as? FirQualifiedAccessExpression val targetExpression = argument as? FirQualifiedAccessExpression
@@ -134,8 +128,8 @@ fun FirAnnotation.isRepeatable(session: FirSession): Boolean {
fun FirClassLikeSymbol<*>.containsRepeatableAnnotation(session: FirSession): Boolean { fun FirClassLikeSymbol<*>.containsRepeatableAnnotation(session: FirSession): Boolean {
if (getAnnotationByClassId(StandardNames.FqNames.repeatableClassId) != null) return true if (getAnnotationByClassId(StandardNames.FqNames.repeatableClassId) != null) return true
if (getAnnotationByClassId(JAVA_REPEATABLE_ANNOTATION_CLASS_ID) != null || if (getAnnotationByClassId(StandardClassIds.Annotations.Java.Repeatable) != null ||
getAnnotationByClassId(JVM_REPEATABLE_ANNOTATION_CLASS_ID) != null getAnnotationByClassId(StandardClassIds.Annotations.JvmRepeatable) != null
) { ) {
return session.languageVersionSettings.supportsFeature(LanguageFeature.RepeatableAnnotations) || return session.languageVersionSettings.supportsFeature(LanguageFeature.RepeatableAnnotations) ||
getAnnotationRetention() == AnnotationRetention.SOURCE && origin == FirDeclarationOrigin.Java getAnnotationRetention() == AnnotationRetention.SOURCE && origin == FirDeclarationOrigin.Java
@@ -67,7 +67,7 @@ private fun FirAnnotatedDeclaration.getOwnSinceKotlinVersion(session: FirSession
// TODO: use-site targeted annotations // TODO: use-site targeted annotations
fun FirAnnotatedDeclaration.consider() { fun FirAnnotatedDeclaration.consider() {
val sinceKotlinSingleArgument = getAnnotationByClassId(StandardClassIds.SinceKotlin)?.findArgumentByName(SINCE_KOTLIN_VERSION_NAME) val sinceKotlinSingleArgument = getAnnotationByClassId(StandardClassIds.Annotations.SinceKotlin)?.findArgumentByName(SINCE_KOTLIN_VERSION_NAME)
val apiVersion = ((sinceKotlinSingleArgument as? FirConstExpression<*>)?.value as? String)?.let(ApiVersion.Companion::parse) val apiVersion = ((sinceKotlinSingleArgument as? FirConstExpression<*>)?.value as? String)?.let(ApiVersion.Companion::parse)
if (apiVersion != null) { if (apiVersion != null) {
// TODO: combine wasExperimentalMarkerClasses in case of several associated declarations with the same maximal API version // TODO: combine wasExperimentalMarkerClasses in case of several associated declarations with the same maximal API version
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
@@ -14,15 +13,16 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirAnnotatedDeclaration import org.jetbrains.kotlin.fir.declarations.FirAnnotatedDeclaration
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.getAnnotationByFqName import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
import org.jetbrains.kotlin.fir.declarations.utils.visibility import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.name.StandardClassIds
object FirPublishedApiChecker : FirAnnotatedDeclarationChecker() { object FirPublishedApiChecker : FirAnnotatedDeclarationChecker() {
override fun check(declaration: FirAnnotatedDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(declaration: FirAnnotatedDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration !is FirMemberDeclaration) return if (declaration !is FirMemberDeclaration) return
if (declaration is FirValueParameter) return if (declaration is FirValueParameter) return
if (declaration.visibility == Visibilities.Internal) return if (declaration.visibility == Visibilities.Internal) return
val annotation = declaration.getAnnotationByFqName(StandardNames.FqNames.publishedApi) ?: return val annotation = declaration.getAnnotationByClassId(StandardClassIds.Annotations.PublishedApi) ?: return
reporter.reportOn(annotation.source, FirErrors.NON_INTERNAL_PUBLISHED_API, context) reporter.reportOn(annotation.source, FirErrors.NON_INTERNAL_PUBLISHED_API, context)
} }
} }
@@ -43,7 +43,7 @@ abstract class AbstractDiagnosticCollector(
fun getDiagnosticsSuppressedForContainer(annotationContainer: FirAnnotationContainer): List<String>? { fun getDiagnosticsSuppressedForContainer(annotationContainer: FirAnnotationContainer): List<String>? {
val annotations = annotationContainer.annotations.filter { val annotations = annotationContainer.annotations.filter {
val type = it.annotationTypeRef.coneType as? ConeClassLikeType ?: return@filter false val type = it.annotationTypeRef.coneType as? ConeClassLikeType ?: return@filter false
type.lookupTag.classId == StandardClassIds.Suppress type.lookupTag.classId == StandardClassIds.Annotations.Suppress
} }
if (annotations.isEmpty()) return null if (annotations.isEmpty()) return null
return annotations.flatMap { annotationCall -> return annotations.flatMap { annotationCall ->
@@ -5,10 +5,10 @@
package org.jetbrains.kotlin.fir.types package org.jetbrains.kotlin.fir.types
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
import kotlin.reflect.KClass import kotlin.reflect.KClass
object CompilerConeAttributes { object CompilerConeAttributes {
@@ -37,7 +37,7 @@ object CompilerConeAttributes {
} }
object EnhancedNullability : ConeAttribute<EnhancedNullability>() { object EnhancedNullability : ConeAttribute<EnhancedNullability>() {
val ANNOTATION_CLASS_ID = StandardClassIds.EnhancedNullability val ANNOTATION_CLASS_ID = StandardClassIds.Annotations.EnhancedNullability
override fun union(other: EnhancedNullability?): EnhancedNullability? = other override fun union(other: EnhancedNullability?): EnhancedNullability? = other
override fun intersect(other: EnhancedNullability?): EnhancedNullability = this override fun intersect(other: EnhancedNullability?): EnhancedNullability = this
@@ -6,13 +6,13 @@
package org.jetbrains.kotlin.fir.backend package org.jetbrains.kotlin.fir.backend
import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.symbolProvider
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
class Fir2IrBuiltIns( class Fir2IrBuiltIns(
@@ -24,14 +24,14 @@ class Fir2IrBuiltIns(
} }
private val enhancedNullabilityAnnotationSymbol by lazy { private val enhancedNullabilityAnnotationSymbol by lazy {
annotationSymbolById(StandardClassIds.EnhancedNullability) annotationSymbolById(StandardClassIds.Annotations.EnhancedNullability)
} }
internal fun enhancedNullabilityAnnotationConstructorCall(): IrConstructorCall? = internal fun enhancedNullabilityAnnotationConstructorCall(): IrConstructorCall? =
enhancedNullabilityAnnotationSymbol?.toConstructorCall() enhancedNullabilityAnnotationSymbol?.toConstructorCall()
private val flexibleNullabilityAnnotationSymbol by lazy { private val flexibleNullabilityAnnotationSymbol by lazy {
annotationSymbolById(StandardClassIds.FlexibleNullability) annotationSymbolById(StandardClassIds.Annotations.FlexibleNullability)
} }
internal fun flexibleNullabilityAnnotationConstructorCall(): IrConstructorCall? = internal fun flexibleNullabilityAnnotationConstructorCall(): IrConstructorCall? =
@@ -32,15 +32,12 @@ import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.load.java.structure.* import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.load.java.structure.impl.JavaElementImpl import org.jetbrains.kotlin.load.java.structure.impl.JavaElementImpl
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds.Annotations
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.ParameterNames
import org.jetbrains.kotlin.types.ConstantValueKind import org.jetbrains.kotlin.types.ConstantValueKind
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import java.lang.Deprecated import java.util.*
import java.lang.annotation.Documented
import java.lang.annotation.Retention
import java.lang.annotation.Target
import java.util.EnumSet
internal val JavaModifierListOwner.modality: Modality internal val JavaModifierListOwner.modality: Modality
get() = when { get() = when {
@@ -84,11 +81,6 @@ private fun buildEnumCall(session: FirSession, classId: ClassId?, entryName: Nam
} }
} }
private val JAVA_TARGET_CLASS_ID = ClassId.topLevel(FqName(Target::class.java.canonicalName))
private val JAVA_RETENTION_CLASS_ID = ClassId.topLevel(FqName(Retention::class.java.canonicalName))
private val JAVA_DEPRECATED_CLASS_ID = ClassId.topLevel(FqName(Deprecated::class.java.canonicalName))
private val JAVA_DOCUMENTED_CLASS_ID = ClassId.topLevel(FqName(Documented::class.java.canonicalName))
private val JAVA_TARGETS_TO_KOTLIN = mapOf( private val JAVA_TARGETS_TO_KOTLIN = mapOf(
"TYPE" to EnumSet.of(AnnotationTarget.CLASS, AnnotationTarget.FILE), "TYPE" to EnumSet.of(AnnotationTarget.CLASS, AnnotationTarget.FILE),
"ANNOTATION_TYPE" to EnumSet.of(AnnotationTarget.ANNOTATION_CLASS), "ANNOTATION_TYPE" to EnumSet.of(AnnotationTarget.ANNOTATION_CLASS),
@@ -101,10 +93,6 @@ private val JAVA_TARGETS_TO_KOTLIN = mapOf(
"TYPE_USE" to EnumSet.of(AnnotationTarget.TYPE) "TYPE_USE" to EnumSet.of(AnnotationTarget.TYPE)
) )
private val TARGET_ALLOWED_TARGETS_NAME = Name.identifier("allowedTargets")
private val RETENTION_VALUE_NAME = Name.identifier("value")
private val DEPRECATED_MESSAGE_NAME = Name.identifier("message")
private fun List<JavaAnnotationArgument>.mapJavaTargetArguments(session: FirSession): FirExpression? { private fun List<JavaAnnotationArgument>.mapJavaTargetArguments(session: FirSession): FirExpression? {
return buildVarargArgumentsExpression { return buildVarargArgumentsExpression {
val resultSet = EnumSet.noneOf(AnnotationTarget::class.java) val resultSet = EnumSet.noneOf(AnnotationTarget::class.java)
@@ -152,7 +140,7 @@ private fun fillAnnotationArgumentMapping(
?.declarations ?.declarations
?.firstIsInstanceOrNull<FirConstructor>() ?.firstIsInstanceOrNull<FirConstructor>()
annotationArguments.associateTo(destination) { argument -> annotationArguments.associateTo(destination) { argument ->
val name = argument.name ?: JavaClassConverter.VALUE_METHOD_NAME val name = argument.name ?: ParameterNames.value
val parameter = annotationConstructor?.valueParameters?.find { it.name == name } val parameter = annotationConstructor?.valueParameters?.find { it.name == name }
name to argument.toFirExpression(session, javaTypeParameterStack, parameter?.returnTypeRef) name to argument.toFirExpression(session, javaTypeParameterStack, parameter?.returnTypeRef)
} }
@@ -179,10 +167,10 @@ private fun JavaAnnotation.toFirAnnotationCall(
): FirAnnotation { ): FirAnnotation {
return buildAnnotation { return buildAnnotation {
val lookupTag = when (classId) { val lookupTag = when (classId) {
JAVA_TARGET_CLASS_ID -> ClassId.topLevel(StandardNames.FqNames.target) Annotations.Java.Target -> ClassId.topLevel(StandardNames.FqNames.target)
JAVA_RETENTION_CLASS_ID -> ClassId.topLevel(StandardNames.FqNames.retention) Annotations.Java.Retention -> ClassId.topLevel(StandardNames.FqNames.retention)
JAVA_DOCUMENTED_CLASS_ID -> ClassId.topLevel(StandardNames.FqNames.mustBeDocumented) Annotations.Java.Documented -> ClassId.topLevel(StandardNames.FqNames.mustBeDocumented)
JAVA_DEPRECATED_CLASS_ID -> ClassId.topLevel(StandardNames.FqNames.deprecated) Annotations.Java.Deprecated -> ClassId.topLevel(StandardNames.FqNames.deprecated)
else -> classId else -> classId
}?.let(::ConeClassLikeLookupTagImpl) }?.let(::ConeClassLikeLookupTagImpl)
annotationTypeRef = if (lookupTag != null) { annotationTypeRef = if (lookupTag != null) {
@@ -195,22 +183,22 @@ private fun JavaAnnotation.toFirAnnotationCall(
argumentMapping = buildAnnotationArgumentMapping { argumentMapping = buildAnnotationArgumentMapping {
when (classId) { when (classId) {
JAVA_TARGET_CLASS_ID -> { Annotations.Java.Target -> {
when (val argument = arguments.firstOrNull()) { when (val argument = arguments.firstOrNull()) {
is JavaArrayAnnotationArgument -> argument.getElements().mapJavaTargetArguments(session) is JavaArrayAnnotationArgument -> argument.getElements().mapJavaTargetArguments(session)
is JavaEnumValueAnnotationArgument -> listOf(argument).mapJavaTargetArguments(session) is JavaEnumValueAnnotationArgument -> listOf(argument).mapJavaTargetArguments(session)
else -> null else -> null
}?.let { }?.let {
mapping[TARGET_ALLOWED_TARGETS_NAME] = it mapping[ParameterNames.targetAllowedTargets] = it
} }
} }
JAVA_RETENTION_CLASS_ID -> { Annotations.Java.Retention -> {
arguments.firstOrNull()?.mapJavaRetentionArgument(session)?.let { arguments.firstOrNull()?.mapJavaRetentionArgument(session)?.let {
mapping[RETENTION_VALUE_NAME] = it mapping[ParameterNames.retentionValue] = it
} }
} }
JAVA_DEPRECATED_CLASS_ID -> { Annotations.Java.Deprecated -> {
mapping[DEPRECATED_MESSAGE_NAME] = buildConstExpression( mapping[ParameterNames.deprecatedMessage] = buildConstExpression(
source = null, source = null,
ConstantValueKind.String, ConstantValueKind.String,
"Deprecated in Java" "Deprecated in Java"
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
import org.jetbrains.kotlin.load.kotlin.findKotlinClass import org.jetbrains.kotlin.load.kotlin.findKotlinClass
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.resolve.constants.ClassLiteralValue import org.jetbrains.kotlin.resolve.constants.ClassLiteralValue
internal class AnnotationsLoader(private val session: FirSession, private val kotlinClassFinder: KotlinClassFinder) { internal class AnnotationsLoader(private val session: FirSession, private val kotlinClassFinder: KotlinClassFinder) {
@@ -164,7 +165,7 @@ internal class AnnotationsLoader(private val session: FirSession, private val ko
private fun isRepeatableWithImplicitContainer(lookupTag: ConeClassLikeLookupTag, argumentMap: Map<Name, FirExpression>): Boolean { private fun isRepeatableWithImplicitContainer(lookupTag: ConeClassLikeLookupTag, argumentMap: Map<Name, FirExpression>): Boolean {
if (lookupTag.classId != SpecialJvmAnnotations.JAVA_LANG_ANNOTATION_REPEATABLE) return false if (lookupTag.classId != SpecialJvmAnnotations.JAVA_LANG_ANNOTATION_REPEATABLE) return false
val getClassCall = argumentMap[Name.identifier("value")] as? FirGetClassCall ?: return false val getClassCall = argumentMap[StandardClassIds.Annotations.ParameterNames.value] as? FirGetClassCall ?: return false
val classReference = getClassCall.argument as? FirClassReferenceExpression ?: return false val classReference = getClassCall.argument as? FirClassReferenceExpression ?: return false
val containerType = classReference.classTypeRef.coneType as? ConeClassLikeType ?: return false val containerType = classReference.classTypeRef.coneType as? ConeClassLikeType ?: return false
val classId = containerType.lookupTag.classId val classId = containerType.lookupTag.classId
@@ -20,17 +20,10 @@ import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.coneTypeSafe import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
private val RETENTION_CLASS_ID = ClassId.fromString("kotlin/annotation/Retention")
private val TARGET_CLASS_ID = ClassId.fromString("kotlin/annotation/Target")
private val JVM_FIELD_CLASS_ID = ClassId.fromString("kotlin/jvm/JvmField")
private val RETENTION_VALUE_NAME = Name.identifier("value")
private val TARGET_ALLOWED_TARGET_NAME = Name.identifier("allowedTargets")
private fun FirAnnotation.toAnnotationLookupTag(): ConeClassLikeLookupTag? = private fun FirAnnotation.toAnnotationLookupTag(): ConeClassLikeLookupTag? =
// this cast fails when we have generic-typed annotations @T // this cast fails when we have generic-typed annotations @T
(annotationTypeRef.coneType as? ConeClassLikeType)?.lookupTag (annotationTypeRef.coneType as? ConeClassLikeType)?.lookupTag
@@ -49,12 +42,15 @@ private val FirExpression.callableNameOfMetaAnnotationArgument: Name?
callableSymbol?.callableId?.callableName callableSymbol?.callableId?.callableName
} }
private val sourceName = Name.identifier("SOURCE")
fun FirAnnotationContainer.nonSourceAnnotations(session: FirSession): List<FirAnnotation> = fun FirAnnotationContainer.nonSourceAnnotations(session: FirSession): List<FirAnnotation> =
annotations.filter { annotation -> annotations.filter { annotation ->
val firAnnotationClass = annotation.toAnnotationClass(session) val firAnnotationClass = annotation.toAnnotationClass(session)
firAnnotationClass != null && firAnnotationClass.annotations.none { meta -> firAnnotationClass != null && firAnnotationClass.annotations.none { meta ->
meta.toAnnotationClassId() == RETENTION_CLASS_ID && meta.toAnnotationClassId() == StandardClassIds.Annotations.Retention &&
meta.findArgumentByName(RETENTION_VALUE_NAME)?.callableNameOfMetaAnnotationArgument == Name.identifier("SOURCE") meta.findArgumentByName(StandardClassIds.Annotations.ParameterNames.retentionValue)
?.callableNameOfMetaAnnotationArgument == sourceName
} }
} }
@@ -62,13 +58,13 @@ inline val FirProperty.hasJvmFieldAnnotation: Boolean
get() = annotations.any { it.isJvmFieldAnnotation } get() = annotations.any { it.isJvmFieldAnnotation }
val FirAnnotation.isJvmFieldAnnotation: Boolean val FirAnnotation.isJvmFieldAnnotation: Boolean
get() = toAnnotationClassId() == JVM_FIELD_CLASS_ID get() = toAnnotationClassId() == StandardClassIds.Annotations.JvmField
fun FirAnnotation.useSiteTargetsFromMetaAnnotation(session: FirSession): Set<AnnotationUseSiteTarget> { fun FirAnnotation.useSiteTargetsFromMetaAnnotation(session: FirSession): Set<AnnotationUseSiteTarget> {
return toAnnotationClass(session) return toAnnotationClass(session)
?.annotations ?.annotations
?.find { it.toAnnotationClassId() == TARGET_CLASS_ID } ?.find { it.toAnnotationClassId() == StandardClassIds.Annotations.Target }
?.findArgumentByName(TARGET_ALLOWED_TARGET_NAME) ?.findArgumentByName(StandardClassIds.Annotations.ParameterNames.targetAllowedTargets)
?.unwrapVarargValue() ?.unwrapVarargValue()
?.toAnnotationUseSiteTargets() ?.toAnnotationUseSiteTargets()
?: DEFAULT_USE_SITE_TARGETS ?: DEFAULT_USE_SITE_TARGETS
@@ -105,31 +101,21 @@ fun FirAnnotatedDeclaration.hasAnnotation(classId: ClassId): Boolean {
return annotations.any { it.toAnnotationClassId() == classId } return annotations.any { it.toAnnotationClassId() == classId }
} }
fun <D> FirBasedSymbol<out D>.getAnnotationByFqName(fqName: FqName): FirAnnotation? where D : FirAnnotationContainer, D : FirDeclaration {
return fir.getAnnotationByFqName(fqName)
}
fun <D> FirBasedSymbol<out D>.getAnnotationByClassId(classId: ClassId): FirAnnotation? where D : FirAnnotationContainer, D : FirDeclaration { fun <D> FirBasedSymbol<out D>.getAnnotationByClassId(classId: ClassId): FirAnnotation? where D : FirAnnotationContainer, D : FirDeclaration {
return fir.getAnnotationByClassId(classId) return fir.getAnnotationByClassId(classId)
} }
fun FirAnnotationContainer.getAnnotationByFqName(fqName: FqName): FirAnnotation? {
return annotations.find {
it.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag?.classId?.asSingleFqName() == fqName
}
}
fun FirAnnotationContainer.getAnnotationByClassId(classId: ClassId): FirAnnotation? { fun FirAnnotationContainer.getAnnotationByClassId(classId: ClassId): FirAnnotation? {
return annotations.find { return annotations.find {
it.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag?.classId == classId it.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag?.classId == classId
} }
} }
fun FirAnnotationContainer.getAnnotationsByFqName(fqName: FqName): List<FirAnnotation> = annotations.getAnnotationsByFqName(fqName) fun FirAnnotationContainer.getAnnotationsByClassId(classId: ClassId): List<FirAnnotation> = annotations.getAnnotationsByClassId(classId)
fun List<FirAnnotation>.getAnnotationsByFqName(fqName: FqName): List<FirAnnotation> { fun List<FirAnnotation>.getAnnotationsByClassId(classId: ClassId): List<FirAnnotation> {
return filter { return filter {
it.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag?.classId?.asSingleFqName() == fqName it.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag?.classId == classId
} }
} }
@@ -161,13 +147,11 @@ fun FirAnnotation.getStringArgument(name: Name): String? =
expression.safeAs<FirConstExpression<*>>()?.value as? String expression.safeAs<FirConstExpression<*>>()?.value as? String
} }
private val jvmNameAnnotationFqName = FqName.fromSegments(listOf("kotlin", "jvm", "JvmName"))
fun FirAnnotationContainer.getJvmNameFromAnnotation(target: AnnotationUseSiteTarget? = null): String? { fun FirAnnotationContainer.getJvmNameFromAnnotation(target: AnnotationUseSiteTarget? = null): String? {
val name = Name.identifier("name") val annotationCalls = getAnnotationsByClassId(StandardClassIds.Annotations.JvmName)
val annotationCalls = getAnnotationsByFqName(jvmNameAnnotationFqName)
return annotationCalls.firstNotNullOfOrNull { call -> return annotationCalls.firstNotNullOfOrNull { call ->
call.getStringArgument(name)?.takeIf { target == null || call.useSiteTarget == target } call.getStringArgument(StandardClassIds.Annotations.ParameterNames.jvmNameName)
?.takeIf { target == null || call.useSiteTarget == target }
} }
} }
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.fir.declarations package org.jetbrains.kotlin.fir.declarations
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.FirAnnotationContainer import org.jetbrains.kotlin.fir.FirAnnotationContainer
@@ -16,21 +15,18 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.ParameterNames
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.ParameterNames.deprecatedSinceKotlinErrorSince
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.ParameterNames.deprecatedSinceKotlinHiddenSince
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.ParameterNames.deprecatedSinceKotlinWarningSince
import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
import org.jetbrains.kotlin.resolve.deprecation.SimpleDeprecationInfo import org.jetbrains.kotlin.resolve.deprecation.SimpleDeprecationInfo
import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
private val JAVA_DEPRECATED = FqName("java.lang.Deprecated")
private val HIDDEN_SINCE_NAME = Name.identifier("hiddenSince")
private val ERROR_SINCE_NAME = Name.identifier("errorSince")
private val WARNING_SINCE_NAME = Name.identifier("warningSince")
private val MESSAGE_NAME = Name.identifier("message")
private val LEVEL_NAME = Name.identifier("level")
private val JAVA_ORIGINS = setOf(FirDeclarationOrigin.Java, FirDeclarationOrigin.Enhancement) private val JAVA_ORIGINS = setOf(FirDeclarationOrigin.Java, FirDeclarationOrigin.Enhancement)
fun FirBasedSymbol<*>.getDeprecation(callSite: FirElement?): DeprecationInfo? { fun FirBasedSymbol<*>.getDeprecation(callSite: FirElement?): DeprecationInfo? {
@@ -99,10 +95,13 @@ private fun FirAnnotation.getVersionFromArgument(name: Name): ApiVersion? =
private fun FirAnnotation.getDeprecationLevel(): DeprecationLevelValue? { private fun FirAnnotation.getDeprecationLevel(): DeprecationLevelValue? {
//take last because Annotation might be not resolved yet and arguments passed without explicit names //take last because Annotation might be not resolved yet and arguments passed without explicit names
val argument = if (resolved) { val argument = if (resolved) {
argumentMapping.mapping[LEVEL_NAME] argumentMapping.mapping[ParameterNames.deprecatedLevel]
} else { } else {
val call = this as? FirAnnotationCall ?: return null val call = this as? FirAnnotationCall ?: return null
call.arguments.firstOrNull { it is FirNamedArgumentExpression && it.name == LEVEL_NAME }?.unwrapArgument() ?: arguments.lastOrNull() call.arguments
.firstOrNull { it is FirNamedArgumentExpression && it.name == ParameterNames.deprecatedLevel }
?.unwrapArgument()
?: arguments.lastOrNull()
} ?: return null } ?: return null
val targetExpression = argument as? FirQualifiedAccessExpression ?: return null val targetExpression = argument as? FirQualifiedAccessExpression ?: return null
val targetName = (targetExpression.calleeReference as? FirNamedReference)?.name?.asString() ?: return null val targetName = (targetExpression.calleeReference as? FirNamedReference)?.name?.asString() ?: return null
@@ -113,24 +112,28 @@ private fun List<FirAnnotation>.extractDeprecationInfoPerUseSite(
currentVersion: ApiVersion, currentVersion: ApiVersion,
fromJava: Boolean fromJava: Boolean
): List<Pair<AnnotationUseSiteTarget?, DeprecationInfo>> { ): List<Pair<AnnotationUseSiteTarget?, DeprecationInfo>> {
val annotations = getAnnotationsByFqName(StandardNames.FqNames.deprecated).map { it to false } + val annotations = getAnnotationsByClassId(StandardClassIds.Annotations.Deprecated).map { it to false } +
getAnnotationsByFqName(JAVA_DEPRECATED).map { it to true } getAnnotationsByClassId(StandardClassIds.Annotations.Java.Deprecated).map { it to true }
return annotations.mapNotNull { (deprecated, fromJavaAnnotation) -> return annotations.mapNotNull { (deprecated, fromJavaAnnotation) ->
val deprecationLevel = deprecated.getDeprecationLevel() ?: DeprecationLevelValue.WARNING val deprecationLevel = deprecated.getDeprecationLevel() ?: DeprecationLevelValue.WARNING
val deprecatedSinceKotlin = getAnnotationsByFqName(StandardNames.FqNames.deprecatedSinceKotlin).firstOrNull() val deprecatedSinceKotlin = getAnnotationsByClassId(StandardClassIds.Annotations.DeprecatedSinceKotlin).firstOrNull()
fun levelApplied(name: Name, level: DeprecationLevelValue): DeprecationLevelValue? { fun levelApplied(name: Name, level: DeprecationLevelValue): DeprecationLevelValue? {
deprecatedSinceKotlin?.getVersionFromArgument(name)?.takeIf { it <= currentVersion }?.let { return level } deprecatedSinceKotlin?.getVersionFromArgument(name)?.takeIf { it <= currentVersion }?.let { return level }
return level.takeIf { deprecatedSinceKotlin == null && level == deprecationLevel } return level.takeIf { deprecatedSinceKotlin == null && level == deprecationLevel }
} }
val appliedLevel = (levelApplied(HIDDEN_SINCE_NAME, DeprecationLevelValue.HIDDEN) val appliedLevel = (levelApplied(deprecatedSinceKotlinHiddenSince, DeprecationLevelValue.HIDDEN)
?: levelApplied(ERROR_SINCE_NAME, DeprecationLevelValue.ERROR) ?: levelApplied(deprecatedSinceKotlinErrorSince, DeprecationLevelValue.ERROR)
?: levelApplied(WARNING_SINCE_NAME, DeprecationLevelValue.WARNING)) ?: levelApplied(deprecatedSinceKotlinWarningSince, DeprecationLevelValue.WARNING))
appliedLevel?.let { appliedLevel?.let {
val inheritable = !fromJavaAnnotation && !fromJava val inheritable = !fromJavaAnnotation && !fromJava
deprecated.useSiteTarget to SimpleDeprecationInfo(it, inheritable, deprecated.getStringArgument(MESSAGE_NAME)) deprecated.useSiteTarget to SimpleDeprecationInfo(
it,
inheritable,
deprecated.getStringArgument(ParameterNames.deprecatedMessage)
)
} }
} }
} }
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyBackingField
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility
import org.jetbrains.kotlin.fir.declarations.utils.isExpect import org.jetbrains.kotlin.fir.declarations.utils.isExpect
@@ -196,7 +195,7 @@ class FirStatusResolver(
val annotations = ((containingProperty ?: declaration) as? FirAnnotatedDeclaration)?.annotations ?: emptyList() val annotations = ((containingProperty ?: declaration) as? FirAnnotatedDeclaration)?.annotations ?: emptyList()
val hasPublishedApiAnnotation = annotations.any { val hasPublishedApiAnnotation = annotations.any {
it.typeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag?.classId == StandardClassIds.PublishedApi it.typeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag?.classId == StandardClassIds.Annotations.PublishedApi
} }
var selfPublishedEffectiveVisibility = runIf(hasPublishedApiAnnotation) { var selfPublishedEffectiveVisibility = runIf(hasPublishedApiAnnotation) {
@@ -8,17 +8,14 @@ package org.jetbrains.kotlin.name
import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.StandardNames
object StandardClassIds { object StandardClassIds {
val BASE_KOTLIN_PACKAGE = FqName("kotlin") val BASE_KOTLIN_PACKAGE = FqName("kotlin")
val BASE_REFLECT_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("reflect")) val BASE_REFLECT_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("reflect"))
val BASE_COLLECTIONS_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("collections")) val BASE_COLLECTIONS_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("collections"))
val BASE_JVM_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("jvm")) val BASE_JVM_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("jvm"))
private fun String.baseId() = ClassId(BASE_KOTLIN_PACKAGE, Name.identifier(this)) val BASE_JVM_INTERNAL_PACKAGE = BASE_JVM_PACKAGE.child(Name.identifier("internal"))
private fun ClassId.unsignedId() = ClassId(BASE_KOTLIN_PACKAGE, Name.identifier("U" + shortClassName.identifier)) val BASE_ANNOTATION_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("annotation"))
private fun String.reflectId() = ClassId(BASE_REFLECT_PACKAGE, Name.identifier(this)) val BASE_INTERNAL_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("internal"))
private fun Name.primitiveArrayId() = ClassId(Array.packageFqName, Name.identifier(identifier + Array.shortClassName.identifier)) val BASE_INTERNAL_IR_PACKAGE = BASE_INTERNAL_PACKAGE.child(Name.identifier("ir"))
private fun String.collectionsId() = ClassId(BASE_COLLECTIONS_PACKAGE, Name.identifier(this))
private fun String.jvmId() = ClassId(BASE_JVM_PACKAGE, Name.identifier(this))
val Nothing = "Nothing".baseId() val Nothing = "Nothing".baseId()
val Unit = "Unit".baseId() val Unit = "Unit".baseId()
@@ -64,7 +61,6 @@ object StandardClassIds {
fun byName(name: String) = name.baseId() fun byName(name: String) = name.baseId()
fun reflectByName(name: String) = name.reflectId() fun reflectByName(name: String) = name.reflectId()
val primitiveTypes = setOf(Boolean, Char, Byte, Short, Int, Long, Float, Double) val primitiveTypes = setOf(Boolean, Char, Byte, Short, Int, Long, Float, Double)
val primitiveArrayTypeByElementType = primitiveTypes.associateWith { id -> id.shortClassName.primitiveArrayId() } val primitiveArrayTypeByElementType = primitiveTypes.associateWith { id -> id.shortClassName.primitiveArrayId() }
@@ -76,8 +72,7 @@ object StandardClassIds {
val constantAllowedTypes = primitiveTypes + unsignedTypes + String val constantAllowedTypes = primitiveTypes + unsignedTypes + String
val Continuation = val Continuation = ClassId(StandardNames.COROUTINES_PACKAGE_FQ_NAME, StandardNames.CONTINUATION_INTERFACE_FQ_NAME.shortName())
ClassId(StandardNames.COROUTINES_PACKAGE_FQ_NAME, StandardNames.CONTINUATION_INTERFACE_FQ_NAME.shortName())
@Suppress("FunctionName") @Suppress("FunctionName")
fun FunctionN(n: Int): ClassId { fun FunctionN(n: Int): ClassId {
@@ -103,25 +98,73 @@ object StandardClassIds {
val MapEntry = Map.createNestedClassId(Name.identifier("Entry")) val MapEntry = Map.createNestedClassId(Name.identifier("Entry"))
val MutableMapEntry = MutableMap.createNestedClassId(Name.identifier("MutableEntry")) val MutableMapEntry = MutableMap.createNestedClassId(Name.identifier("MutableEntry"))
val extensionFunctionType = "ExtensionFunctionType".baseId()
val Suppress = "Suppress".baseId()
val FlexibleNullability = ClassId(FqName("kotlin.internal.ir"), Name.identifier("FlexibleNullability"))
val EnhancedNullability = ClassId(FqName("kotlin.jvm.internal"), Name.identifier("EnhancedNullability"))
val PublishedApi = "PublishedApi".baseId()
val SinceKotlin = "SinceKotlin".baseId()
val coroutineContext = CallableId(StandardNames.COROUTINES_PACKAGE_FQ_NAME, Name.identifier("coroutineContext")) val coroutineContext = CallableId(StandardNames.COROUTINES_PACKAGE_FQ_NAME, Name.identifier("coroutineContext"))
val suspend = CallableId(BASE_KOTLIN_PACKAGE, Name.identifier("suspend")) val suspend = CallableId(BASE_KOTLIN_PACKAGE, Name.identifier("suspend"))
val JvmStatic = "JvmStatic".jvmId()
val JvmName = "JvmName".jvmId()
val JvmField = "JvmField".jvmId()
val Result = "Result".baseId() val Result = "Result".baseId()
object Annotations {
val Suppress = "Suppress".baseId()
val PublishedApi = "PublishedApi".baseId()
val SinceKotlin = "SinceKotlin".baseId()
val ExtensionFunctionType = "ExtensionFunctionType".baseId()
val Deprecated = "Deprecated".baseId()
val DeprecatedSinceKotlin = "DeprecatedSinceKotlin".baseId()
val Repeatable = "Repeatable".annotationId()
val Retention = "Retention".annotationId()
val Target = "Target".annotationId()
val JvmStatic = "JvmStatic".jvmId()
val JvmName = "JvmName".jvmId()
val JvmField = "JvmField".jvmId()
val JvmDefault = "JvmDefault".jvmId()
val JvmRepeatable = "JvmRepeatable".jvmId()
val FlexibleNullability = "FlexibleNullability".internalIrId()
val EnhancedNullability = "EnhancedNullability".jvmInternalId()
object Java {
val Deprecated = "Deprecated".javaLangId()
val Repeatable = "Repeatable".javaAnnotationId()
val Retention = "Retention".javaAnnotationId()
val Documented = "Documented".javaAnnotationId()
val Target = "Target".javaAnnotationId()
}
object ParameterNames {
val value = Name.identifier("value")
val retentionValue = value
val targetAllowedTargets = Name.identifier("allowedTargets")
val jvmNameName = Name.identifier("name")
val deprecatedMessage = Name.identifier("message")
val deprecatedLevel = Name.identifier("level")
val deprecatedSinceKotlinWarningSince = Name.identifier("warningSince")
val deprecatedSinceKotlinErrorSince = Name.identifier("errorSince")
val deprecatedSinceKotlinHiddenSince = Name.identifier("hiddenSince")
}
}
} }
private fun <K, V> Map<K, V>.inverseMap() = entries.associate { (k, v) -> v to k } private fun String.baseId() = ClassId(StandardClassIds.BASE_KOTLIN_PACKAGE, Name.identifier(this))
private fun ClassId.unsignedId() = ClassId(StandardClassIds.BASE_KOTLIN_PACKAGE, Name.identifier("U" + shortClassName.identifier))
private fun String.reflectId() = ClassId(StandardClassIds.BASE_REFLECT_PACKAGE, Name.identifier(this))
private fun Name.primitiveArrayId() = ClassId(StandardClassIds.Array.packageFqName, Name.identifier(identifier + StandardClassIds.Array.shortClassName.identifier))
private fun String.collectionsId() = ClassId(StandardClassIds.BASE_COLLECTIONS_PACKAGE, Name.identifier(this))
private fun String.annotationId() = ClassId(StandardClassIds.BASE_ANNOTATION_PACKAGE, Name.identifier(this))
private fun String.jvmId() = ClassId(StandardClassIds.BASE_JVM_PACKAGE, Name.identifier(this))
private fun String.jvmInternalId() = ClassId(StandardClassIds.BASE_JVM_INTERNAL_PACKAGE, Name.identifier(this))
private fun String.internalId() = ClassId(StandardClassIds.BASE_INTERNAL_PACKAGE, Name.identifier(this))
private fun String.internalIrId() = ClassId(StandardClassIds.BASE_INTERNAL_IR_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))
private fun <K, V> Map<K, V>.inverseMap(): Map<V, K> = entries.associate { (k, v) -> v to k }
@@ -13,8 +13,6 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.annotations.createDeprecatedAnnotation import org.jetbrains.kotlin.descriptors.annotations.createDeprecatedAnnotation
import org.jetbrains.kotlin.descriptors.impl.* import org.jetbrains.kotlin.descriptors.impl.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor
@@ -34,7 +32,6 @@ import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationDesc
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.IMPL_NAME import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.IMPL_NAME
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.SERIALIZER_CLASS_NAME import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.SERIALIZER_CLASS_NAME
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.typeArgPrefix import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.typeArgPrefix
import java.util.*
object KSerializerDescriptorResolver { object KSerializerDescriptorResolver {
@@ -530,7 +527,7 @@ object KSerializerDescriptorResolver {
else this.makeNullable() else this.makeNullable()
fun createWriteSelfFunctionDescriptor(thisClass: ClassDescriptor): SimpleFunctionDescriptor { fun createWriteSelfFunctionDescriptor(thisClass: ClassDescriptor): SimpleFunctionDescriptor {
val jvmStaticClass = thisClass.module.findClassAcrossModuleDependencies(StandardClassIds.JvmStatic)!! val jvmStaticClass = thisClass.module.findClassAcrossModuleDependencies(StandardClassIds.Annotations.JvmStatic)!!
val jvmStaticAnnotation = AnnotationDescriptorImpl(jvmStaticClass.defaultType, mapOf(), jvmStaticClass.source) val jvmStaticAnnotation = AnnotationDescriptorImpl(jvmStaticClass.defaultType, mapOf(), jvmStaticClass.source)
val annotations = Annotations.create(listOf(jvmStaticAnnotation)) val annotations = Annotations.create(listOf(jvmStaticAnnotation))