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 new file mode 100644 index 00000000000..6e8e59fced8 --- /dev/null +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmBinaryAnnotationDeserializer.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. 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.FirSession +import org.jetbrains.kotlin.fir.deserialization.AbstractAnnotationDeserializer +import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall +import org.jetbrains.kotlin.metadata.ProtoBuf +import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf +import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmNameResolver + +class JvmBinaryAnnotationDeserializer( + session: FirSession, nameResolver: JvmNameResolver +) : AbstractAnnotationDeserializer(session, nameResolver) { + override fun loadTypeAnnotations(typeProto: ProtoBuf.Type): List { + val annotations = typeProto.getExtension(JvmProtoBuf.typeAnnotation).orEmpty() + return annotations.map { deserializeAnnotation(it) } + } +} \ 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 0db123a0d19..38613113657 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 @@ -100,7 +100,10 @@ class KotlinDeserializedJvmSymbolsProvider( PackagePartsCacheData( packageProto, - FirDeserializationContext.createForPackage(packageFqName, packageProto, nameResolver, session) + FirDeserializationContext.createForPackage( + packageFqName, packageProto, nameResolver, session, + JvmBinaryAnnotationDeserializer(session, nameResolver) + ) ) } } @@ -272,7 +275,6 @@ class KotlinDeserializedJvmSymbolsProvider( return loadAnnotation(annotationClassId, result) } - private fun findAndDeserializeClass( classId: ClassId, parentContext: FirDeserializationContext? = null @@ -299,7 +301,11 @@ class KotlinDeserializedJvmSymbolsProvider( val symbol = FirClassSymbol(classId) deserializeClassToSymbol( - classId, classProto, symbol, nameResolver, session, parentContext, + classId, classProto, symbol, nameResolver, session, + parentContext ?: FirDeserializationContext.createForClass( + classId, classProto, nameResolver, session, + JvmBinaryAnnotationDeserializer(session, nameResolver) + ), this::findAndDeserializeClass ) val annotations = mutableListOf() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirAnnotationDeserializer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt similarity index 89% rename from compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirAnnotationDeserializer.kt rename to compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt index 1e3bc20176c..4cf528831be 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirAnnotationDeserializer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt @@ -29,11 +29,11 @@ import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerial import org.jetbrains.kotlin.serialization.deserialization.getClassId import org.jetbrains.kotlin.serialization.deserialization.getName -class FirAnnotationDeserializer( +abstract class AbstractAnnotationDeserializer( private val session: FirSession, private val nameResolver: NameResolver ) { - private val protocol = BuiltInSerializerProtocol + protected val protocol = BuiltInSerializerProtocol fun loadClassAnnotations(classProto: ProtoBuf.Class): List { if (!Flags.HAS_ANNOTATIONS.get(classProto.flags)) return emptyList() @@ -65,13 +65,9 @@ class FirAnnotationDeserializer( return annotations.map { deserializeAnnotation(it) } } - fun loadTypeAnnotations(typeProto: ProtoBuf.Type): List { - if (!Flags.HAS_ANNOTATIONS.get(typeProto.flags)) return emptyList() - val annotations = typeProto.getExtension(protocol.typeAnnotation).orEmpty() - return annotations.map { deserializeAnnotation(it) } - } + abstract fun loadTypeAnnotations(typeProto: ProtoBuf.Type): List - private fun deserializeAnnotation(proto: ProtoBuf.Annotation): FirAnnotationCall { + fun deserializeAnnotation(proto: ProtoBuf.Annotation): FirAnnotationCall { val classId = nameResolver.getClassId(proto.id) val lookupTag = ConeClassLikeLookupTagImpl(classId) val symbol = lookupTag.toSymbol(session) @@ -126,12 +122,12 @@ class FirAnnotationDeserializer( CLASS -> FirGetClassCallImpl(session, null).apply { val classId = nameResolver.getClassId(value.classId) val lookupTag = ConeClassLikeLookupTagImpl(classId) - val symbol = lookupTag.toSymbol(this@FirAnnotationDeserializer.session) ?: return null + val symbol = lookupTag.toSymbol(this@AbstractAnnotationDeserializer.session) ?: return null val referencedType = symbol.constructType(emptyArray(), isNullable = false) arguments += FirClassReferenceExpressionImpl( - this@FirAnnotationDeserializer.session, null, + this@AbstractAnnotationDeserializer.session, null, FirResolvedTypeRefImpl( - this@FirAnnotationDeserializer.session, null, referencedType, + this@AbstractAnnotationDeserializer.session, null, referencedType, isMarkedNullable = false, annotations = emptyList() ) ) @@ -141,11 +137,11 @@ class FirAnnotationDeserializer( val entryName = nameResolver.getName(value.enumValueId) val entryClassId = classId.createNestedClassId(entryName) val entryLookupTag = ConeClassLikeLookupTagImpl(entryClassId) - val entrySymbol = entryLookupTag.toSymbol(this@FirAnnotationDeserializer.session) + val entrySymbol = entryLookupTag.toSymbol(this@AbstractAnnotationDeserializer.session) this.calleeReference = entrySymbol?.let { - FirResolvedCallableReferenceImpl(this@FirAnnotationDeserializer.session, null, entryName, it) + FirResolvedCallableReferenceImpl(this@AbstractAnnotationDeserializer.session, null, entryName, it) } ?: FirErrorNamedReference( - this@FirAnnotationDeserializer.session, null, + this@AbstractAnnotationDeserializer.session, null, errorReason = "Strange deserialized enum value: $classId.$entryName" ) } 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 eb047af24b0..8e7e15ba644 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 @@ -45,8 +45,9 @@ fun deserializeClassToSymbol( val context = parentContext?.childContext(classProto.typeParameterList, nameResolver, TypeTable(classProto.typeTable)) - ?: FirDeserializationContext - .createForClass(classId, classProto, nameResolver, session) + ?: FirDeserializationContext.createForClass( + classId, classProto, nameResolver, session, FirBuiltinAnnotationDeserializer(session, nameResolver) + ) typeParameters += context.typeDeserializer.ownTypeParameters.map { it.firUnsafe() } annotations += context.annotationDeserializer.loadClassAnnotations(classProto) 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 new file mode 100644 index 00000000000..c78c0e29331 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirBuiltinAnnotationDeserializer.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. 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.expressions.FirAnnotationCall +import org.jetbrains.kotlin.metadata.ProtoBuf +import org.jetbrains.kotlin.metadata.deserialization.Flags +import org.jetbrains.kotlin.metadata.deserialization.NameResolver + +class FirBuiltinAnnotationDeserializer( + session: FirSession, nameResolver: NameResolver +) : AbstractAnnotationDeserializer(session, nameResolver) { + + override fun loadTypeAnnotations(typeProto: ProtoBuf.Type): List { + if (!Flags.HAS_ANNOTATIONS.get(typeProto.flags)) return emptyList() + val annotations = typeProto.getExtension(protocol.typeAnnotation).orEmpty() + return annotations.map { deserializeAnnotation(it) } + } +} \ No newline at end of file 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 263d38571f4..f441e72ef8e 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 @@ -37,6 +37,7 @@ class FirDeserializationContext( val packageFqName: FqName, val relativeClassName: FqName?, val typeDeserializer: FirTypeDeserializer, + val annotationDeserializer: AbstractAnnotationDeserializer, val components: FirDeserializationComponents ) { fun childContext( @@ -48,23 +49,23 @@ class FirDeserializationContext( FirTypeDeserializer( session, nameResolver, typeTable, typeParameterProtos, typeDeserializer ), - components + annotationDeserializer, components ) val memberDeserializer: FirMemberDeserializer = FirMemberDeserializer(this) - val annotationDeserializer: FirAnnotationDeserializer = FirAnnotationDeserializer(session, nameResolver) - companion object { fun createForPackage( fqName: FqName, packageProto: ProtoBuf.Package, nameResolver: NameResolver, - session: FirSession + session: FirSession, + annotationDeserializer: AbstractAnnotationDeserializer ) = createRootContext( nameResolver, TypeTable(packageProto.typeTable), session, + annotationDeserializer, fqName, relativeClassName = null, typeParameterProtos = emptyList() @@ -74,11 +75,13 @@ class FirDeserializationContext( classId: ClassId, classProto: ProtoBuf.Class, nameResolver: NameResolver, - session: FirSession + session: FirSession, + annotationDeserializer: AbstractAnnotationDeserializer ) = createRootContext( nameResolver, TypeTable(classProto.typeTable), session, + annotationDeserializer, classId.packageFqName, classId.relativeClassName, classProto.typeParameterList @@ -88,6 +91,7 @@ class FirDeserializationContext( nameResolver: NameResolver, typeTable: TypeTable, session: FirSession, + annotationDeserializer: AbstractAnnotationDeserializer, packageFqName: FqName, relativeClassName: FqName?, typeParameterProtos: List @@ -105,6 +109,7 @@ class FirDeserializationContext( typeParameterProtos, null ), + annotationDeserializer, FirDeserializationComponents() ) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirLibrarySymbolProviderImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirLibrarySymbolProviderImpl.kt index 30993b05853..5daf7feb955 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirLibrarySymbolProviderImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirLibrarySymbolProviderImpl.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.impl.FirClassImpl import org.jetbrains.kotlin.fir.declarations.impl.FirEnumEntryImpl +import org.jetbrains.kotlin.fir.deserialization.FirBuiltinAnnotationDeserializer import org.jetbrains.kotlin.fir.deserialization.FirDeserializationContext import org.jetbrains.kotlin.fir.deserialization.deserializeClassToSymbol import org.jetbrains.kotlin.fir.resolve.* @@ -65,7 +66,10 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider val classDataFinder = ProtoBasedClassDataFinder(packageProto, nameResolver, version) { SourceElement.NO_SOURCE } private val memberDeserializer by lazy { - FirDeserializationContext.createForPackage(fqName, packageProto.`package`, nameResolver, session).memberDeserializer + FirDeserializationContext.createForPackage( + fqName, packageProto.`package`, nameResolver, session, + FirBuiltinAnnotationDeserializer(session, nameResolver) + ).memberDeserializer } val lookup = mutableMapOf() diff --git a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/types/ClassLiteralArgument.txt b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/types/ClassLiteralArgument.txt index 69f5b7cdabe..c1ce1028bb4 100644 --- a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/types/ClassLiteralArgument.txt +++ b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/types/ClassLiteralArgument.txt @@ -1,17 +1,17 @@ public final class A : R|kotlin/Any| { - public final fun arrays(s: R|kotlin/Array|, t: R|kotlin/Array|, u: R|kotlin/Array>|, v: R|kotlin/Array>>|): R|kotlin/Unit| + public final fun arrays(s: @R|test/Ann|(klass = ((R|kotlin/Int|))) R|kotlin/Array|, t: @R|test/Ann|(klass = ((R|kotlin/IntArray|))) R|kotlin/Array|, u: @R|test/Ann|(klass = ((R|kotlin/Int|))) R|kotlin/Array>|, v: @R|test/Ann|(klass = ((R|kotlin/String|))) R|kotlin/Array>>|): R|kotlin/Unit| - public final fun generic(s: R|kotlin/String|): R|kotlin/Unit| + public final fun generic(s: @R|test/Ann|(klass = ((R|test/Generic|))) R|kotlin/String|): R|kotlin/Unit| - public final fun innerGeneric(s: R|kotlin/String|): R|kotlin/Unit| + public final fun innerGeneric(s: @R|test/Ann|(klass = ((R|test/InnerGeneric.Inner|))) R|kotlin/String|): R|kotlin/Unit| - public final fun simple(s: R|kotlin/String|): R|kotlin/Unit| + public final fun simple(s: @R|test/Ann|(klass = ((R|test/Simple|))) R|kotlin/String|): R|kotlin/Unit| public constructor(): R|test/A| } -public final annotation class Ann : R|kotlin/Annotation| { +@R|kotlin/annotation/Target|(allowedTargets = (R|kotlin/annotation/AnnotationTarget.TYPE|())) public final annotation class Ann : R|kotlin/Annotation| { public final val klass: R|kotlin/reflect/KClass<*>| public get(): R|kotlin/reflect/KClass<*>| diff --git a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/types/ReceiverParameter.txt b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/types/ReceiverParameter.txt index beb3006bea4..1e558b421dc 100644 --- a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/types/ReceiverParameter.txt +++ b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/types/ReceiverParameter.txt @@ -1,6 +1,6 @@ -public final fun R|kotlin/String|.foo(): R|kotlin/Unit| +public final fun @R|test/A|() R|kotlin/String|.foo(): R|kotlin/Unit| -public final annotation class A : R|kotlin/Annotation| { +@R|kotlin/annotation/Target|(allowedTargets = (R|kotlin/annotation/AnnotationTarget.TYPE|())) public final annotation class A : R|kotlin/Annotation| { public constructor(): R|test/A| } diff --git a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/types/SimpleTypeAnnotation.txt b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/types/SimpleTypeAnnotation.txt index 85a99c727e7..3631a7836d9 100644 --- a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/types/SimpleTypeAnnotation.txt +++ b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/types/SimpleTypeAnnotation.txt @@ -1,10 +1,10 @@ -public final annotation class A : R|kotlin/Annotation| { +@R|kotlin/annotation/Target|(allowedTargets = (R|kotlin/annotation/AnnotationTarget.TYPE|())) public final annotation class A : R|kotlin/Annotation| { public constructor(): R|test/A| } public final class SimpleTypeAnnotation : R|kotlin/Any| { - public final fun foo(x: R|kotlin/ranges/IntRange|): R|kotlin/Int| + public final fun foo(x: @R|test/A|() R|kotlin/ranges/IntRange|): @R|test/A|() R|kotlin/Int| public constructor(): R|test/SimpleTypeAnnotation| diff --git a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/types/TypeAnnotationWithArguments.txt b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/types/TypeAnnotationWithArguments.txt index d09a220cdae..d6858f5175b 100644 --- a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/types/TypeAnnotationWithArguments.txt +++ b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/types/TypeAnnotationWithArguments.txt @@ -10,7 +10,7 @@ } public final class TypeAnnotationWithArguments : R|kotlin/Any| { - public final fun foo(param: R|kotlin/ranges/IntRange|): R|kotlin/Unit| + public final fun foo(param: @R|test/Ann|(x = String(param), y = Double(3.14)) R|kotlin/ranges/IntRange|): @R|test/Ann|(x = String(fun), y = Double(2.72)) R|kotlin/Unit| public constructor(): R|test/TypeAnnotationWithArguments| diff --git a/compiler/fir/resolve/testData/loadCompiledKotlin/coroutines/Basic.txt b/compiler/fir/resolve/testData/loadCompiledKotlin/coroutines/Basic.txt index eb6291f6e79..1727bf2edad 100644 --- a/compiler/fir/resolve/testData/loadCompiledKotlin/coroutines/Basic.txt +++ b/compiler/fir/resolve/testData/loadCompiledKotlin/coroutines/Basic.txt @@ -1,4 +1,4 @@ -public final fun builder(c: R|class error: createSuspendFunctionType not supported|): R|kotlin/Unit| +public final fun builder(c: @R|kotlin/ExtensionFunctionType|() R|class error: createSuspendFunctionType not supported|): R|kotlin/Unit| public final class Controller : R|kotlin/Any| { public final suspend fun suspendFun(): R|kotlin/Unit| diff --git a/compiler/fir/resolve/testData/loadCompiledKotlin/fromLoadJava/kotlinSignature/MethodWithFunctionTypes.txt b/compiler/fir/resolve/testData/loadCompiledKotlin/fromLoadJava/kotlinSignature/MethodWithFunctionTypes.txt index 2ef3b1e67f1..1067e3b9add 100644 --- a/compiler/fir/resolve/testData/loadCompiledKotlin/fromLoadJava/kotlinSignature/MethodWithFunctionTypes.txt +++ b/compiler/fir/resolve/testData/loadCompiledKotlin/fromLoadJava/kotlinSignature/MethodWithFunctionTypes.txt @@ -1,5 +1,5 @@ public open class MethodWithFunctionTypes : R|kotlin/Any| { - public open fun foo(f: R|kotlin/Function1|): R|kotlin/Function1|? + public open fun foo(f: R|kotlin/Function1|): @R|kotlin/ExtensionFunctionType|() R|kotlin/Function1|? public constructor(): R|test/MethodWithFunctionTypes| diff --git a/compiler/fir/resolve/testData/loadCompiledKotlin/type/SuspendFunction.txt b/compiler/fir/resolve/testData/loadCompiledKotlin/type/SuspendFunction.txt index 9757c2f1505..4b61728ec8c 100644 --- a/compiler/fir/resolve/testData/loadCompiledKotlin/type/SuspendFunction.txt +++ b/compiler/fir/resolve/testData/loadCompiledKotlin/type/SuspendFunction.txt @@ -1,6 +1,6 @@ public final fun test1(): R|class error: createSuspendFunctionType not supported| -public final fun test2(): R|class error: createSuspendFunctionType not supported| +public final fun test2(): @R|kotlin/ExtensionFunctionType|() R|class error: createSuspendFunctionType not supported| public final fun test3(): R|kotlin/collections/List| diff --git a/compiler/fir/resolve/testData/loadCompiledKotlin/typealias/TypeAliasToExtension.txt b/compiler/fir/resolve/testData/loadCompiledKotlin/typealias/TypeAliasToExtension.txt index c39a9b2429c..5bc662a86d9 100644 --- a/compiler/fir/resolve/testData/loadCompiledKotlin/typealias/TypeAliasToExtension.txt +++ b/compiler/fir/resolve/testData/loadCompiledKotlin/typealias/TypeAliasToExtension.txt @@ -1,4 +1,4 @@ -public final fun

foo(x: R|kotlin/Function1, kotlin/Unit>|): R|kotlin/Unit| +public final fun

foo(x: @R|kotlin/ExtensionFunctionType|() R|kotlin/Function1, kotlin/Unit>|): R|kotlin/Unit| public final class Foo : R|kotlin/Any| { public constructor(): R|test/Foo|