From dfa6dfa960adaedebe782faacae3a556c038521c Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Thu, 27 Feb 2020 13:51:22 +0300 Subject: [PATCH] [FIR] Support deserialization of annotations on JVM --- .../deserialization/ConstantValueFactory.kt | 44 +++ .../JvmBinaryAnnotationDeserializer.kt | 333 +++++++++++++++++- .../KotlinDeserializedJvmSymbolsProvider.kt | 1 + .../AbstractAnnotationDeserializer.kt | 35 +- .../deserialization/ClassDeserialization.kt | 13 +- .../FirBuiltinAnnotationDeserializer.kt | 8 +- .../deserialization/FirMemberDeserializer.kt | 58 ++- .../fir/deserialization/ProtoContainer.kt | 40 +++ .../resolve/impl/FirBuiltinSymbolProvider.kt | 2 +- .../packageMembers/EnumArgument.txt | 2 +- .../packageMembers/EnumArrayArgument.txt | 4 +- .../annotations/packageMembers/Function.txt | 2 +- .../packageMembers/StringArrayArgument.txt | 4 +- .../resolveWithStdlib/delegationByMap.kt | 4 + .../resolveWithStdlib/delegationByMap.txt | 17 + .../problems/delegateTypeMismatch.txt | 8 +- .../simpleDelegatedToMap.txt | 20 +- ...FirDiagnosticsWithStdlibTestGenerated.java | 5 + .../declarations/classLevelProperties.fir.txt | 27 +- .../declarations/delegatedProperties.fir.txt | 54 +-- .../localDelegatedProperties.fir.txt | 18 +- .../packageLevelProperties.fir.txt | 27 +- 22 files changed, 626 insertions(+), 100 deletions(-) create mode 100644 compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/ConstantValueFactory.kt create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ProtoContainer.kt create mode 100644 compiler/fir/resolve/testData/resolveWithStdlib/delegationByMap.kt create mode 100644 compiler/fir/resolve/testData/resolveWithStdlib/delegationByMap.txt diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/ConstantValueFactory.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/ConstantValueFactory.kt new file mode 100644 index 00000000000..8d53a94ac9f --- /dev/null +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/ConstantValueFactory.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2010-2020 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.java.deserialization + +import org.jetbrains.kotlin.fir.expressions.FirArrayOfCall +import org.jetbrains.kotlin.fir.expressions.FirConstKind +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.builder.buildArrayOfCall +import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression + +object ConstantValueFactory { + fun createArrayValue(value: List): FirArrayOfCall { + return buildArrayOfCall { + arguments += value + } + } + + fun createConstantValue(value: Any?): FirExpression? { + return when (value) { + is Byte -> buildConstExpression(null, FirConstKind.Byte, value) + is Short -> buildConstExpression(null, FirConstKind.Short, value) + is Int -> buildConstExpression(null, FirConstKind.Int, value) + is Long -> buildConstExpression(null, FirConstKind.Long, value) + is Char -> buildConstExpression(null, FirConstKind.Char, value) + is Float -> buildConstExpression(null, FirConstKind.Float, value) + is Double -> buildConstExpression(null, FirConstKind.Double, value) + is Boolean -> buildConstExpression(null, FirConstKind.Boolean, value) + is String -> buildConstExpression(null, FirConstKind.String, value) + is ByteArray -> createArrayValue(value.map { createConstantValue(it)!! }) + is ShortArray -> createArrayValue(value.map { createConstantValue(it)!! }) + is IntArray -> createArrayValue(value.map { createConstantValue(it)!! }) + is LongArray -> createArrayValue(value.map { createConstantValue(it)!! }) + is CharArray -> createArrayValue(value.map { createConstantValue(it)!! }) + is FloatArray -> createArrayValue(value.map { createConstantValue(it)!! }) + is DoubleArray -> createArrayValue(value.map { createConstantValue(it)!! }) + is BooleanArray -> createArrayValue(value.map { createConstantValue(it)!! }) + null -> buildConstExpression(null, FirConstKind.Null, value) + else -> null + } + } +} 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 6a794fae679..8ade9427a0c 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 @@ -5,18 +5,349 @@ package org.jetbrains.kotlin.fir.java.deserialization +import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.deserialization.AbstractAnnotationDeserializer +import org.jetbrains.kotlin.fir.deserialization.ProtoContainer +import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.builder.* +import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference +import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl +import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol +import org.jetbrains.kotlin.fir.types.ConeKotlinType +import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef +import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl +import org.jetbrains.kotlin.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader +import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource +import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass +import org.jetbrains.kotlin.load.kotlin.MemberSignature import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.deserialization.NameResolver +import org.jetbrains.kotlin.metadata.deserialization.TypeTable +import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf +import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.protobuf.MessageLite +import org.jetbrains.kotlin.resolve.constants.ClassLiteralValue +import org.jetbrains.kotlin.serialization.deserialization.AnnotatedCallableKind +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull +import org.jetbrains.kotlin.utils.compact +import java.util.* class JvmBinaryAnnotationDeserializer( session: FirSession ) : AbstractAnnotationDeserializer(session) { - override fun loadTypeAnnotations(typeProto: ProtoBuf.Type, nameResolver: NameResolver): List { + private val cache: MutableMap = mutableMapOf() + + private class Storage( + val memberAnnotations: Map>, + val propertyConstants: Map + ) + + private val ProtoContainer.kotlinJvmBinaryClass: KotlinJvmBinaryClass? + get() = (sourceElement as? JvmPackagePartSource)?.knownJvmBinaryClass + + override fun loadTypeAnnotations( + containingDeclaration: ProtoContainer, + typeProto: ProtoBuf.Type, + nameResolver: NameResolver, + typeTable: TypeTable + ): List { val annotations = typeProto.getExtension(JvmProtoBuf.typeAnnotation).orEmpty() return annotations.map { deserializeAnnotation(it, nameResolver) } } + + override fun loadFunctionAnnotations( + containingDeclaration: ProtoContainer, + functionProto: ProtoBuf.Function, + nameResolver: NameResolver, + typeTable: TypeTable + ): List { + val kotlinClass = containingDeclaration.kotlinJvmBinaryClass ?: return emptyList() + val signature = getCallableSignature(functionProto, nameResolver, typeTable, AnnotatedCallableKind.FUNCTION) ?: return emptyList() + val storage = loadClassFileContent(kotlinClass) + return storage.memberAnnotations[signature] ?: emptyList() + } + + override fun loadPropertyAnnotations( + containingDeclaration: ProtoContainer, + propertyProto: ProtoBuf.Property, + nameResolver: NameResolver, + typeTable: TypeTable + ): List { + val kotlinClass = containingDeclaration.kotlinJvmBinaryClass ?: return emptyList() + val signature = getPropertySignature(propertyProto, nameResolver, typeTable) ?: return emptyList() + val storage = loadClassFileContent(kotlinClass) + return storage.memberAnnotations[signature] ?: emptyList() + } + + override fun loadConstructorAnnotations( + containingDeclaration: ProtoContainer, + constructorProto: ProtoBuf.Constructor, + nameResolver: NameResolver, + typeTable: TypeTable + ): List { + val kotlinClass = containingDeclaration.kotlinJvmBinaryClass ?: return emptyList() + val signature = getCallableSignature(constructorProto, nameResolver, typeTable, AnnotatedCallableKind.FUNCTION) ?: return emptyList() + val storage = loadClassFileContent(kotlinClass) + return storage.memberAnnotations[signature] ?: emptyList() + } + + private fun getCallableSignature( + proto: MessageLite, + nameResolver: NameResolver, + typeTable: TypeTable, + kind: AnnotatedCallableKind, + requireHasFieldFlagForField: Boolean = false + ): MemberSignature? { + return when (proto) { + is ProtoBuf.Constructor -> { + MemberSignature.fromJvmMemberSignature( + JvmProtoBufUtil.getJvmConstructorSignature(proto, nameResolver, typeTable) ?: return null + ) + } + is ProtoBuf.Function -> { + MemberSignature.fromJvmMemberSignature(JvmProtoBufUtil.getJvmMethodSignature(proto, nameResolver, typeTable) ?: return null) + } + is ProtoBuf.Property -> { + val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature) ?: return null + when (kind) { + AnnotatedCallableKind.PROPERTY_GETTER -> + if (signature.hasGetter()) MemberSignature.fromMethod(nameResolver, signature.getter) else null + AnnotatedCallableKind.PROPERTY_SETTER -> + if (signature.hasSetter()) MemberSignature.fromMethod(nameResolver, signature.setter) else null + AnnotatedCallableKind.PROPERTY -> + getPropertySignature(proto, nameResolver, typeTable, true, true, requireHasFieldFlagForField) + else -> null + } + } + else -> null + } + } + + private fun getPropertySignature( + proto: ProtoBuf.Property, + nameResolver: NameResolver, + typeTable: TypeTable, + field: Boolean = false, + synthetic: Boolean = false, + requireHasFieldFlagForField: Boolean = true + ): MemberSignature? { + val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature) ?: return null + + if (field) { + val fieldSignature = + JvmProtoBufUtil.getJvmFieldSignature(proto, nameResolver, typeTable, requireHasFieldFlagForField) ?: return null + return MemberSignature.fromJvmMemberSignature(fieldSignature) + } else if (synthetic && signature.hasSyntheticMethod()) { + return MemberSignature.fromMethod(nameResolver, signature.syntheticMethod) + } + + return null + } + + + private fun loadClassFileContent(kotlinClass: KotlinJvmBinaryClass): Storage { + cache[kotlinClass]?.let { return it } + + val memberAnnotations = HashMap>() + val propertyConstants = HashMap() + + kotlinClass.visitMembers(object : KotlinJvmBinaryClass.MemberVisitor { + override fun visitMethod(name: Name, desc: String): KotlinJvmBinaryClass.MethodAnnotationVisitor? { + return AnnotationVisitorForMethod(MemberSignature.fromMethodNameAndDesc(name.asString(), desc)) + } + + override fun visitField(name: Name, desc: String, initializer: Any?): KotlinJvmBinaryClass.AnnotationVisitor? { + val signature = MemberSignature.fromFieldNameAndDesc(name.asString(), desc) + + if (initializer != null) { + val constant = loadConstant(desc, initializer) + if (constant != null) { + propertyConstants[signature] = constant + } + } + return MemberAnnotationVisitor(signature) + } + + inner class AnnotationVisitorForMethod(signature: MemberSignature) : MemberAnnotationVisitor(signature), + KotlinJvmBinaryClass.MethodAnnotationVisitor { + + override fun visitParameterAnnotation( + index: Int, classId: ClassId, source: SourceElement + ): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { + val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(signature, index) + var result = memberAnnotations[paramSignature] + if (result == null) { + result = ArrayList() + memberAnnotations[paramSignature] = result + } + return loadAnnotationIfNotSpecial(classId, source, result) + } + } + + open inner class MemberAnnotationVisitor(protected val signature: MemberSignature) : KotlinJvmBinaryClass.AnnotationVisitor { + private val result = ArrayList() + + override fun visitAnnotation(classId: ClassId, source: SourceElement): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { + return loadAnnotationIfNotSpecial(classId, source, result) + } + + override fun visitEnd() { + if (result.isNotEmpty()) { + memberAnnotations[signature] = result + } + } + } + }, getCachedFileContent(kotlinClass)) + + return Storage(memberAnnotations, propertyConstants).also { + cache[kotlinClass] = it + } + } + + fun getCachedFileContent(kotlinClass: KotlinJvmBinaryClass): ByteArray? = null + + private fun loadConstant(desc: String, initializer: Any): FirExpression? { + val normalizedValue: Any = if (desc in "ZBCS") { + val intValue = initializer as Int + when (desc) { + "Z" -> intValue != 0 + "B" -> intValue.toByte() + "C" -> intValue.toChar() + "S" -> intValue.toShort() + else -> throw AssertionError(desc) + } + } else { + initializer + } + + return ConstantValueFactory.createConstantValue(normalizedValue) + } + + private fun loadAnnotationIfNotSpecial( + annotationClassId: ClassId, + source: SourceElement, + result: MutableList + ): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { + if (annotationClassId in AbstractBinaryClassAnnotationAndConstantLoader.SPECIAL_ANNOTATIONS) return null + + return loadAnnotation(annotationClassId, result) + } + + fun loadClass(classId: ClassId): FirClassSymbol<*>? { + return session.firSymbolProvider.getClassLikeSymbolByFqName(classId) as? FirClassSymbol<*> + } + + private fun ClassId.toConeKotlinType(): ConeKotlinType = ConeClassLikeTypeImpl(ConeClassLikeLookupTagImpl(this), emptyArray(), isNullable = false) + + fun loadAnnotation( + annotationClassId: ClassId, + result: MutableList + ): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { + val annotationClass = loadClass(annotationClassId) ?: return null + val annotationConstructor = annotationClass.fir.declarations.firstIsInstanceOrNull() ?: return null + + val builder = FirAnnotationCallBuilder().apply { + annotationTypeRef = buildResolvedTypeRef { + type = annotationClassId.toConeKotlinType() + } + } + + return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor { + private val arguments = HashMap() + + override fun visit(name: Name?, value: Any?) { + if (name != null) { + arguments[name] = createConstant(name, value) + } + } + + override fun visitClassLiteral(name: Name, value: ClassLiteralValue) { + arguments[name] = buildClassLiteral(value) + } + + override fun visitEnum(name: Name, enumClassId: ClassId, enumEntryName: Name) { + arguments[name] = buildEnum(enumClassId, enumEntryName) + } + + private fun buildClassLiteral(value: ClassLiteralValue): FirExpression { + return buildGetClassCall { + arguments += buildResolvedQualifier { + + } + } + } + + private fun buildEnum( + enumClassId: ClassId, + enumEntryName: Name + ): FirExpression { + return buildQualifiedAccessExpression { + typeRef = buildResolvedTypeRef { + type = enumClassId.toConeKotlinType() + } + calleeReference = buildResolvedNamedReference { + name = enumEntryName + resolvedSymbol = loadClass(enumClassId)!! + } + } + } + + override fun visitArray(name: Name): KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor? { + return object : KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor { + private val elements = ArrayList() + + override fun visit(value: Any?) { + elements.add(createConstant(name, value)) + } + + override fun visitEnum(enumClassId: ClassId, enumEntryName: Name) { + elements.add(buildEnum(enumClassId, enumEntryName)) + } + + override fun visitClassLiteral(value: ClassLiteralValue) { + elements.add(buildClassLiteral(value)) + } + + override fun visitEnd() { + val parameter = annotationConstructor.valueParameters.firstOrNull { it.name == name } + if (parameter != null) { + arguments[name] = ConstantValueFactory.createArrayValue(elements.compact()) + } + } + } + } + + override fun visitAnnotation(name: Name, classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { + val list = ArrayList() + val visitor = loadAnnotation(classId, list)!! + return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor { + override fun visitEnd() { + visitor.visitEnd() + arguments[name] = list.single() + } + } + } + + override fun visitEnd() { + result += builder.build() + } + + private fun createConstant(name: Name?, value: Any?): FirExpression { + return ConstantValueFactory.createConstantValue(value) + ?: buildErrorExpression { + diagnostic = FirSimpleDiagnostic("Unsupported annotation argument: $name") + } + } + } + } + } \ No newline at end of file diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt index e648a5b0ad8..a3f7c598f82 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt @@ -122,6 +122,7 @@ class KotlinDeserializedJvmSymbolsProvider( FirDeserializationContext.createForPackage( packageFqName, packageProto, nameResolver, session, JvmBinaryAnnotationDeserializer(session), + source ), source, ) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt index 1cb722cee54..276b0e36834 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt @@ -31,46 +31,67 @@ import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.ProtoBuf.Annotation.Argument.Value.Type.* import org.jetbrains.kotlin.metadata.deserialization.Flags import org.jetbrains.kotlin.metadata.deserialization.NameResolver +import org.jetbrains.kotlin.metadata.deserialization.TypeTable import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol import org.jetbrains.kotlin.serialization.deserialization.getClassId import org.jetbrains.kotlin.serialization.deserialization.getName abstract class AbstractAnnotationDeserializer( - private val session: FirSession + protected val session: FirSession ) { protected val protocol = BuiltInSerializerProtocol - fun loadClassAnnotations(classProto: ProtoBuf.Class, nameResolver: NameResolver): List { + open fun loadClassAnnotations(classProto: ProtoBuf.Class, nameResolver: NameResolver): List { if (!Flags.HAS_ANNOTATIONS.get(classProto.flags)) return emptyList() val annotations = classProto.getExtension(protocol.classAnnotation).orEmpty() return annotations.map { deserializeAnnotation(it, nameResolver) } } - fun loadFunctionAnnotations(functionProto: ProtoBuf.Function, nameResolver: NameResolver): List { + open fun loadFunctionAnnotations( + containingDeclaration: ProtoContainer, + functionProto: ProtoBuf.Function, + nameResolver: NameResolver, + typeTable: TypeTable + ): List { if (!Flags.HAS_ANNOTATIONS.get(functionProto.flags)) return emptyList() val annotations = functionProto.getExtension(protocol.functionAnnotation).orEmpty() return annotations.map { deserializeAnnotation(it, nameResolver) } } - fun loadPropertyAnnotations(propertyProto: ProtoBuf.Property, nameResolver: NameResolver): List { + open fun loadPropertyAnnotations( + containingDeclaration: ProtoContainer, + propertyProto: ProtoBuf.Property, + nameResolver: NameResolver, + typeTable: TypeTable + ): List { if (!Flags.HAS_ANNOTATIONS.get(propertyProto.flags)) return emptyList() val annotations = propertyProto.getExtension(protocol.propertyAnnotation).orEmpty() return annotations.map { deserializeAnnotation(it, nameResolver) } } - fun loadConstructorAnnotations(constructorProto: ProtoBuf.Constructor, nameResolver: NameResolver): List { + open fun loadConstructorAnnotations( + containingDeclaration: ProtoContainer, + constructorProto: ProtoBuf.Constructor, + nameResolver: NameResolver, + typeTable: TypeTable + ): List { if (!Flags.HAS_ANNOTATIONS.get(constructorProto.flags)) return emptyList() val annotations = constructorProto.getExtension(protocol.constructorAnnotation).orEmpty() return annotations.map { deserializeAnnotation(it, nameResolver) } } - fun loadValueParameterAnnotations(valueParameterProto: ProtoBuf.ValueParameter, nameResolver: NameResolver): List { + open fun loadValueParameterAnnotations( + containingDeclaration: ProtoContainer, + valueParameterProto: ProtoBuf.ValueParameter, + nameResolver: NameResolver, + typeTable: TypeTable + ): List { if (!Flags.HAS_ANNOTATIONS.get(valueParameterProto.flags)) return emptyList() val annotations = valueParameterProto.getExtension(protocol.parameterAnnotation).orEmpty() return annotations.map { deserializeAnnotation(it, nameResolver) } } - abstract fun loadTypeAnnotations(typeProto: ProtoBuf.Type, nameResolver: NameResolver): List + abstract fun loadTypeAnnotations(containingDeclaration: ProtoContainer, typeProto: ProtoBuf.Type, nameResolver: NameResolver, typeTable: TypeTable): List fun deserializeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): FirAnnotationCall { val classId = nameResolver.getClassId(proto.id) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt index 601bd59bda9..d6a9465ec86 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt @@ -63,9 +63,18 @@ fun deserializeClassToSymbol( classProto.typeParameterList, nameResolver, TypeTable(classProto.typeTable), - classId.relativeClassName + classId.relativeClassName, + ProtoContainer.Class( + classProto, + parentContext.containingDeclaration as? ProtoContainer.Class, + classId, + null + ) ) ?: FirDeserializationContext.createForClass( - classId, classProto, nameResolver, session, + classId, + classProto, + nameResolver, + session, defaultAnnotationDeserializer ?: FirBuiltinAnnotationDeserializer(session) ) classBuilder.apply { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirBuiltinAnnotationDeserializer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirBuiltinAnnotationDeserializer.kt index d3bcec605b7..2f2e2110cfe 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirBuiltinAnnotationDeserializer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirBuiltinAnnotationDeserializer.kt @@ -10,12 +10,18 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.deserialization.Flags import org.jetbrains.kotlin.metadata.deserialization.NameResolver +import org.jetbrains.kotlin.metadata.deserialization.TypeTable class FirBuiltinAnnotationDeserializer( session: FirSession ) : AbstractAnnotationDeserializer(session) { - override fun loadTypeAnnotations(typeProto: ProtoBuf.Type, nameResolver: NameResolver): List { + override fun loadTypeAnnotations( + containigDeclaration: ProtoContainer, + typeProto: ProtoBuf.Type, + nameResolver: NameResolver, + typeTable: TypeTable + ): List { if (!Flags.HAS_ANNOTATIONS.get(typeProto.flags)) return emptyList() val annotations = typeProto.getExtension(protocol.typeAnnotation).orEmpty() return annotations.map { deserializeAnnotation(it, nameResolver) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt index 9b1039a1926..2ec4bb794b5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt @@ -6,11 +6,14 @@ package org.jetbrains.kotlin.fir.deserialization import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.builder.* -import org.jetbrains.kotlin.fir.declarations.impl.* +import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl +import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter +import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.builder.buildExpressionStub import org.jetbrains.kotlin.fir.symbols.CallableId @@ -37,19 +40,21 @@ class FirDeserializationContext( val relativeClassName: FqName?, val typeDeserializer: FirTypeDeserializer, val annotationDeserializer: AbstractAnnotationDeserializer, - val components: FirDeserializationComponents + val components: FirDeserializationComponents, + val containingDeclaration: ProtoContainer ) { fun childContext( typeParameterProtos: List, nameResolver: NameResolver = this.nameResolver, typeTable: TypeTable = this.typeTable, - relativeClassName: FqName? = this.relativeClassName + relativeClassName: FqName? = this.relativeClassName, + containingDeclaration: ProtoContainer = this.containingDeclaration ): FirDeserializationContext = FirDeserializationContext( nameResolver, typeTable, versionRequirementTable, session, packageFqName, relativeClassName, FirTypeDeserializer( session, nameResolver, typeTable, typeParameterProtos, typeDeserializer ), - annotationDeserializer, components + annotationDeserializer, components, containingDeclaration ) val memberDeserializer: FirMemberDeserializer = FirMemberDeserializer(this) @@ -60,7 +65,8 @@ class FirDeserializationContext( packageProto: ProtoBuf.Package, nameResolver: NameResolver, session: FirSession, - annotationDeserializer: AbstractAnnotationDeserializer + annotationDeserializer: AbstractAnnotationDeserializer, + sourceElement: SourceElement? ) = createRootContext( nameResolver, TypeTable(packageProto.typeTable), @@ -68,7 +74,8 @@ class FirDeserializationContext( annotationDeserializer, fqName, relativeClassName = null, - typeParameterProtos = emptyList() + typeParameterProtos = emptyList(), + ProtoContainer.Package(fqName, sourceElement) ) fun createForClass( @@ -84,7 +91,8 @@ class FirDeserializationContext( annotationDeserializer, classId.packageFqName, classId.relativeClassName, - classProto.typeParameterList + classProto.typeParameterList, + ProtoContainer.Class(classProto, outerClass = null, classId, null) ) private fun createRootContext( @@ -94,7 +102,8 @@ class FirDeserializationContext( annotationDeserializer: AbstractAnnotationDeserializer, packageFqName: FqName, relativeClassName: FqName?, - typeParameterProtos: List + typeParameterProtos: List, + containingDeclaration: ProtoContainer ): FirDeserializationContext { return FirDeserializationContext( nameResolver, typeTable, @@ -110,7 +119,8 @@ class FirDeserializationContext( null ), annotationDeserializer, - FirDeserializationComponents() + FirDeserializationComponents(), + containingDeclaration ) } } @@ -180,7 +190,12 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES typeParameters += local.typeDeserializer.ownTypeParameters.map { it.fir } - annotations += c.annotationDeserializer.loadPropertyAnnotations(proto, local.nameResolver) + annotations += c.annotationDeserializer.loadPropertyAnnotations( + c.containingDeclaration, + proto, + local.nameResolver, + local.typeTable + ) getter = FirDefaultPropertyGetter(null, c.session, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(getterFlags))) setter = if (isVar) { FirDefaultPropertySetter(null, c.session, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(setterFlags))) @@ -228,7 +243,12 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES typeParameters += local.typeDeserializer.ownTypeParameters.map { it.fir } valueParameters += local.memberDeserializer.valueParameters(proto.valueParameterList) - annotations += local.annotationDeserializer.loadFunctionAnnotations(proto, local.nameResolver) + annotations += local.annotationDeserializer.loadFunctionAnnotations( + c.containingDeclaration, + proto, + local.nameResolver, + local.typeTable + ) this.containerSource = containerSource } if (proto.hasContract()) { @@ -275,7 +295,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { valueParameters += local.memberDeserializer.valueParameters( proto.valueParameterList, addDefaultValue = classBuilder.symbol.classId == StandardClassIds.Enum ) - annotations += local.annotationDeserializer.loadConstructorAnnotations(proto, local.nameResolver) + annotations += local.annotationDeserializer.loadConstructorAnnotations(c.containingDeclaration, proto, local.nameResolver, local.typeTable) }.build() } @@ -305,7 +325,12 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { isCrossinline = Flags.IS_CROSSINLINE.get(flags) isNoinline = Flags.IS_NOINLINE.get(flags) isVararg = proto.varargElementType(c.typeTable) != null - annotations += c.annotationDeserializer.loadValueParameterAnnotations(proto, c.nameResolver) + annotations += c.annotationDeserializer.loadValueParameterAnnotations( + c.containingDeclaration, + proto, + c.nameResolver, + c.typeTable + ) } }.toList() } @@ -313,7 +338,12 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { private fun ProtoBuf.Type.toTypeRef(context: FirDeserializationContext): FirTypeRef { return buildResolvedTypeRef { type = context.typeDeserializer.type(this@toTypeRef) - annotations += context.annotationDeserializer.loadTypeAnnotations(this@toTypeRef, context.nameResolver) + annotations += context.annotationDeserializer.loadTypeAnnotations( + c.containingDeclaration, + this@toTypeRef, + context.nameResolver, + context.typeTable + ) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ProtoContainer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ProtoContainer.kt new file mode 100644 index 00000000000..deb6e330f75 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ProtoContainer.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2010-2020 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.descriptors.SourceElement +import org.jetbrains.kotlin.metadata.ProtoBuf +import org.jetbrains.kotlin.metadata.deserialization.Flags +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName + +sealed class ProtoContainer( + val sourceElement: SourceElement? +) { + class Class( + val classProto: ProtoBuf.Class, + val outerClass: Class?, + val classId: ClassId, + sourceElement: SourceElement? + ) : ProtoContainer(sourceElement) { + val kind: ProtoBuf.Class.Kind = Flags.CLASS_KIND.get(classProto.flags) ?: ProtoBuf.Class.Kind + .CLASS + val isInner: Boolean = Flags.IS_INNER.get(classProto.flags) + + override fun debugFqName(): FqName = classId.asSingleFqName() + } + + class Package( + val fqName: FqName, + sourceElement: SourceElement? + ) : ProtoContainer(sourceElement) { + override fun debugFqName(): FqName = fqName + } + + abstract fun debugFqName(): FqName + + override fun toString() = "${this::class.java.simpleName}: ${debugFqName()}" +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirBuiltinSymbolProvider.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirBuiltinSymbolProvider.kt index 02e6bbd706e..2f88d665cd5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirBuiltinSymbolProvider.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirBuiltinSymbolProvider.kt @@ -77,7 +77,7 @@ class FirBuiltinSymbolProvider(val session: FirSession, val kotlinScopeProvider: private val memberDeserializer by lazy { FirDeserializationContext.createForPackage( fqName, packageProto.`package`, nameResolver, session, - FirBuiltinAnnotationDeserializer(session), + FirBuiltinAnnotationDeserializer(session), null ).memberDeserializer } diff --git a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/packageMembers/EnumArgument.txt b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/packageMembers/EnumArgument.txt index 9cdb69dbdf8..e27b0653765 100644 --- a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/packageMembers/EnumArgument.txt +++ b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/packageMembers/EnumArgument.txt @@ -1,4 +1,4 @@ -public final fun foo(): R|kotlin/Unit| +@R|test/Anno|() public final fun foo(): R|kotlin/Unit| public final annotation class Anno : R|kotlin/Annotation| { public final val t: R|java/lang/annotation/ElementType| diff --git a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/packageMembers/EnumArrayArgument.txt b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/packageMembers/EnumArrayArgument.txt index 63a245ce5d8..4f0bd51ed22 100644 --- a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/packageMembers/EnumArrayArgument.txt +++ b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/packageMembers/EnumArrayArgument.txt @@ -1,6 +1,6 @@ -public final fun baz(): R|kotlin/Unit| +@R|test/Anno|() public final fun baz(): R|kotlin/Unit| -public final fun foo(): R|kotlin/Unit| +@R|test/Anno|() public final fun foo(): R|kotlin/Unit| public final annotation class Anno : R|kotlin/Annotation| { public final val t: R|kotlin/Array| diff --git a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/packageMembers/Function.txt b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/packageMembers/Function.txt index 30ed424ed0d..368dd815c1d 100644 --- a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/packageMembers/Function.txt +++ b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/packageMembers/Function.txt @@ -1,4 +1,4 @@ -public final fun function(): R|kotlin/Unit| +@R|test/Anno|() public final fun function(): R|kotlin/Unit| public final annotation class Anno : R|kotlin/Annotation| { public constructor(): R|test/Anno| diff --git a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/packageMembers/StringArrayArgument.txt b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/packageMembers/StringArrayArgument.txt index 0fc95adf14a..c0ca184a970 100644 --- a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/packageMembers/StringArrayArgument.txt +++ b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/packageMembers/StringArrayArgument.txt @@ -1,6 +1,6 @@ -public final fun baz(): R|kotlin/Unit| +@R|test/Anno|() public final fun baz(): R|kotlin/Unit| -public final fun foo(): R|kotlin/Unit| +@R|test/Anno|() public final fun foo(): R|kotlin/Unit| public final annotation class Anno : R|kotlin/Annotation| { public final val t: R|kotlin/Array| diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/delegationByMap.kt b/compiler/fir/resolve/testData/resolveWithStdlib/delegationByMap.kt new file mode 100644 index 00000000000..99fe278dd32 --- /dev/null +++ b/compiler/fir/resolve/testData/resolveWithStdlib/delegationByMap.kt @@ -0,0 +1,4 @@ +class A { + val x by mutableMapOf() + val y: Int by mutableMapOf() +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/delegationByMap.txt b/compiler/fir/resolve/testData/resolveWithStdlib/delegationByMap.txt new file mode 100644 index 00000000000..ba4ace5ca14 --- /dev/null +++ b/compiler/fir/resolve/testData/resolveWithStdlib/delegationByMap.txt @@ -0,0 +1,17 @@ +FILE: delegationByMap.kt + public final class A : R|kotlin/Any| { + public constructor(): R|A| { + super() + } + + public final val x: R|kotlin/Int|by R|kotlin/collections/mutableMapOf|() + public get(): R|kotlin/Int| { + ^ D|/A.x|.R|kotlin/collections/getValue|(this@R|/A|, ::R|/A.x|) + } + + public final val y: R|kotlin/Int|by R|kotlin/collections/mutableMapOf|() + public get(): R|kotlin/Int| { + ^ D|/A.y|.R|kotlin/collections/getValue|(this@R|/A|, ::R|/A.y|) + } + + } diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/problems/delegateTypeMismatch.txt b/compiler/fir/resolve/testData/resolveWithStdlib/problems/delegateTypeMismatch.txt index 82a5b9de3b8..9203f9f8469 100644 --- a/compiler/fir/resolve/testData/resolveWithStdlib/problems/delegateTypeMismatch.txt +++ b/compiler/fir/resolve/testData/resolveWithStdlib/problems/delegateTypeMismatch.txt @@ -41,14 +41,14 @@ FILE: delegateTypeMismatch.kt D|/A.classifierNamePolicy|.#(this@R|/A|, ::R|/A.classifierNamePolicy|, R|/classifierNamePolicy|) } - public final var typeNormalizer: by # KotlinType|>(property@fun (): R|ERROR CLASS: Unresolved name: it| { + public final var typeNormalizer: by # KotlinType|>(property@fun (): R|ERROR CLASS: Unresolved name: it| { ^ # } ) - public get(): { - ^ D|/A.typeNormalizer|.#(this@R|/A|, ::R|/A.typeNormalizer|) + public get(): { + ^ D|/A.typeNormalizer|.#(this@R|/A|, ::R|/A.typeNormalizer|) } - public set(: ): R|kotlin/Unit| { + public set(: ): R|kotlin/Unit| { D|/A.typeNormalizer|.#(this@R|/A|, ::R|/A.typeNormalizer|, R|/typeNormalizer|) } diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/simpleDelegatedToMap.txt b/compiler/fir/resolve/testData/resolveWithStdlib/simpleDelegatedToMap.txt index c4019f42bea..cf2d7e855c2 100644 --- a/compiler/fir/resolve/testData/resolveWithStdlib/simpleDelegatedToMap.txt +++ b/compiler/fir/resolve/testData/resolveWithStdlib/simpleDelegatedToMap.txt @@ -7,19 +7,19 @@ FILE: simpleDelegatedToMap.kt public final val map: R|kotlin/collections/MutableMap| = R|/map| public get(): R|kotlin/collections/MutableMap| - public final var foo: by R|/map| - public get(): { - ^ D|/C.foo|.#(this@R|/C|, ::R|/C.foo|) + public final var foo: R|kotlin/Any|by R|/map| + public get(): R|kotlin/Any| { + ^ D|/C.foo|.R|kotlin/collections/getValue|(this@R|/C|, ::R|/C.foo|) } - public set(: ): R|kotlin/Unit| { - D|/C.foo|.#(this@R|/C|, ::R|/C.foo|, R|/foo|) + public set(: R|kotlin/Any|): R|kotlin/Unit| { + D|/C.foo|.R|kotlin/collections/setValue|(this@R|/C|, ::R|/C.foo|, R|/foo|) } } - public final var bar: by R|kotlin/collections/hashMapOf|() - public get(): { - ^ D|/bar|.#(Null(null), ::R|/bar|) + public final var bar: R|ft!|by R|kotlin/collections/hashMapOf|() + public get(): R|ft!| { + ^ D|/bar|.R|kotlin/collections/getValue|!|, R|ft!|>(Null(null), ::R|/bar|) } - public set(: ): R|kotlin/Unit| { - D|/bar|.#(Null(null), ::R|/bar|, R|/bar|) + public set(: R|ft!|): R|kotlin/Unit| { + D|/bar|.R|kotlin/collections/setValue|!|>(Null(null), ::R|/bar|, R|/bar|) } diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java index 518bd30fd05..4aca220f6c2 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java @@ -83,6 +83,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic runTest("compiler/fir/resolve/testData/resolveWithStdlib/concurrentMapOfAliases.kt"); } + @TestMetadata("delegationByMap.kt") + public void testDelegationByMap() throws Exception { + runTest("compiler/fir/resolve/testData/resolveWithStdlib/delegationByMap.kt"); + } + @TestMetadata("emptyArray.kt") public void testEmptyArray() throws Exception { runTest("compiler/fir/resolve/testData/resolveWithStdlib/emptyArray.kt"); diff --git a/compiler/testData/ir/irText/declarations/classLevelProperties.fir.txt b/compiler/testData/ir/irText/declarations/classLevelProperties.fir.txt index ca1a9e3933b..76b5afea5bb 100644 --- a/compiler/testData/ir/irText/declarations/classLevelProperties.fir.txt +++ b/compiler/testData/ir/irText/declarations/classLevelProperties.fir.txt @@ -109,23 +109,28 @@ FILE fqName: fileName:/classLevelProperties.kt CALL 'public final fun hashMapOf (): java.util.HashMap [inline] declared in kotlin.collections' type=java.util.HashMap origin=null : kotlin.String : kotlin.Int - FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.C) returnType:IrErrorType + FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.C) returnType:kotlin.Int? correspondingProperty: PROPERTY name:test8 visibility:public modality:FINAL [delegated,var] $this: VALUE_PARAMETER name: type:.C BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): IrErrorType declared in .C' - ERROR_CALL 'Unresolved reference: #' type=IrErrorType - GET_VAR ': .C declared in .C' type=.C origin=null - PROPERTY_REFERENCE 'public final test8: IrErrorType [delegated,var]' field='FIELD PROPERTY_DELEGATE name:test8$delegate type:java.util.HashMap visibility:private [final]' getter='public final fun (): IrErrorType declared in .C' setter='public final fun (: IrErrorType): kotlin.Unit declared in .C' type=kotlin.reflect.KProperty<*> origin=null - FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.C, :IrErrorType) returnType:kotlin.Unit + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Int? declared in .C' + CALL 'public final fun getValue (thisRef: kotlin.Any?, property: kotlin.reflect.KProperty<*>): V1 of kotlin.collections.getValue [inline,operator] declared in kotlin.collections' type=kotlin.Int? origin=null + : kotlin.Int? + : kotlin.Int? + $receiver: GET_FIELD 'FIELD PROPERTY_DELEGATE name:test8$delegate type:java.util.HashMap visibility:private [final]' type=java.util.HashMap origin=GET_PROPERTY + thisRef: GET_VAR ': .C declared in .C' type=.C origin=null + property: PROPERTY_REFERENCE 'public final test8: kotlin.Int? [delegated,var]' field='FIELD PROPERTY_DELEGATE name:test8$delegate type:java.util.HashMap visibility:private [final]' getter='public final fun (): kotlin.Int? declared in .C' setter='public final fun (: kotlin.Int?): kotlin.Unit declared in .C' type=kotlin.reflect.KProperty<*> origin=null + FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.C, :kotlin.Int?) returnType:kotlin.Unit correspondingProperty: PROPERTY name:test8 visibility:public modality:FINAL [delegated,var] $this: VALUE_PARAMETER name: type:.C - VALUE_PARAMETER name: index:0 type:IrErrorType + VALUE_PARAMETER name: index:0 type:kotlin.Int? BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=IrErrorType - GET_VAR ': .C declared in .C' type=.C origin=null - PROPERTY_REFERENCE 'public final test8: IrErrorType [delegated,var]' field='FIELD PROPERTY_DELEGATE name:test8$delegate type:java.util.HashMap visibility:private [final]' getter='public final fun (): IrErrorType declared in .C' setter='public final fun (: IrErrorType): kotlin.Unit declared in .C' type=kotlin.reflect.KProperty<*> origin=null - GET_VAR ': IrErrorType declared in .C.' type=IrErrorType origin=null + CALL 'public final fun setValue (thisRef: kotlin.Any?, property: kotlin.reflect.KProperty<*>, value: V of kotlin.collections.setValue): kotlin.Unit [inline,operator] declared in kotlin.collections' type=kotlin.Unit origin=null + : kotlin.Int? + $receiver: GET_FIELD 'FIELD PROPERTY_DELEGATE name:test8$delegate type:java.util.HashMap visibility:private [final]' type=java.util.HashMap origin=GET_PROPERTY + thisRef: GET_VAR ': .C declared in .C' type=.C origin=null + property: PROPERTY_REFERENCE 'public final test8: kotlin.Int? [delegated,var]' field='FIELD PROPERTY_DELEGATE name:test8$delegate type:java.util.HashMap visibility:private [final]' getter='public final fun (): kotlin.Int? declared in .C' setter='public final fun (: kotlin.Int?): kotlin.Unit declared in .C' type=kotlin.reflect.KProperty<*> origin=null + value: GET_VAR ': kotlin.Int? declared in .C.' type=kotlin.Int? origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/declarations/delegatedProperties.fir.txt b/compiler/testData/ir/irText/declarations/delegatedProperties.fir.txt index 71693eff27f..03394432875 100644 --- a/compiler/testData/ir/irText/declarations/delegatedProperties.fir.txt +++ b/compiler/testData/ir/irText/declarations/delegatedProperties.fir.txt @@ -61,23 +61,28 @@ FILE fqName: fileName:/delegatedProperties.kt FIELD PROPERTY_DELEGATE name:test3$delegate type:kotlin.collections.MutableMap visibility:private [final] EXPRESSION_BODY GET_VAR 'map: kotlin.collections.MutableMap declared in .C.' type=kotlin.collections.MutableMap origin=null - FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.C) returnType:IrErrorType + FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.C) returnType:kotlin.Any correspondingProperty: PROPERTY name:test3 visibility:public modality:FINAL [delegated,var] $this: VALUE_PARAMETER name: type:.C BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): IrErrorType declared in .C' - ERROR_CALL 'Unresolved reference: #' type=IrErrorType - GET_VAR ': .C declared in .C' type=.C origin=null - PROPERTY_REFERENCE 'public final test3: IrErrorType [delegated,var]' field='FIELD PROPERTY_DELEGATE name:test3$delegate type:kotlin.collections.MutableMap visibility:private [final]' getter='public final fun (): IrErrorType declared in .C' setter='public final fun (: IrErrorType): kotlin.Unit declared in .C' type=kotlin.reflect.KProperty<*> origin=null - FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.C, :IrErrorType) returnType:kotlin.Unit + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Any declared in .C' + CALL 'public final fun getValue (thisRef: kotlin.Any?, property: kotlin.reflect.KProperty<*>): V1 of kotlin.collections.getValue [inline,operator] declared in kotlin.collections' type=kotlin.Any origin=null + : kotlin.Any + : kotlin.Any + $receiver: GET_FIELD 'FIELD PROPERTY_DELEGATE name:test3$delegate type:kotlin.collections.MutableMap visibility:private [final]' type=kotlin.collections.MutableMap origin=GET_PROPERTY + thisRef: GET_VAR ': .C declared in .C' type=.C origin=null + property: PROPERTY_REFERENCE 'public final test3: kotlin.Any [delegated,var]' field='FIELD PROPERTY_DELEGATE name:test3$delegate type:kotlin.collections.MutableMap visibility:private [final]' getter='public final fun (): kotlin.Any declared in .C' setter='public final fun (: kotlin.Any): kotlin.Unit declared in .C' type=kotlin.reflect.KProperty<*> origin=null + FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.C, :kotlin.Any) returnType:kotlin.Unit correspondingProperty: PROPERTY name:test3 visibility:public modality:FINAL [delegated,var] $this: VALUE_PARAMETER name: type:.C - VALUE_PARAMETER name: index:0 type:IrErrorType + VALUE_PARAMETER name: index:0 type:kotlin.Any BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=IrErrorType - GET_VAR ': .C declared in .C' type=.C origin=null - PROPERTY_REFERENCE 'public final test3: IrErrorType [delegated,var]' field='FIELD PROPERTY_DELEGATE name:test3$delegate type:kotlin.collections.MutableMap visibility:private [final]' getter='public final fun (): IrErrorType declared in .C' setter='public final fun (: IrErrorType): kotlin.Unit declared in .C' type=kotlin.reflect.KProperty<*> origin=null - GET_VAR ': IrErrorType declared in .C.' type=IrErrorType origin=null + CALL 'public final fun setValue (thisRef: kotlin.Any?, property: kotlin.reflect.KProperty<*>, value: V of kotlin.collections.setValue): kotlin.Unit [inline,operator] declared in kotlin.collections' type=kotlin.Unit origin=null + : kotlin.Any + $receiver: GET_FIELD 'FIELD PROPERTY_DELEGATE name:test3$delegate type:kotlin.collections.MutableMap visibility:private [final]' type=kotlin.collections.MutableMap origin=GET_PROPERTY + thisRef: GET_VAR ': .C declared in .C' type=.C origin=null + property: PROPERTY_REFERENCE 'public final test3: kotlin.Any [delegated,var]' field='FIELD PROPERTY_DELEGATE name:test3$delegate type:kotlin.collections.MutableMap visibility:private [final]' getter='public final fun (): kotlin.Any declared in .C' setter='public final fun (: kotlin.Any): kotlin.Unit declared in .C' type=kotlin.reflect.KProperty<*> origin=null + value: GET_VAR ': kotlin.Any declared in .C.' type=kotlin.Any origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any @@ -97,18 +102,23 @@ FILE fqName: fileName:/delegatedProperties.kt CALL 'public final fun hashMapOf (): java.util.HashMap [inline] declared in kotlin.collections' type=java.util.HashMap origin=null : kotlin.String : kotlin.Any - FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:IrErrorType + FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.Any? correspondingProperty: PROPERTY name:test4 visibility:public modality:FINAL [delegated,var] BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): IrErrorType declared in ' - ERROR_CALL 'Unresolved reference: #' type=IrErrorType - CONST Null type=kotlin.Nothing? value=null - PROPERTY_REFERENCE 'public final test4: IrErrorType [delegated,var]' field='FIELD PROPERTY_DELEGATE name:test4$delegate type:java.util.HashMap visibility:private [final,static]' getter='public final fun (): IrErrorType declared in ' setter='public final fun (: IrErrorType): kotlin.Unit declared in ' type=kotlin.reflect.KProperty<*> origin=null - FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> (:IrErrorType) returnType:kotlin.Unit + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Any? declared in ' + CALL 'public final fun getValue (thisRef: kotlin.Any?, property: kotlin.reflect.KProperty<*>): V1 of kotlin.collections.getValue [inline,operator] declared in kotlin.collections' type=kotlin.Any? origin=null + : kotlin.Any? + : kotlin.Any? + $receiver: GET_FIELD 'FIELD PROPERTY_DELEGATE name:test4$delegate type:java.util.HashMap visibility:private [final,static]' type=java.util.HashMap origin=GET_PROPERTY + thisRef: CONST Null type=kotlin.Nothing? value=null + property: PROPERTY_REFERENCE 'public final test4: kotlin.Any? [delegated,var]' field='FIELD PROPERTY_DELEGATE name:test4$delegate type:java.util.HashMap visibility:private [final,static]' getter='public final fun (): kotlin.Any? declared in ' setter='public final fun (: kotlin.Any?): kotlin.Unit declared in ' type=kotlin.reflect.KProperty<*> origin=null + FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> (:kotlin.Any?) returnType:kotlin.Unit correspondingProperty: PROPERTY name:test4 visibility:public modality:FINAL [delegated,var] - VALUE_PARAMETER name: index:0 type:IrErrorType + VALUE_PARAMETER name: index:0 type:kotlin.Any? BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=IrErrorType - CONST Null type=kotlin.Nothing? value=null - PROPERTY_REFERENCE 'public final test4: IrErrorType [delegated,var]' field='FIELD PROPERTY_DELEGATE name:test4$delegate type:java.util.HashMap visibility:private [final,static]' getter='public final fun (): IrErrorType declared in ' setter='public final fun (: IrErrorType): kotlin.Unit declared in ' type=kotlin.reflect.KProperty<*> origin=null - GET_VAR ': IrErrorType declared in .' type=IrErrorType origin=null + CALL 'public final fun setValue (thisRef: kotlin.Any?, property: kotlin.reflect.KProperty<*>, value: V of kotlin.collections.setValue): kotlin.Unit [inline,operator] declared in kotlin.collections' type=kotlin.Unit origin=null + : kotlin.Any? + $receiver: GET_FIELD 'FIELD PROPERTY_DELEGATE name:test4$delegate type:java.util.HashMap visibility:private [final,static]' type=java.util.HashMap origin=GET_PROPERTY + thisRef: CONST Null type=kotlin.Nothing? value=null + property: PROPERTY_REFERENCE 'public final test4: kotlin.Any? [delegated,var]' field='FIELD PROPERTY_DELEGATE name:test4$delegate type:java.util.HashMap visibility:private [final,static]' getter='public final fun (): kotlin.Any? declared in ' setter='public final fun (: kotlin.Any?): kotlin.Unit declared in ' type=kotlin.reflect.KProperty<*> origin=null + value: GET_VAR ': kotlin.Any? declared in .' type=kotlin.Any? origin=null diff --git a/compiler/testData/ir/irText/declarations/localDelegatedProperties.fir.txt b/compiler/testData/ir/irText/declarations/localDelegatedProperties.fir.txt index 517bd7baad5..45ae4a14426 100644 --- a/compiler/testData/ir/irText/declarations/localDelegatedProperties.fir.txt +++ b/compiler/testData/ir/irText/declarations/localDelegatedProperties.fir.txt @@ -6,20 +6,18 @@ FILE fqName: fileName:/localDelegatedProperties.kt message: GET_VAR 'val x: kotlin.Int [val] declared in .test1' type=kotlin.Int origin=null FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY - VAR name:x type:IrErrorType [var] - SET_VAR 'var x: IrErrorType [var] declared in .test2' type=kotlin.Unit origin=null + VAR name:x type:kotlin.Int? [var] + SET_VAR 'var x: kotlin.Int? [var] declared in .test2' type=kotlin.Unit origin=null CONST Int type=kotlin.Int value=0 VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Int [val] TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int - GET_VAR 'var x: IrErrorType [var] declared in .test2' type=IrErrorType origin=null - SET_VAR 'var x: IrErrorType [var] declared in .test2' type=kotlin.Unit origin=null + GET_VAR 'var x: kotlin.Int? [var] declared in .test2' type=kotlin.Int? origin=null + SET_VAR 'var x: kotlin.Int? [var] declared in .test2' type=kotlin.Unit origin=null CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: TYPE_OP type=IrErrorType origin=IMPLICIT_CAST typeOperand=IrErrorType - GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null - TYPE_OP type=IrErrorType origin=IMPLICIT_CAST typeOperand=IrErrorType - GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null - SET_VAR 'var x: IrErrorType [var] declared in .test2' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null + GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null + SET_VAR 'var x: kotlin.Int? [var] declared in .test2' type=kotlin.Unit origin=null CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null $this: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int - GET_VAR 'var x: IrErrorType [var] declared in .test2' type=IrErrorType origin=null + GET_VAR 'var x: kotlin.Int? [var] declared in .test2' type=kotlin.Int? origin=null other: CONST Int type=kotlin.Int value=1 diff --git a/compiler/testData/ir/irText/declarations/packageLevelProperties.fir.txt b/compiler/testData/ir/irText/declarations/packageLevelProperties.fir.txt index db2b414e403..0c442f5e2c3 100644 --- a/compiler/testData/ir/irText/declarations/packageLevelProperties.fir.txt +++ b/compiler/testData/ir/irText/declarations/packageLevelProperties.fir.txt @@ -87,18 +87,23 @@ FILE fqName: fileName:/packageLevelProperties.kt CALL 'public final fun hashMapOf (): java.util.HashMap [inline] declared in kotlin.collections' type=java.util.HashMap origin=null : kotlin.String : kotlin.Int - FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:IrErrorType + FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.Int? correspondingProperty: PROPERTY name:test8 visibility:public modality:FINAL [delegated,var] BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): IrErrorType declared in ' - ERROR_CALL 'Unresolved reference: #' type=IrErrorType - CONST Null type=kotlin.Nothing? value=null - PROPERTY_REFERENCE 'public final test8: IrErrorType [delegated,var]' field='FIELD PROPERTY_DELEGATE name:test8$delegate type:java.util.HashMap visibility:private [final,static]' getter='public final fun (): IrErrorType declared in ' setter='public final fun (: IrErrorType): kotlin.Unit declared in ' type=kotlin.reflect.KProperty<*> origin=null - FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> (:IrErrorType) returnType:kotlin.Unit + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Int? declared in ' + CALL 'public final fun getValue (thisRef: kotlin.Any?, property: kotlin.reflect.KProperty<*>): V1 of kotlin.collections.getValue [inline,operator] declared in kotlin.collections' type=kotlin.Int? origin=null + : kotlin.Int? + : kotlin.Int? + $receiver: GET_FIELD 'FIELD PROPERTY_DELEGATE name:test8$delegate type:java.util.HashMap visibility:private [final,static]' type=java.util.HashMap origin=GET_PROPERTY + thisRef: CONST Null type=kotlin.Nothing? value=null + property: PROPERTY_REFERENCE 'public final test8: kotlin.Int? [delegated,var]' field='FIELD PROPERTY_DELEGATE name:test8$delegate type:java.util.HashMap visibility:private [final,static]' getter='public final fun (): kotlin.Int? declared in ' setter='public final fun (: kotlin.Int?): kotlin.Unit declared in ' type=kotlin.reflect.KProperty<*> origin=null + FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> (:kotlin.Int?) returnType:kotlin.Unit correspondingProperty: PROPERTY name:test8 visibility:public modality:FINAL [delegated,var] - VALUE_PARAMETER name: index:0 type:IrErrorType + VALUE_PARAMETER name: index:0 type:kotlin.Int? BLOCK_BODY - ERROR_CALL 'Unresolved reference: #' type=IrErrorType - CONST Null type=kotlin.Nothing? value=null - PROPERTY_REFERENCE 'public final test8: IrErrorType [delegated,var]' field='FIELD PROPERTY_DELEGATE name:test8$delegate type:java.util.HashMap visibility:private [final,static]' getter='public final fun (): IrErrorType declared in ' setter='public final fun (: IrErrorType): kotlin.Unit declared in ' type=kotlin.reflect.KProperty<*> origin=null - GET_VAR ': IrErrorType declared in .' type=IrErrorType origin=null + CALL 'public final fun setValue (thisRef: kotlin.Any?, property: kotlin.reflect.KProperty<*>, value: V of kotlin.collections.setValue): kotlin.Unit [inline,operator] declared in kotlin.collections' type=kotlin.Unit origin=null + : kotlin.Int? + $receiver: GET_FIELD 'FIELD PROPERTY_DELEGATE name:test8$delegate type:java.util.HashMap visibility:private [final,static]' type=java.util.HashMap origin=GET_PROPERTY + thisRef: CONST Null type=kotlin.Nothing? value=null + property: PROPERTY_REFERENCE 'public final test8: kotlin.Int? [delegated,var]' field='FIELD PROPERTY_DELEGATE name:test8$delegate type:java.util.HashMap visibility:private [final,static]' getter='public final fun (): kotlin.Int? declared in ' setter='public final fun (: kotlin.Int?): kotlin.Unit declared in ' type=kotlin.reflect.KProperty<*> origin=null + value: GET_VAR ': kotlin.Int? declared in .' type=kotlin.Int? origin=null