提交 b076bec0 编写于 作者: J Jinseong Jeon 提交者: Denis Zharkov

FIR deserializer: signature-aware annotation loading for functions

上级 11a680d7
public open class AnnotatedMethod : R|kotlin/Any| {
public open fun f(): R|kotlin/Unit|
@R|kotlin/Deprecated|(message = String(Deprecated in Java)) public open fun f(): R|kotlin/Unit|
public constructor(): R|test/AnnotatedMethod|
......
......@@ -19,7 +19,7 @@ public final annotation class EnumAnno : R|kotlin/Annotation| {
}
public final class EnumArgumentWithCustomToString : R|kotlin/Any| {
public final fun annotated(): R|kotlin/Unit|
@R|test/EnumAnno|(value = R|test/E.CAKE|()) @R|test/EnumArrayAnno|(value = <implicitArrayOf>(R|test/E.CAKE|(), R|test/E.CAKE|())) public final fun annotated(): R|kotlin/Unit|
public constructor(): R|test/EnumArgumentWithCustomToString|
......
......@@ -7,7 +7,7 @@ public final annotation class Anno : R|kotlin/Annotation| {
}
public abstract interface T : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Array<kotlin/Array<kotlin/Array<test/T>>>|
@R|test/Anno|(s = String(foo)) public abstract fun foo(): R|kotlin/Array<kotlin/Array<kotlin/Array<test/T>>>|
public abstract val bar: R|kotlin/Array<kotlin/Array<kotlin/BooleanArray>>|
public get(): R|kotlin/Array<kotlin/Array<kotlin/BooleanArray>>|
......
......@@ -7,7 +7,7 @@ public final annotation class Anno : R|kotlin/Annotation| {
}
public final class Class : R|kotlin/Any| {
public final fun foo(): R|kotlin/Unit|
@R|test/Anno|(t = R|java/lang/annotation/ElementType.METHOD|()) public final fun foo(): R|kotlin/Unit|
public final var bar: R|kotlin/Int|
public get(): R|kotlin/Int|
......
......@@ -4,7 +4,7 @@ public final annotation class Anno : R|kotlin/Annotation| {
}
public final class Class : R|kotlin/Any| {
public final fun foo(): R|kotlin/Unit|
@R|test/Anno|() public final fun foo(): R|kotlin/Unit|
public constructor(): R|test/Class|
......
......@@ -9,7 +9,7 @@ public final class A : R|kotlin/Any| {
}
@R|test/A.Anno|() public final class B : R|kotlin/Any| {
public final fun f(): R|kotlin/Unit|
@R|test/A.Anno|() public final fun f(): R|kotlin/Unit|
public constructor(): R|test/B|
......
public final fun foo(): R|kotlin/Unit|
@R|test/Anno|(t = R|java/lang/annotation/ElementType.METHOD|()) public final fun foo(): R|kotlin/Unit|
public final annotation class Anno : R|kotlin/Annotation| {
public final val t: R|java/lang/annotation/ElementType|
......
public final fun baz(): R|kotlin/Unit|
@R|test/Anno|(t = <implicitArrayOf>()) public final fun baz(): R|kotlin/Unit|
public final fun foo(): R|kotlin/Unit|
@R|test/Anno|(t = <implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.FIELD|())) public final fun foo(): R|kotlin/Unit|
public final annotation class Anno : R|kotlin/Annotation| {
public final val t: R|kotlin/Array<out java/lang/annotation/ElementType>|
......
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|
......
public final fun baz(): R|kotlin/Unit|
@R|test/Anno|(t = <implicitArrayOf>()) public final fun baz(): R|kotlin/Unit|
public final fun foo(): R|kotlin/Unit|
@R|test/Anno|(t = <implicitArrayOf>(String(live), String(long))) public final fun foo(): R|kotlin/Unit|
public final annotation class Anno : R|kotlin/Annotation| {
public final val t: R|kotlin/Array<out kotlin/String>|
......
......@@ -17,8 +17,10 @@ import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
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
......@@ -33,6 +35,7 @@ class JvmBinaryAnnotationDeserializer(
private data class MemberAnnotations(val memberAnnotations: Map<MemberSignature, MutableList<FirAnnotationCall>>)
private enum class CallableKind {
FUNCTION,
PROPERTY_GETTER,
PROPERTY_SETTER
}
......@@ -42,36 +45,55 @@ class JvmBinaryAnnotationDeserializer(
return annotations.map { deserializeAnnotation(it, nameResolver) }
}
override fun loadFunctionAnnotations(
containerSource: DeserializedContainerSource?,
functionProto: ProtoBuf.Function,
nameResolver: NameResolver,
typeTable: TypeTable
): List<FirAnnotationCall> {
val signature = getCallableSignature(functionProto, nameResolver, typeTable, CallableKind.FUNCTION) ?: return emptyList()
return findJvmBinaryClassAndLoadMemberAnnotations(containerSource, signature)
}
override fun loadPropertyGetterAnnotations(
containerSource: DeserializedContainerSource?,
propertyProto: ProtoBuf.Property,
nameResolver: NameResolver,
typeTable: TypeTable,
getterFlags: Int
): List<FirAnnotationCall> {
val signature = getCallableSignature(propertyProto, nameResolver, CallableKind.PROPERTY_GETTER) ?: return emptyList()
val kotlinClass = containerSource?.toKotlinJvmBinaryClass() ?: return emptyList()
return loadMemberAnnotations(kotlinClass).memberAnnotations[signature] ?: emptyList()
val signature = getCallableSignature(propertyProto, nameResolver, typeTable, CallableKind.PROPERTY_GETTER) ?: return emptyList()
return findJvmBinaryClassAndLoadMemberAnnotations(containerSource, signature)
}
override fun loadPropertySetterAnnotations(
containerSource: DeserializedContainerSource?,
propertyProto: ProtoBuf.Property,
nameResolver: NameResolver,
typeTable: TypeTable,
setterFlags: Int
): List<FirAnnotationCall> {
val signature = getCallableSignature(propertyProto, nameResolver, CallableKind.PROPERTY_SETTER) ?: return emptyList()
val kotlinClass = containerSource?.toKotlinJvmBinaryClass() ?: return emptyList()
return loadMemberAnnotations(kotlinClass).memberAnnotations[signature] ?: emptyList()
val signature = getCallableSignature(propertyProto, nameResolver, typeTable, CallableKind.PROPERTY_SETTER) ?: return emptyList()
return findJvmBinaryClassAndLoadMemberAnnotations(containerSource, signature)
}
private fun getCallableSignature(
proto: MessageLite,
nameResolver: NameResolver,
typeTable: TypeTable,
kind: CallableKind
): MemberSignature? {
return when (proto) {
// TODO: ProtoBuf.Constructor
// TODO: ProtoBuf.Function
is ProtoBuf.Function -> {
val signature = JvmProtoBufUtil.getJvmMethodSignature(proto, nameResolver, typeTable) ?: return null
// TODO: Investigate why annotations for accessors affect resolution, resulting in dangling type parameter.
// regressions: Fir2IrTextTest.Declarations.test*LevelProperties
if (signature.name.startsWith("get") || signature.name.startsWith("set")) {
return null
}
MemberSignature.fromJvmMemberSignature(signature)
}
is ProtoBuf.Property -> {
val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature) ?: return null
when (kind) {
......@@ -80,12 +102,22 @@ class JvmBinaryAnnotationDeserializer(
CallableKind.PROPERTY_SETTER ->
if (signature.hasSetter()) MemberSignature.fromMethod(nameResolver, signature.setter) else null
// TODO: PROPERTY
else ->
null
}
}
else -> null
}
}
private fun findJvmBinaryClassAndLoadMemberAnnotations(
containerSource: DeserializedContainerSource?,
memberSignature: MemberSignature
): List<FirAnnotationCall> {
val kotlinClass = containerSource?.toKotlinJvmBinaryClass() ?: return emptyList()
return loadMemberAnnotations(kotlinClass).memberAnnotations[memberSignature] ?: emptyList()
}
private fun DeserializedContainerSource.toKotlinJvmBinaryClass(): KotlinJvmBinaryClass? =
when (this) {
is JvmPackagePartSource -> this.knownJvmBinaryClass
......
......@@ -29,6 +29,7 @@ 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.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.serialization.deserialization.getClassId
......@@ -45,7 +46,12 @@ abstract class AbstractAnnotationDeserializer(
return annotations.map { deserializeAnnotation(it, nameResolver) }
}
fun loadFunctionAnnotations(functionProto: ProtoBuf.Function, nameResolver: NameResolver): List<FirAnnotationCall> {
open fun loadFunctionAnnotations(
containerSource: DeserializedContainerSource?,
functionProto: ProtoBuf.Function,
nameResolver: NameResolver,
typeTable: TypeTable
): List<FirAnnotationCall> {
if (!Flags.HAS_ANNOTATIONS.get(functionProto.flags)) return emptyList()
val annotations = functionProto.getExtension(protocol.functionAnnotation).orEmpty()
return annotations.map { deserializeAnnotation(it, nameResolver) }
......@@ -61,6 +67,7 @@ abstract class AbstractAnnotationDeserializer(
containerSource: DeserializedContainerSource?,
propertyProto: ProtoBuf.Property,
nameResolver: NameResolver,
typeTable: TypeTable,
getterFlags: Int
): List<FirAnnotationCall> {
if (!Flags.HAS_ANNOTATIONS.get(getterFlags)) return emptyList()
......@@ -72,6 +79,7 @@ abstract class AbstractAnnotationDeserializer(
containerSource: DeserializedContainerSource?,
propertyProto: ProtoBuf.Property,
nameResolver: NameResolver,
typeTable: TypeTable,
setterFlags: Int
): List<FirAnnotationCall> {
if (!Flags.HAS_ANNOTATIONS.get(setterFlags)) return emptyList()
......
......@@ -196,7 +196,9 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
isGetter = true
status = FirDeclarationStatusImpl(visibility, modality)
annotations +=
c.annotationDeserializer.loadPropertyGetterAnnotations(c.containerSource, proto, local.nameResolver, getterFlags)
c.annotationDeserializer.loadPropertyGetterAnnotations(
c.containerSource, proto, local.nameResolver, local.typeTable, getterFlags
)
this.symbol = FirPropertyAccessorSymbol()
}
} else {
......@@ -218,7 +220,9 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
isGetter = false
status = FirDeclarationStatusImpl(visibility, modality)
annotations +=
c.annotationDeserializer.loadPropertySetterAnnotations(c.containerSource, proto, local.nameResolver, setterFlags)
c.annotationDeserializer.loadPropertySetterAnnotations(
c.containerSource, proto, local.nameResolver, local.typeTable, setterFlags
)
this.symbol = FirPropertyAccessorSymbol()
valueParameters += proto.setterValueParameter.let {
val parameterFlags = if (it.hasFlags()) it.flags else 0
......@@ -316,7 +320,8 @@ 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 +=
c.annotationDeserializer.loadFunctionAnnotations(c.containerSource, proto, local.nameResolver, local.typeTable)
this.containerSource = c.containerSource
}
if (proto.hasContract()) {
......
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// KJS_WITH_FULL_RUNTIME
fun foo(): Array<Boolean> {
......
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// KJS_WITH_FULL_RUNTIME
fun foo(): Array<Boolean> {
......
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
// Auto-generated by GenerateInRangeExpressionTestData. Do not edit!
// WITH_RUNTIME
......
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
// Auto-generated by GenerateInRangeExpressionTestData. Do not edit!
// WITH_RUNTIME
......
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
// Auto-generated by GenerateInRangeExpressionTestData. Do not edit!
// WITH_RUNTIME
......
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
// Auto-generated by GenerateInRangeExpressionTestData. Do not edit!
// WITH_RUNTIME
......
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
// Auto-generated by GenerateInRangeExpressionTestData. Do not edit!
// WITH_RUNTIME
......
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
// Auto-generated by GenerateInRangeExpressionTestData. Do not edit!
// WITH_RUNTIME
......
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
// Auto-generated by GenerateInRangeExpressionTestData. Do not edit!
// WITH_RUNTIME
......
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
// Auto-generated by GenerateInRangeExpressionTestData. Do not edit!
// WITH_RUNTIME
......
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
// Auto-generated by GenerateInRangeExpressionTestData. Do not edit!
// WITH_RUNTIME
......
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
fun inInt(x: Long): Boolean {
......
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// TODO: muted automatically, investigate should it be ran for JS or not
......
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
fun box(): String {
......
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
......
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
......
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
......
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
......
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册