diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLoadK1CompiledKotlinGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLoadK1CompiledKotlinGenerated.java index d21f79f39ca..3156acf1d72 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLoadK1CompiledKotlinGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLoadK1CompiledKotlinGenerated.java @@ -3216,6 +3216,12 @@ public class FirLoadK1CompiledKotlinGenerated extends AbstractFirLoadK1CompiledK KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("annotationClassDefaultValues.kt") + public void testAnnotationClassDefaultValues() throws Exception { + runTest("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/annotationClassDefaultValues.kt"); + } + @Test @TestMetadata("AnnotationInAnnotationArguments.kt") public void testAnnotationInAnnotationArguments() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLoadK2CompiledKotlinGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLoadK2CompiledKotlinGenerated.java index e647b196cca..3837f33eab0 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLoadK2CompiledKotlinGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLoadK2CompiledKotlinGenerated.java @@ -3216,6 +3216,12 @@ public class FirLoadK2CompiledKotlinGenerated extends AbstractFirLoadK2CompiledK KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("annotationClassDefaultValues.kt") + public void testAnnotationClassDefaultValues() throws Exception { + runTest("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/annotationClassDefaultValues.kt"); + } + @Test @TestMetadata("AnnotationInAnnotationArguments.kt") public void testAnnotationInAnnotationArguments() throws Exception { diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt index 168392138c0..c06bd239b93 100644 --- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt @@ -164,6 +164,15 @@ abstract class AbstractAnnotationDeserializer( ): List { return emptyList() } + open fun loadAnnotationPropertyDefaultValue( + containerSource: DeserializedContainerSource?, + propertyProto: ProtoBuf.Property, + expectedPropertyType: FirTypeRef, + nameResolver: NameResolver, + typeTable: TypeTable + ): FirExpression? { + return null + } abstract fun loadTypeAnnotations(typeProto: ProtoBuf.Type, nameResolver: NameResolver): List diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirEnumEntryDeserializerAccessUtil.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirEnumEntryDeserializerAccessUtil.kt new file mode 100644 index 00000000000..885e3a98b37 --- /dev/null +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirEnumEntryDeserializerAccessUtil.kt @@ -0,0 +1,51 @@ +/* + * 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.deserialization + +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.utils.isStatic +import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic +import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind +import org.jetbrains.kotlin.fir.expressions.FirEnumEntryDeserializedAccessExpression +import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression +import org.jetbrains.kotlin.fir.expressions.builder.buildPropertyAccessExpression +import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference +import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference +import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredPropertySymbols +import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider +import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef +import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl +import org.jetbrains.kotlin.fir.types.toLookupTag + +fun FirEnumEntryDeserializedAccessExpression.toQualifiedPropertyAccessExpression(session: FirSession): FirPropertyAccessExpression = + buildPropertyAccessExpression { + val entryPropertySymbol = session.symbolProvider.getClassDeclaredPropertySymbols( + enumClassId, enumEntryName, + ).firstOrNull { it.isStatic } + + calleeReference = when { + entryPropertySymbol != null -> { + buildResolvedNamedReference { + this.name = enumEntryName + resolvedSymbol = entryPropertySymbol + } + } + else -> { + buildErrorNamedReference { + diagnostic = ConeSimpleDiagnostic( + "Strange deserialized enum value: $enumClassId.$enumEntryName", + DiagnosticKind.Java, + ) + } + } + } + + typeRef = buildResolvedTypeRef { + type = ConeClassLikeTypeImpl( + enumClassId.toLookupTag(), emptyArray(), isNullable = false + ) + } + } diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt index ef43c7c5bba..fec6a010ca2 100644 --- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt @@ -448,7 +448,20 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { ) } this.containerSource = c.containerSource - this.initializer = c.constDeserializer.loadConstant(proto, symbol.callableId, c.nameResolver) + this.initializer = when { + Flags.HAS_CONSTANT.get(proto.flags) -> c.constDeserializer.loadConstant(proto, symbol.callableId, c.nameResolver) + // classSymbol?.classKind?.isAnnotationClass throws 'Fir is not initialized for FirRegularClassSymbol kotlin/String' + classProto != null && Flags.CLASS_KIND.get(classProto.flags) == ProtoBuf.Class.Kind.ANNOTATION_CLASS -> { + c.annotationDeserializer.loadAnnotationPropertyDefaultValue( + c.containerSource, + proto, + returnTypeRef, + local.nameResolver, + local.typeTable + ) + } + else -> null + } deprecationsProvider = annotations.getDeprecationsProviderFromAnnotations(c.session, fromJava = false) proto.contextReceiverTypes(c.typeTable).mapTo(contextReceivers, ::loadContextReceiver) diff --git a/compiler/fir/fir2ir/build.gradle.kts b/compiler/fir/fir2ir/build.gradle.kts index ad8b76cc95c..9c2cbfc5b0d 100644 --- a/compiler/fir/fir2ir/build.gradle.kts +++ b/compiler/fir/fir2ir/build.gradle.kts @@ -17,6 +17,7 @@ dependencies { compileOnly(project(":compiler:ir.backend.common")) compileOnly(project(":compiler:ir.serialization.common")) compileOnly(project(":compiler:fir:fir-serialization")) + compileOnly(project(":compiler:fir:fir-deserialization")) compileOnly(intellijCore()) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index 937a490bacd..2968bf9470e 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType import org.jetbrains.kotlin.fir.declarations.utils.isSealed import org.jetbrains.kotlin.fir.declarations.utils.isSynthetic import org.jetbrains.kotlin.fir.declarations.utils.visibility +import org.jetbrains.kotlin.fir.deserialization.toQualifiedPropertyAccessExpression import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.FirContractCallBlock import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition @@ -952,6 +953,13 @@ class Fir2IrVisitor( } } + override fun visitEnumEntryDeserializedAccessExpression( + enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression, + data: Any? + ): IrElement { + return visitPropertyAccessExpression(enumEntryDeserializedAccessExpression.toQualifiedPropertyAccessExpression(session), data) + } + override fun visitElvisExpression(elvisExpression: FirElvisExpression, data: Any?): IrElement { val firLhsVariable = buildProperty { source = elvisExpression.source diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt index b81cd1c0d7a..2ae4e416dd2 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.lazy import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.descriptors.isAnnotationClass import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter @@ -21,6 +22,7 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar import org.jetbrains.kotlin.ir.expressions.IrConstructorCall +import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpressionBody import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.types.IrErrorType @@ -32,7 +34,7 @@ import org.jetbrains.kotlin.name.NameUtils import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource class Fir2IrLazyProperty( - components: Fir2IrComponents, + private val components: Fir2IrComponents, override val startOffset: Int, override val endOffset: Int, override var origin: IrDeclarationOrigin, @@ -93,12 +95,22 @@ class Fir2IrLazyProperty( } private fun toIrInitializer(initializer: FirExpression?): IrExpressionBody? { - return if (initializer is FirConstExpression<*>) { - // TODO: Normally we shouldn't have error type here - val constType = with(typeConverter) { initializer.typeRef.toIrType().takeIf { it !is IrErrorType } ?: type } - factory.createExpressionBody(initializer.toIrConst(constType)) - } else { - null + // Annotations need full initializer information to instantiate them correctly + return when { + containingClass?.classKind?.isAnnotationClass == true -> { + when (val elem = initializer?.accept(Fir2IrVisitor(components, Fir2IrConversionScope()), null)) { + is IrExpressionBody -> elem + is IrExpression -> factory.createExpressionBody(elem) + else -> null + } + } + // Setting initializers to every other class causes some cryptic errors in lowerings + initializer is FirConstExpression<*> -> { + // TODO: Normally we shouldn't have error type here + val constType = with(typeConverter) { initializer.typeRef.toIrType().takeIf { it !is IrErrorType } ?: type } + factory.createExpressionBody(initializer.toIrConst(constType)) + } + else -> null } } 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 3d716554f52..66215d7faf9 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 @@ -61,12 +61,12 @@ internal fun Any?.createConstantOrError(session: FirSession): FirExpression { } } -internal fun Any?.createConstantIfAny(session: FirSession): FirExpression? { +internal fun Any?.createConstantIfAny(session: FirSession, unsigned: Boolean = false): FirExpression? { return when (this) { - is Byte -> buildConstExpression(null, ConstantValueKind.Byte, this).setProperType(session) - is Short -> buildConstExpression(null, ConstantValueKind.Short, this).setProperType(session) - is Int -> buildConstExpression(null, ConstantValueKind.Int, this).setProperType(session) - is Long -> buildConstExpression(null, ConstantValueKind.Long, this).setProperType(session) + is Byte -> buildConstExpression(null, if (unsigned) ConstantValueKind.UnsignedByte else ConstantValueKind.Byte, this).setProperType(session) + is Short -> buildConstExpression(null, if (unsigned) ConstantValueKind.UnsignedShort else ConstantValueKind.Short, this).setProperType(session) + is Int -> buildConstExpression(null, if (unsigned) ConstantValueKind.UnsignedInt else ConstantValueKind.Int, this).setProperType(session) + is Long -> buildConstExpression(null, if (unsigned) ConstantValueKind.UnsignedLong else ConstantValueKind.Long, this).setProperType(session) is Char -> buildConstExpression(null, ConstantValueKind.Char, this).setProperType(session) is Float -> buildConstExpression(null, ConstantValueKind.Float, this).setProperType(session) is Double -> buildConstExpression(null, ConstantValueKind.Double, this).setProperType(session) diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/AnnotationsLoader.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/AnnotationsLoader.kt index de7b4882a48..5ad4e0aa168 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/AnnotationsLoader.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/AnnotationsLoader.kt @@ -7,157 +7,142 @@ package org.jetbrains.kotlin.fir.java.deserialization import org.jetbrains.kotlin.SpecialJvmAnnotations import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic -import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind +import org.jetbrains.kotlin.fir.deserialization.toQualifiedPropertyAccessExpression import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.* import org.jetbrains.kotlin.fir.java.createConstantOrError import org.jetbrains.kotlin.fir.languageVersionSettings -import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference -import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredPropertySymbols import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef -import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.load.java.JvmAbi -import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder -import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass -import org.jetbrains.kotlin.load.kotlin.findKotlinClass +import org.jetbrains.kotlin.load.kotlin.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.resolve.constants.ClassLiteralValue +import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType import org.jetbrains.kotlin.utils.toMetadataVersion internal class AnnotationsLoader(private val session: FirSession, private val kotlinClassFinder: KotlinClassFinder) { + private abstract inner class AnnotationsLoaderVisitorImpl(val enumEntryReferenceCreator: (ClassId, Name) -> FirExpression) : KotlinJvmBinaryClass.AnnotationArgumentVisitor { + abstract fun visitExpression(name: Name?, expr: FirExpression) + + abstract val visitNullNames: Boolean + + abstract fun guessArrayTypeIfNeeded(name: Name?, arrayOfElements: List): FirTypeRef? + + override fun visit(name: Name?, value: Any?) { + visitExpression(name, createConstant(value)) + } + + private fun ClassLiteralValue.toFirClassReferenceExpression(): FirClassReferenceExpression { + val resolvedClassTypeRef = classId.toLookupTag().toDefaultResolvedTypeRef() + return buildClassReferenceExpression { + classTypeRef = resolvedClassTypeRef + typeRef = buildResolvedTypeRef { + type = StandardClassIds.KClass.constructClassLikeType(arrayOf(resolvedClassTypeRef.type), false) + } + } + } + + override fun visitClassLiteral(name: Name?, value: ClassLiteralValue) { + visitExpression(name, buildGetClassCall { + val argument = value.toFirClassReferenceExpression() + argumentList = buildUnaryArgumentList(argument) + typeRef = argument.typeRef + }) + } + + override fun visitEnum(name: Name?, enumClassId: ClassId, enumEntryName: Name) { + if (name == null && !visitNullNames) return + visitExpression(name, enumEntryReferenceCreator(enumClassId, enumEntryName)) + } + + override fun visitArray(name: Name?): KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor? { + if (name == null && !visitNullNames) return null + return object : KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor { + private val elements = mutableListOf() + + override fun visit(value: Any?) { + elements.add(createConstant(value)) + } + + override fun visitEnum(enumClassId: ClassId, enumEntryName: Name) { + elements.add(enumEntryReferenceCreator(enumClassId, enumEntryName)) + } + + override fun visitClassLiteral(value: ClassLiteralValue) { + elements.add(buildGetClassCall { + val argument = value.toFirClassReferenceExpression() + argumentList = buildUnaryArgumentList(argument) + typeRef = argument.typeRef + }) + } + + override fun visitAnnotation(classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor { + val list = mutableListOf() + val visitor = loadAnnotation(classId, list, enumEntryReferenceCreator) + return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor { + override fun visitEnd() { + visitor.visitEnd() + elements.add(list.single()) + } + } + } + + override fun visitEnd() { + visitExpression(name, buildArrayOfCall { + guessArrayTypeIfNeeded(name, elements)?.let { typeRef = it } + argumentList = buildArgumentList { + arguments += elements + } + }) + } + } + } + + override fun visitAnnotation(name: Name?, classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { + if (name == null && !visitNullNames) return null + val list = mutableListOf() + val visitor = loadAnnotation(classId, list, enumEntryReferenceCreator) + return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor { + override fun visitEnd() { + visitor.visitEnd() + visitExpression(name, list.single()) + } + } + } + + private fun createConstant(value: Any?): FirExpression { + return value.createConstantOrError(session) + } + } + private fun loadAnnotation( - annotationClassId: ClassId, result: MutableList, + annotationClassId: ClassId, result: MutableList, enumEntryReferenceCreator: (ClassId, Name) -> FirExpression ): KotlinJvmBinaryClass.AnnotationArgumentVisitor { val lookupTag = annotationClassId.toLookupTag() - return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor { + return object : AnnotationsLoaderVisitorImpl(enumEntryReferenceCreator) { private val argumentMap = mutableMapOf() - override fun visit(name: Name?, value: Any?) { - if (name != null) { - argumentMap[name] = createConstant(value) - } + override fun visitExpression(name: Name?, expr: FirExpression) { + if (name != null) argumentMap[name] = expr } - private fun ClassLiteralValue.toFirClassReferenceExpression(): FirClassReferenceExpression { - val resolvedClassTypeRef = classId.toLookupTag().toDefaultResolvedTypeRef() - return buildClassReferenceExpression { - classTypeRef = resolvedClassTypeRef - typeRef = buildResolvedTypeRef { - type = StandardClassIds.KClass.constructClassLikeType(arrayOf(resolvedClassTypeRef.type), false) - } - } - } + override val visitNullNames: Boolean = false - private fun ClassId.toEnumEntryReferenceExpression(name: Name): FirExpression { - return buildPropertyAccessExpression { - val entryPropertySymbol = - session.symbolProvider.getClassDeclaredPropertySymbols( - this@toEnumEntryReferenceExpression, name, - ).firstOrNull() - - calleeReference = when { - entryPropertySymbol != null -> { - buildResolvedNamedReference { - this.name = name - resolvedSymbol = entryPropertySymbol - } - } - else -> { - buildErrorNamedReference { - diagnostic = ConeSimpleDiagnostic( - "Strange deserialized enum value: ${this@toEnumEntryReferenceExpression}.$name", - DiagnosticKind.Java, - ) - } - } - } - - typeRef = buildResolvedTypeRef { - type = ConeClassLikeTypeImpl( - this@toEnumEntryReferenceExpression.toLookupTag(), - emptyArray(), - isNullable = false - ) - } - } - } - - override fun visitClassLiteral(name: Name?, value: ClassLiteralValue) { - if (name == null) return - argumentMap[name] = buildGetClassCall { - val argument = value.toFirClassReferenceExpression() - argumentList = buildUnaryArgumentList(argument) - typeRef = argument.typeRef - } - } - - override fun visitEnum(name: Name?, enumClassId: ClassId, enumEntryName: Name) { - if (name == null) return - argumentMap[name] = enumClassId.toEnumEntryReferenceExpression(enumEntryName) - } - - override fun visitArray(name: Name?): KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor? { + override fun guessArrayTypeIfNeeded(name: Name?, arrayOfElements: List): FirTypeRef? { + // Needed if we load a default value which is another annotation that has array value in it. e.g.: + // To instantiate Deprecated() we need a default value for ReplaceWith() that has imports: Array with default value []. if (name == null) return null - return object : KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor { - private val elements = mutableListOf() - - override fun visit(value: Any?) { - elements.add(createConstant(value)) - } - - override fun visitEnum(enumClassId: ClassId, enumEntryName: Name) { - elements.add(enumClassId.toEnumEntryReferenceExpression(enumEntryName)) - } - - override fun visitClassLiteral(value: ClassLiteralValue) { - elements.add( - buildGetClassCall { - val argument = value.toFirClassReferenceExpression() - argumentList = buildUnaryArgumentList(argument) - typeRef = argument.typeRef - } - ) - } - - override fun visitAnnotation(classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor { - val list = mutableListOf() - val visitor = loadAnnotation(classId, list) - return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor { - override fun visitEnd() { - visitor.visitEnd() - elements.add(list.single()) - } - } - } - - override fun visitEnd() { - argumentMap[name] = buildArrayOfCall { - argumentList = buildArgumentList { - arguments += elements - } - } - } - } - } - - override fun visitAnnotation(name: Name?, classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { - if (name == null) return null - val list = mutableListOf() - val visitor = loadAnnotation(classId, list) - return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor { - override fun visitEnd() { - visitor.visitEnd() - argumentMap[name] = list.single() - } - } + // Note: generally we are not allowed to resolve anything, as this is might lead to recursive resolve problems + // However, K1 deserializer did exactly the same and no issues were reported. + val propS = session.symbolProvider.getClassDeclaredPropertySymbols(annotationClassId, name).firstOrNull() + return propS?.resolvedReturnTypeRef } override fun visitEnd() { @@ -173,9 +158,35 @@ internal class AnnotationsLoader(private val session: FirSession, private val ko } } } + } + } - private fun createConstant(value: Any?): FirExpression { - return value.createConstantOrError(session) + internal fun loadAnnotationMethodDefaultValue( + methodSignature: MemberSignature, + consumeResult: (FirExpression) -> Unit + ): KotlinJvmBinaryClass.AnnotationArgumentVisitor { + return object : AnnotationsLoaderVisitorImpl(this::toEnumEntryReferenceExpressionUnresolved) { + var defaultValue: FirExpression? = null + + override fun visitExpression(name: Name?, expr: FirExpression) { + defaultValue = expr + } + + override val visitNullNames: Boolean = true + + override fun guessArrayTypeIfNeeded(name: Name?, arrayOfElements: List): FirTypeRef { + val descName = methodSignature.signature.substringAfterLast(')').removePrefix("[") + val targetClassId = JvmPrimitiveType.getByDesc(descName)?.primitiveType?.typeFqName?.let { ClassId.topLevel(it) } + ?: FileBasedKotlinClass.resolveNameByInternalName( + descName.removePrefix("L").removeSuffix(";"), + // It seems that some inner classes info is required, but so far there are no problems with them (see six() in multimoduleCreation test) + FileBasedKotlinClass.InnerClassesInfo() + ) + return targetClassId.toLookupTag().constructClassType(arrayOf(), false).createOutArrayType().toFirResolvedTypeRef() + } + + override fun visitEnd() { + defaultValue?.let(consumeResult) } } } @@ -187,8 +198,7 @@ internal class AnnotationsLoader(private val session: FirSession, private val ko val classReference = getClassCall.argument as? FirClassReferenceExpression ?: return false val containerType = classReference.classTypeRef.coneType as? ConeClassLikeType ?: return false val classId = containerType.lookupTag.classId - if (classId.outerClassId == null || - classId.shortClassName.asString() != JvmAbi.REPEATABLE_ANNOTATION_CONTAINER_NAME + if (classId.outerClassId == null || classId.shortClassName.asString() != JvmAbi.REPEATABLE_ANNOTATION_CONTAINER_NAME ) return false val klass = kotlinClassFinder.findKotlinClass(classId, session.languageVersionSettings.languageVersion.toMetadataVersion()) @@ -199,11 +209,21 @@ internal class AnnotationsLoader(private val session: FirSession, private val ko annotationClassId: ClassId, result: MutableList, ): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { if (annotationClassId in SpecialJvmAnnotations.SPECIAL_ANNOTATIONS) return null - return loadAnnotation(annotationClassId, result) + // Note: we shouldn't resolve enum entries here either: KT-58294 + return loadAnnotation(annotationClassId, result, this::toEnumEntryReferenceExpressionWithResolve) } private fun ConeClassLikeLookupTag.toDefaultResolvedTypeRef(): FirResolvedTypeRef = buildResolvedTypeRef { type = constructClassType(emptyArray(), isNullable = false) } + + private fun toEnumEntryReferenceExpressionWithResolve(classId: ClassId, name: Name): FirPropertyAccessExpression = + toEnumEntryReferenceExpressionUnresolved(classId, name).toQualifiedPropertyAccessExpression(session) + + private fun toEnumEntryReferenceExpressionUnresolved(classId: ClassId, name: Name): FirEnumEntryDeserializedAccessExpression = + buildEnumEntryDeserializedAccessExpression { + enumClassId = classId + enumEntryName = name + } } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmBinaryAnnotationDeserializer.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmBinaryAnnotationDeserializer.kt index 719b53b1caa..d7f556f3cd5 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmBinaryAnnotationDeserializer.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmBinaryAnnotationDeserializer.kt @@ -10,10 +10,19 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.deserialization.AbstractAnnotationDeserializer import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.fir.expressions.FirConstExpression +import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotation +import org.jetbrains.kotlin.fir.java.createConstantIfAny import org.jetbrains.kotlin.fir.languageVersionSettings +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.types.coneType +import org.jetbrains.kotlin.fir.types.isUnsignedType import org.jetbrains.kotlin.load.java.JvmAbi -import org.jetbrains.kotlin.load.kotlin.* +import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder +import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass +import org.jetbrains.kotlin.load.kotlin.MemberSignature +import org.jetbrains.kotlin.load.kotlin.getPropertySignature import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.deserialization.* import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf @@ -24,6 +33,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.protobuf.MessageLite import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource +import org.jetbrains.kotlin.types.ConstantValueKind import org.jetbrains.kotlin.utils.addToStdlib.runIf import org.jetbrains.kotlin.utils.toMetadataVersion @@ -197,6 +207,24 @@ class JvmBinaryAnnotationDeserializer( return findJvmBinaryClassAndLoadMemberAnnotations(paramSignature) } + override fun loadAnnotationPropertyDefaultValue( + containerSource: DeserializedContainerSource?, + propertyProto: ProtoBuf.Property, + expectedPropertyType: FirTypeRef, + nameResolver: NameResolver, + typeTable: TypeTable + ): FirExpression? { + val signature = getCallableSignature(propertyProto, nameResolver, typeTable, CallableKind.PROPERTY_GETTER) ?: return null + val firExpr = annotationInfo.annotationMethodsDefaultValues[signature] + return if (firExpr is FirConstExpression<*> && expectedPropertyType.coneType.isUnsignedType && firExpr.kind.isSignedNumber) + firExpr.value.createConstantIfAny(session, unsigned = true) + else + firExpr + } + + private val ConstantValueKind.isSignedNumber: Boolean + get() = this is ConstantValueKind.Byte || this is ConstantValueKind.Short || this is ConstantValueKind.Int || this is ConstantValueKind.Long + private fun computeJvmParameterIndexShift(classProto: ProtoBuf.Class?, message: MessageLite): Int { return when (message) { is ProtoBuf.Function -> if (message.hasReceiver()) 1 else 0 @@ -268,7 +296,10 @@ class JvmBinaryAnnotationDeserializer( } // TODO: Rename this once property constants are recorded as well -private data class MemberAnnotations(val memberAnnotations: MutableMap>) +private data class MemberAnnotations( + val memberAnnotations: MutableMap>, + val annotationMethodsDefaultValues: Map +) // TODO: better to be in KotlinDeserializedJvmSymbolsProvider? private fun FirSession.loadMemberAnnotations( @@ -278,6 +309,7 @@ private fun FirSession.loadMemberAnnotations( ): MemberAnnotations { val memberAnnotations = hashMapOf>() val annotationsLoader = AnnotationsLoader(this, kotlinClassFinder) + val annotationMethodsDefaultValues = hashMapOf() kotlinBinaryClass.visitMembers(object : KotlinJvmBinaryClass.MemberVisitor { override fun visitMethod(name: Name, desc: String): KotlinJvmBinaryClass.MethodAnnotationVisitor { @@ -288,6 +320,7 @@ private fun FirSession.loadMemberAnnotations( val signature = MemberSignature.fromFieldNameAndDesc(name.asString(), desc) if (initializer != null) { // TODO: load constant + // TODO: Given there is FirConstDeserializer, maybe this comment is obsolete? } return MemberAnnotationVisitor(signature) } @@ -310,8 +343,7 @@ private fun FirSession.loadMemberAnnotations( } override fun visitAnnotationMemberDefaultValue(): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { - // TODO: load annotation default values to properly support annotation instantiation feature - return null + return annotationsLoader.loadAnnotationMethodDefaultValue(signature) { annotationMethodsDefaultValues[signature] = it } } } @@ -330,5 +362,9 @@ private fun FirSession.loadMemberAnnotations( } }, byteContent) - return MemberAnnotations(memberAnnotations) + + return MemberAnnotations( + memberAnnotations, + annotationMethodsDefaultValues + ) } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirEnumEntryDeserializedAccessExpression.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirEnumEntryDeserializedAccessExpression.kt new file mode 100644 index 00000000000..8265aefa6fd --- /dev/null +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirEnumEntryDeserializedAccessExpression.kt @@ -0,0 +1,38 @@ +/* + * 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.expressions + +import org.jetbrains.kotlin.KtSourceElement +import org.jetbrains.kotlin.fir.FirElement +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.fir.visitors.* + +/* + * This file was generated automatically + * DO NOT MODIFY IT MANUALLY + */ + +abstract class FirEnumEntryDeserializedAccessExpression : FirExpression() { + abstract override val source: KtSourceElement? + abstract override val typeRef: FirTypeRef + abstract override val annotations: List + abstract val enumClassId: ClassId + abstract val enumEntryName: Name + + override fun accept(visitor: FirVisitor, data: D): R = visitor.visitEnumEntryDeserializedAccessExpression(this, data) + + @Suppress("UNCHECKED_CAST") + override fun transform(transformer: FirTransformer, data: D): E = + transformer.transformEnumEntryDeserializedAccessExpression(this, data) as E + + abstract override fun replaceTypeRef(newTypeRef: FirTypeRef) + + abstract override fun replaceAnnotations(newAnnotations: List) + + abstract override fun transformAnnotations(transformer: FirTransformer, data: D): FirEnumEntryDeserializedAccessExpression +} diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirEnumEntryDeserializedAccessExpressionBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirEnumEntryDeserializedAccessExpressionBuilder.kt new file mode 100644 index 00000000000..477f5d2c0d7 --- /dev/null +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirEnumEntryDeserializedAccessExpressionBuilder.kt @@ -0,0 +1,67 @@ +/* + * 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. + */ + +@file:Suppress("DuplicatedCode") + +package org.jetbrains.kotlin.fir.expressions.builder + +import kotlin.contracts.* +import org.jetbrains.kotlin.KtSourceElement +import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder +import org.jetbrains.kotlin.fir.builder.FirBuilderDsl +import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty +import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.fir.expressions.FirEnumEntryDeserializedAccessExpression +import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder +import org.jetbrains.kotlin.fir.expressions.impl.FirEnumEntryDeserializedAccessExpressionImpl +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef +import org.jetbrains.kotlin.fir.types.constructClassType +import org.jetbrains.kotlin.fir.types.toLookupTag +import org.jetbrains.kotlin.fir.visitors.* +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.Name + +/* + * This file was generated automatically + * DO NOT MODIFY IT MANUALLY + */ + +@FirBuilderDsl +class FirEnumEntryDeserializedAccessExpressionBuilder : FirAnnotationContainerBuilder, FirExpressionBuilder { + override val annotations: MutableList = mutableListOf() + lateinit var enumClassId: ClassId + lateinit var enumEntryName: Name + + override fun build(): FirEnumEntryDeserializedAccessExpression { + return FirEnumEntryDeserializedAccessExpressionImpl( + annotations.toMutableOrEmpty(), + enumClassId, + enumEntryName, + ) + } + + @Deprecated("Modification of 'source' has no impact for FirEnumEntryDeserializedAccessExpressionBuilder", level = DeprecationLevel.HIDDEN) + override var source: KtSourceElement? + get() = throw IllegalStateException() + set(_) { + throw IllegalStateException() + } + + @Deprecated("Modification of 'typeRef' has no impact for FirEnumEntryDeserializedAccessExpressionBuilder", level = DeprecationLevel.HIDDEN) + override var typeRef: FirTypeRef + get() = throw IllegalStateException() + set(_) { + throw IllegalStateException() + } +} + +@OptIn(ExperimentalContracts::class) +inline fun buildEnumEntryDeserializedAccessExpression(init: FirEnumEntryDeserializedAccessExpressionBuilder.() -> Unit): FirEnumEntryDeserializedAccessExpression { + contract { + callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE) + } + return FirEnumEntryDeserializedAccessExpressionBuilder().apply(init).build() +} diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirEnumEntryDeserializedAccessExpressionImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirEnumEntryDeserializedAccessExpressionImpl.kt new file mode 100644 index 00000000000..68652ae6b39 --- /dev/null +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirEnumEntryDeserializedAccessExpressionImpl.kt @@ -0,0 +1,59 @@ +/* + * 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. + */ + +@file:Suppress("DuplicatedCode") + +package org.jetbrains.kotlin.fir.expressions.impl + +import org.jetbrains.kotlin.KtSourceElement +import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.fir.expressions.FirEnumEntryDeserializedAccessExpression +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef +import org.jetbrains.kotlin.fir.types.constructClassType +import org.jetbrains.kotlin.fir.types.toLookupTag +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.fir.visitors.* +import org.jetbrains.kotlin.fir.MutableOrEmptyList +import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty + +/* + * This file was generated automatically + * DO NOT MODIFY IT MANUALLY + */ + +internal class FirEnumEntryDeserializedAccessExpressionImpl( + override var annotations: MutableOrEmptyList, + override val enumClassId: ClassId, + override val enumEntryName: Name, +) : FirEnumEntryDeserializedAccessExpression() { + override val source: KtSourceElement? get() = null + override var typeRef: FirTypeRef = buildResolvedTypeRef { type = enumClassId.toLookupTag().constructClassType(emptyArray(), false) } + + override fun acceptChildren(visitor: FirVisitor, data: D) { + typeRef.accept(visitor, data) + annotations.forEach { it.accept(visitor, data) } + } + + override fun transformChildren(transformer: FirTransformer, data: D): FirEnumEntryDeserializedAccessExpressionImpl { + typeRef = typeRef.transform(transformer, data) + transformAnnotations(transformer, data) + return this + } + + override fun transformAnnotations(transformer: FirTransformer, data: D): FirEnumEntryDeserializedAccessExpressionImpl { + annotations.transformInplace(transformer, data) + return this + } + + override fun replaceTypeRef(newTypeRef: FirTypeRef) { + typeRef = newTypeRef + } + + override fun replaceAnnotations(newAnnotations: List) { + annotations = newAnnotations.toMutableOrEmpty() + } +} diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitor.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitor.kt index f1f7fa8d6a1..c77e4bc6b7b 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitor.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitor.kt @@ -128,6 +128,7 @@ import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment import org.jetbrains.kotlin.fir.expressions.FirWhenSubjectExpression import org.jetbrains.kotlin.fir.expressions.FirDesugaredAssignmentValueReferenceExpression import org.jetbrains.kotlin.fir.expressions.FirWrappedDelegateExpression +import org.jetbrains.kotlin.fir.expressions.FirEnumEntryDeserializedAccessExpression import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.references.FirNamedReferenceWithCandidateBase import org.jetbrains.kotlin.fir.references.FirErrorNamedReference @@ -279,6 +280,8 @@ abstract class FirDefaultVisitor : FirVisitor() { override fun visitWrappedDelegateExpression(wrappedDelegateExpression: FirWrappedDelegateExpression, data: D): R = visitWrappedExpression(wrappedDelegateExpression, data) + override fun visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression, data: D): R = visitExpression(enumEntryDeserializedAccessExpression, data) + override fun visitNamedReference(namedReference: FirNamedReference, data: D): R = visitReference(namedReference, data) override fun visitNamedReferenceWithCandidateBase(namedReferenceWithCandidateBase: FirNamedReferenceWithCandidateBase, data: D): R = visitNamedReference(namedReferenceWithCandidateBase, data) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitorVoid.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitorVoid.kt index 215d987d6c5..27661ddb2de 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitorVoid.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitorVoid.kt @@ -128,6 +128,7 @@ import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment import org.jetbrains.kotlin.fir.expressions.FirWhenSubjectExpression import org.jetbrains.kotlin.fir.expressions.FirDesugaredAssignmentValueReferenceExpression import org.jetbrains.kotlin.fir.expressions.FirWrappedDelegateExpression +import org.jetbrains.kotlin.fir.expressions.FirEnumEntryDeserializedAccessExpression import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.references.FirNamedReferenceWithCandidateBase import org.jetbrains.kotlin.fir.references.FirErrorNamedReference @@ -279,6 +280,8 @@ abstract class FirDefaultVisitorVoid : FirVisitorVoid() { override fun visitWrappedDelegateExpression(wrappedDelegateExpression: FirWrappedDelegateExpression) = visitWrappedExpression(wrappedDelegateExpression) + override fun visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression) = visitExpression(enumEntryDeserializedAccessExpression) + override fun visitNamedReference(namedReference: FirNamedReference) = visitReference(namedReference) override fun visitNamedReferenceWithCandidateBase(namedReferenceWithCandidateBase: FirNamedReferenceWithCandidateBase) = visitNamedReference(namedReferenceWithCandidateBase) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirTransformer.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirTransformer.kt index 8bd4e9bf562..afa10b3225d 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirTransformer.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirTransformer.kt @@ -128,6 +128,7 @@ import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment import org.jetbrains.kotlin.fir.expressions.FirWhenSubjectExpression import org.jetbrains.kotlin.fir.expressions.FirDesugaredAssignmentValueReferenceExpression import org.jetbrains.kotlin.fir.expressions.FirWrappedDelegateExpression +import org.jetbrains.kotlin.fir.expressions.FirEnumEntryDeserializedAccessExpression import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.references.FirNamedReferenceWithCandidateBase import org.jetbrains.kotlin.fir.references.FirErrorNamedReference @@ -652,6 +653,10 @@ abstract class FirTransformer : FirVisitor() { return transformElement(wrappedDelegateExpression, data) } + open fun transformEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression, data: D): FirStatement { + return transformElement(enumEntryDeserializedAccessExpression, data) + } + open fun transformNamedReference(namedReference: FirNamedReference, data: D): FirReference { return transformElement(namedReference, data) } @@ -1248,6 +1253,10 @@ abstract class FirTransformer : FirVisitor() { return transformWrappedDelegateExpression(wrappedDelegateExpression, data) } + final override fun visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression, data: D): FirStatement { + return transformEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression, data) + } + final override fun visitNamedReference(namedReference: FirNamedReference, data: D): FirReference { return transformNamedReference(namedReference, data) } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitor.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitor.kt index 0b89adcd31e..694f11b6ce4 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitor.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitor.kt @@ -128,6 +128,7 @@ import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment import org.jetbrains.kotlin.fir.expressions.FirWhenSubjectExpression import org.jetbrains.kotlin.fir.expressions.FirDesugaredAssignmentValueReferenceExpression import org.jetbrains.kotlin.fir.expressions.FirWrappedDelegateExpression +import org.jetbrains.kotlin.fir.expressions.FirEnumEntryDeserializedAccessExpression import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.references.FirNamedReferenceWithCandidateBase import org.jetbrains.kotlin.fir.references.FirErrorNamedReference @@ -407,6 +408,8 @@ abstract class FirVisitor { open fun visitWrappedDelegateExpression(wrappedDelegateExpression: FirWrappedDelegateExpression, data: D): R = visitElement(wrappedDelegateExpression, data) + open fun visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression, data: D): R = visitElement(enumEntryDeserializedAccessExpression, data) + open fun visitNamedReference(namedReference: FirNamedReference, data: D): R = visitElement(namedReference, data) open fun visitNamedReferenceWithCandidateBase(namedReferenceWithCandidateBase: FirNamedReferenceWithCandidateBase, data: D): R = visitElement(namedReferenceWithCandidateBase, data) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitorVoid.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitorVoid.kt index 96b5253b745..dfb5f6a5530 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitorVoid.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitorVoid.kt @@ -128,6 +128,7 @@ import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment import org.jetbrains.kotlin.fir.expressions.FirWhenSubjectExpression import org.jetbrains.kotlin.fir.expressions.FirDesugaredAssignmentValueReferenceExpression import org.jetbrains.kotlin.fir.expressions.FirWrappedDelegateExpression +import org.jetbrains.kotlin.fir.expressions.FirEnumEntryDeserializedAccessExpression import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.references.FirNamedReferenceWithCandidateBase import org.jetbrains.kotlin.fir.references.FirErrorNamedReference @@ -651,6 +652,10 @@ abstract class FirVisitorVoid : FirVisitor() { visitElement(wrappedDelegateExpression) } + open fun visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression) { + visitElement(enumEntryDeserializedAccessExpression) + } + open fun visitNamedReference(namedReference: FirNamedReference) { visitElement(namedReference) } @@ -1247,6 +1252,10 @@ abstract class FirVisitorVoid : FirVisitor() { visitWrappedDelegateExpression(wrappedDelegateExpression) } + final override fun visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression, data: Nothing?) { + visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression) + } + final override fun visitNamedReference(namedReference: FirNamedReference, data: Nothing?) { visitNamedReference(namedReference) } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt index 03f1edf0a76..648fbdfe3e9 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt @@ -651,6 +651,12 @@ class FirRenderer( wrappedDelegateExpression.expression.accept(this) } + override fun visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression) { + with(enumEntryDeserializedAccessExpression) { + print("$enumClassId.$enumEntryName") + } + } + override fun visitNamedArgumentExpression(namedArgumentExpression: FirNamedArgumentExpression) { print(namedArgumentExpression.name) print(" = ") diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt index 55b013b831e..d6c9e328a5e 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt @@ -156,6 +156,8 @@ object FirTreeBuilder : AbstractFirTreeBuilder() { val wrappedDelegateExpression by element(Expression, wrappedExpression) + val enumEntryDeserializedAccessExpression by element(Expression, expression) + val namedReference by element(Reference, reference) val namedReferenceWithCandidateBase by element(Reference, namedReference) val errorNamedReference by element(Reference, namedReference, diagnosticHolder) diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt index b5540269065..6756f81e3dd 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt @@ -394,6 +394,14 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() } } + impl(enumEntryDeserializedAccessExpression) { + noSource() + default("typeRef") { + value = "buildResolvedTypeRef { type = enumClassId.toLookupTag().constructClassType(emptyArray(), false) }" + useTypes(buildResolvedTypeRefImport, toLookupTagImport, constructClassTypeImport) + } + } + impl(smartCastExpression) { default("isStable") { value = "smartcastStability == SmartcastStability.STABLE_VALUE" diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index d3d382e7567..e0e94e6bd3c 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -644,6 +644,11 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild +field("delegateProvider", expression).withReplace() } + enumEntryDeserializedAccessExpression.configure { + +field("enumClassId", classIdType) + +field("enumEntryName", nameType) + } + namedReference.configure { +name } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/importables.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/importables.kt index b2f5182d072..ad24f1ea228 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/importables.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/importables.kt @@ -10,4 +10,8 @@ import org.jetbrains.kotlin.fir.tree.generator.model.ArbitraryImportable val phaseAsResolveStateExtentionImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations", "asResolveState") val resolvePhaseExtensionImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations", "resolvePhase") val resolveStateAccessImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations", "ResolveStateAccess") -val resolvedDeclarationStatusImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations.impl", "FirResolvedDeclarationStatusImpl") \ No newline at end of file +val resolvedDeclarationStatusImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations.impl", "FirResolvedDeclarationStatusImpl") + +val buildResolvedTypeRefImport = ArbitraryImportable("org.jetbrains.kotlin.fir.types.builder", "buildResolvedTypeRef") +val constructClassTypeImport = ArbitraryImportable("org.jetbrains.kotlin.fir.types", "constructClassType") +val toLookupTagImport = ArbitraryImportable("org.jetbrains.kotlin.fir.types", "toLookupTag") diff --git a/compiler/testData/codegen/box/annotations/instances/multimoduleCreation.kt b/compiler/testData/codegen/box/annotations/instances/multimoduleCreation.kt index 1b949275abd..b329564f863 100644 --- a/compiler/testData/codegen/box/annotations/instances/multimoduleCreation.kt +++ b/compiler/testData/codegen/box/annotations/instances/multimoduleCreation.kt @@ -1,6 +1,3 @@ -// IGNORE_BACKEND_K2: JVM_IR, JS_IR -// FIR status: IllegalStateException: Usage of default value argument for this annotation is not yet possible. -// Please specify value for 'A.kClass' explicitly // TARGET_BACKEND: JVM_IR // IGNORE_DEXING // WITH_STDLIB @@ -26,6 +23,12 @@ annotation class UnsignedValue( val uint: UInt = 2147483657U // Int.MAX_VALUE + 10 ) +annotation class Outer( + val array: Array = [Inner(1), Inner(2)] +) { + annotation class Inner(val v: Int = 0) +} + // MODULE: app(lib) // FILE: app.kt @@ -45,6 +48,7 @@ class C { fun three(): Deprecated = Deprecated("foo") fun four(): OtherArrays = OtherArrays() fun five(): UnsignedValue = UnsignedValue() + fun six(): Outer = Outer() } fun box(): String { @@ -58,10 +62,13 @@ fun box(): String { """@kotlin.Deprecated(level=WARNING, message=foo, replaceWith=@kotlin.ReplaceWith(expression=, imports=[]))""", C().three().toString() ) - assertEquals( - """@a.OtherArrays(annotationsArray=[], doublesArray=[], enumArray=[], namesArray=[@kotlin.jvm.JvmName(name=foo)])""", - C().four().toString() + val otherArraysStr = C().four().toString() + // K1 and K2 have different properties order after metadata deserialization + assertTrue( + otherArraysStr == """@a.OtherArrays(doublesArray=[], enumArray=[], annotationsArray=[], namesArray=[@kotlin.jvm.JvmName(name=foo)])""" || + otherArraysStr == """@a.OtherArrays(annotationsArray=[], doublesArray=[], enumArray=[], namesArray=[@kotlin.jvm.JvmName(name=foo)])""" ) assertEquals(Int.MAX_VALUE.toUInt() + 10.toUInt(), C().five().uint) + assertEquals("""@a.Outer(array=[@a.Outer.Inner(v=1), @a.Outer.Inner(v=2)])""", C().six().toString()) return "OK" } diff --git a/compiler/testData/loadJava/compiledKotlin/typealias/Annotations.fir.txt b/compiler/testData/loadJava/compiledKotlin/typealias/Annotations.fir.txt index 92c3c6e253f..309dcf885c2 100644 --- a/compiler/testData/loadJava/compiledKotlin/typealias/Annotations.fir.txt +++ b/compiler/testData/loadJava/compiledKotlin/typealias/Annotations.fir.txt @@ -3,7 +3,7 @@ @R|test/Ann|(value = String(OK)) public final typealias A2 = R|kotlin/String| @R|kotlin/annotation/Target|(allowedTargets = (R|kotlin/annotation/AnnotationTarget.TYPEALIAS|)) public final annotation class Ann : R|kotlin/Annotation| { - public final val value: R|kotlin/String| + public final val value: R|kotlin/String| = String() public get(): R|kotlin/String| public constructor(value: R|kotlin/String| = STUB): R|test/Ann| diff --git a/compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/annotationClassDefaultValues.fir.k1.txt b/compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/annotationClassDefaultValues.fir.k1.txt new file mode 100644 index 00000000000..4d0502291f0 --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/annotationClassDefaultValues.fir.k1.txt @@ -0,0 +1,73 @@ +public final annotation class A : R|kotlin/Annotation| { + public final val aI: R|kotlin/IntArray| = (Int(1), Int(2)) + public get(): R|kotlin/IntArray| + + public final val aS: R|kotlin/Array| = (String(a), String(b)) + public get(): R|kotlin/Array| + + public final val anno: R|test/Empty| = @R|test/Empty|() + public get(): R|test/Empty| + + public final val e: R|test/E| = test/E.E0 + public get(): R|test/E| + + public final val i: R|kotlin/Int| = Int(42) + public get(): R|kotlin/Int| + + public final val kClass: R|kotlin/reflect/KClass<*>| = ((R|kotlin/Int|)) + public get(): R|kotlin/reflect/KClass<*>| + + public final val kClassArray: R|kotlin/Array>| = (((R|test/A|))) + public get(): R|kotlin/Array>| + + public final val s: R|kotlin/String| = String(foo) + public get(): R|kotlin/String| + + public constructor(i: R|kotlin/Int| = STUB, s: R|kotlin/String| = STUB, kClass: R|kotlin/reflect/KClass<*>| = STUB, kClassArray: R|kotlin/Array>| = STUB, e: R|test/E| = STUB, anno: R|test/Empty| = STUB, aS: R|kotlin/Array| = STUB, aI: R|kotlin/IntArray| = STUB): R|test/A| + +} + +public final enum class E : R|kotlin/Enum| { + private constructor(): R|test/E| + + public final static enum entry E0: R|test/E| + public final static fun values(): R|kotlin/Array| { + } + + public final static fun valueOf(value: R|kotlin/String|): R|test/E| { + } + + public final static val entries: R|kotlin/enums/EnumEntries| + public get(): R|kotlin/enums/EnumEntries| + +} + +public final annotation class Empty : R|kotlin/Annotation| { + public constructor(): R|test/Empty| + +} + +public final annotation class OtherArrays : R|kotlin/Annotation| { + public final val annotationsArray: R|kotlin/Array| = () + public get(): R|kotlin/Array| + + public final val doublesArray: R|kotlin/DoubleArray| = (Double(1.5)) + public get(): R|kotlin/DoubleArray| + + public final val enumArray: R|kotlin/Array| = (kotlin/text/RegexOption.IGNORE_CASE) + public get(): R|kotlin/Array| + + public final val namesArray: R|kotlin/Array| = (@R|kotlin/jvm/JvmName|(name = String(foo)) ) + public get(): R|kotlin/Array| + + public constructor(doublesArray: R|kotlin/DoubleArray| = STUB, enumArray: R|kotlin/Array| = STUB, annotationsArray: R|kotlin/Array| = STUB, namesArray: R|kotlin/Array| = STUB): R|test/OtherArrays| + +} + +public final annotation class UnsignedValue : R|kotlin/Annotation| { + public final val uint: R|kotlin/UInt| = UInt(-2147483639) + public get(): R|kotlin/UInt| + + public constructor(uint: R|kotlin/UInt| = STUB): R|test/UnsignedValue| + +} diff --git a/compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/annotationClassDefaultValues.fir.k2.txt b/compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/annotationClassDefaultValues.fir.k2.txt new file mode 100644 index 00000000000..eb7b8548779 --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/annotationClassDefaultValues.fir.k2.txt @@ -0,0 +1,73 @@ +public final annotation class A : R|kotlin/Annotation| { + public final val i: R|kotlin/Int| = Int(42) + public get(): R|kotlin/Int| + + public final val s: R|kotlin/String| = String(foo) + public get(): R|kotlin/String| + + public final val kClass: R|kotlin/reflect/KClass<*>| = ((R|kotlin/Int|)) + public get(): R|kotlin/reflect/KClass<*>| + + public final val kClassArray: R|kotlin/Array>| = (((R|test/A|))) + public get(): R|kotlin/Array>| + + public final val e: R|test/E| = test/E.E0 + public get(): R|test/E| + + public final val anno: R|test/Empty| = @R|test/Empty|() + public get(): R|test/Empty| + + public final val aS: R|kotlin/Array| = (String(a), String(b)) + public get(): R|kotlin/Array| + + public final val aI: R|kotlin/IntArray| = (Int(1), Int(2)) + public get(): R|kotlin/IntArray| + + public constructor(i: R|kotlin/Int| = STUB, s: R|kotlin/String| = STUB, kClass: R|kotlin/reflect/KClass<*>| = STUB, kClassArray: R|kotlin/Array>| = STUB, e: R|test/E| = STUB, anno: R|test/Empty| = STUB, aS: R|kotlin/Array| = STUB, aI: R|kotlin/IntArray| = STUB): R|test/A| + +} + +public final enum class E : R|kotlin/Enum| { + private constructor(): R|test/E| + + public final static enum entry E0: R|test/E| + public final static fun values(): R|kotlin/Array| { + } + + public final static fun valueOf(value: R|kotlin/String|): R|test/E| { + } + + public final static val entries: R|kotlin/enums/EnumEntries| + public get(): R|kotlin/enums/EnumEntries| + +} + +public final annotation class Empty : R|kotlin/Annotation| { + public constructor(): R|test/Empty| + +} + +public final annotation class OtherArrays : R|kotlin/Annotation| { + public final val doublesArray: R|kotlin/DoubleArray| = (Double(1.5)) + public get(): R|kotlin/DoubleArray| + + public final val enumArray: R|kotlin/Array| = (kotlin/text/RegexOption.IGNORE_CASE) + public get(): R|kotlin/Array| + + public final val annotationsArray: R|kotlin/Array| = () + public get(): R|kotlin/Array| + + public final val namesArray: R|kotlin/Array| = (@R|kotlin/jvm/JvmName|(name = String(foo)) ) + public get(): R|kotlin/Array| + + public constructor(doublesArray: R|kotlin/DoubleArray| = STUB, enumArray: R|kotlin/Array| = STUB, annotationsArray: R|kotlin/Array| = STUB, namesArray: R|kotlin/Array| = STUB): R|test/OtherArrays| + +} + +public final annotation class UnsignedValue : R|kotlin/Annotation| { + public final val uint: R|kotlin/UInt| = UInt(-2147483639) + public get(): R|kotlin/UInt| + + public constructor(uint: R|kotlin/UInt| = STUB): R|test/UnsignedValue| + +} diff --git a/compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/annotationClassDefaultValues.kt b/compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/annotationClassDefaultValues.kt new file mode 100644 index 00000000000..6417eeda7ae --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/annotationClassDefaultValues.kt @@ -0,0 +1,31 @@ +// NO_CHECK_SOURCE_VS_BINARY +//^ While compiling source with K1, we do not store annotation default values, but we load them when reading compiled files both in K1 and K2 +// This test verifies exactly loading of default values + +package test + +import kotlin.reflect.KClass +enum class E { E0 } +annotation class Empty + +annotation class A( + val i: Int = 42, + val s: String = "foo", + val kClass: KClass<*> = Int::class, + val kClassArray: Array> = [A::class], + val e: E = E.E0, + val anno: Empty = Empty(), + val aS: Array = arrayOf("a", "b"), + val aI: IntArray = intArrayOf(1, 2) +) + +annotation class OtherArrays( + val doublesArray: DoubleArray = [1.5], + val enumArray: Array = [kotlin.text.RegexOption.IGNORE_CASE], + val annotationsArray: Array = [], + val namesArray: Array = [JvmName("foo")] +) + +annotation class UnsignedValue( + val uint: UInt = 2147483657U // Int.MAX_VALUE + 10 +) diff --git a/compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/annotationClassDefaultValues.txt b/compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/annotationClassDefaultValues.txt new file mode 100644 index 00000000000..d3b01026fb2 --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/annotationClassDefaultValues.txt @@ -0,0 +1,63 @@ +package test + +public final annotation class A : kotlin.Annotation { + /*primary*/ public constructor A(/*0*/ i: kotlin.Int = ..., /*1*/ s: kotlin.String = ..., /*2*/ kClass: kotlin.reflect.KClass<*> = ..., /*3*/ kClassArray: kotlin.Array> = ..., /*4*/ e: test.E = ..., /*5*/ anno: test.Empty = ..., /*6*/ aS: kotlin.Array = ..., /*7*/ aI: kotlin.IntArray = ...) + public final val aI: kotlin.IntArray = {1, 2} + public final fun ``(): kotlin.IntArray + public final val aS: kotlin.Array = {"a", "b"} + public final fun ``(): kotlin.Array + public final val anno: test.Empty = test.Empty + public final fun ``(): test.Empty + public final val e: test.E = E.E0 + public final fun ``(): test.E + public final val i: kotlin.Int = 42 + public final fun ``(): kotlin.Int + public final val kClass: kotlin.reflect.KClass<*> = kotlin.Int::class + public final fun ``(): kotlin.reflect.KClass<*> + public final val kClassArray: kotlin.Array> = {test.A::class} + public final fun ``(): kotlin.Array> + public final val s: kotlin.String = "foo" + public final fun ``(): kotlin.String +} + +public final enum class E : kotlin.Enum { + enum entry E0 + + /*primary*/ private constructor E() + @kotlin.internal.IntrinsicConstEvaluation public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ fun ``(): kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + public final override /*1*/ /*fake_override*/ fun ``(): kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.E): kotlin.Int + protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit + public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class! + + // Static members + public final /*synthesized*/ val entries: kotlin.enums.EnumEntries + public final /*synthesized*/ fun ``(): kotlin.enums.EnumEntries + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.E + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final annotation class Empty : kotlin.Annotation { + /*primary*/ public constructor Empty() +} + +public final annotation class OtherArrays : kotlin.Annotation { + /*primary*/ public constructor OtherArrays(/*0*/ doublesArray: kotlin.DoubleArray = ..., /*1*/ enumArray: kotlin.Array = ..., /*2*/ annotationsArray: kotlin.Array = ..., /*3*/ namesArray: kotlin.Array = ...) + public final val annotationsArray: kotlin.Array = {} + public final fun ``(): kotlin.Array + public final val doublesArray: kotlin.DoubleArray = {1.5.toDouble()} + public final fun ``(): kotlin.DoubleArray + public final val enumArray: kotlin.Array = {RegexOption.IGNORE_CASE} + public final fun ``(): kotlin.Array + public final val namesArray: kotlin.Array = {kotlin.jvm.JvmName(name = "foo")} + public final fun ``(): kotlin.Array +} + +public final annotation class UnsignedValue : kotlin.Annotation { + /*primary*/ public constructor UnsignedValue(/*0*/ uint: kotlin.UInt = ...) + public final val uint: kotlin.UInt = -2147483639.toUInt() + public final fun ``(): kotlin.UInt +} diff --git a/compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/classMembers/EnumEntry.fir.txt b/compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/classMembers/EnumEntry.fir.txt index 030696e1e5a..3fb04058025 100644 --- a/compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/classMembers/EnumEntry.fir.txt +++ b/compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/classMembers/EnumEntry.fir.txt @@ -1,8 +1,8 @@ public final annotation class Anno : R|kotlin/Annotation| { - public final val value: R|kotlin/String| + public final val value: R|kotlin/String| = String(0) public get(): R|kotlin/String| - public final val x: R|kotlin/Int| + public final val x: R|kotlin/Int| = Int(0) public get(): R|kotlin/Int| public constructor(value: R|kotlin/String| = STUB, x: R|kotlin/Int| = STUB): R|test/Anno| diff --git a/compiler/tests-gen/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java index 627d97e8058..30fd7515377 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java @@ -4575,6 +4575,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @TestMetadata("annotationClassDefaultValues.kt") + public void testAnnotationClassDefaultValues() throws Exception { + runTest("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/annotationClassDefaultValues.kt"); + } + @TestMetadata("AnnotationInAnnotationArguments.kt") public void testAnnotationInAnnotationArguments() throws Exception { runTest("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/AnnotationInAnnotationArguments.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/jvm/compiler/ir/IrLoadJavaTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/jvm/compiler/ir/IrLoadJavaTestGenerated.java index 0a5eeb85801..2eb85ce66d4 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/jvm/compiler/ir/IrLoadJavaTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/jvm/compiler/ir/IrLoadJavaTestGenerated.java @@ -4576,6 +4576,11 @@ public class IrLoadJavaTestGenerated extends AbstractIrLoadJavaTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @TestMetadata("annotationClassDefaultValues.kt") + public void testAnnotationClassDefaultValues() throws Exception { + runTest("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/annotationClassDefaultValues.kt"); + } + @TestMetadata("AnnotationInAnnotationArguments.kt") public void testAnnotationInAnnotationArguments() throws Exception { runTest("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/AnnotationInAnnotationArguments.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/jvm/compiler/javac/LoadJavaUsingJavacTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/jvm/compiler/javac/LoadJavaUsingJavacTestGenerated.java index 318511b453e..e62b787a0b5 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/jvm/compiler/javac/LoadJavaUsingJavacTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/jvm/compiler/javac/LoadJavaUsingJavacTestGenerated.java @@ -4575,6 +4575,11 @@ public class LoadJavaUsingJavacTestGenerated extends AbstractLoadJavaUsingJavacT KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @TestMetadata("annotationClassDefaultValues.kt") + public void testAnnotationClassDefaultValues() throws Exception { + runTest("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/annotationClassDefaultValues.kt"); + } + @TestMetadata("AnnotationInAnnotationArguments.kt") public void testAnnotationInAnnotationArguments() throws Exception { runTest("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/AnnotationInAnnotationArguments.kt");