FIR deserializer: fix parameter shift for constructor of inner classes and enums

#KT-39837 Fixed
This commit is contained in:
Jinseong Jeon
2020-06-30 11:50:25 -07:00
committed by Dmitriy Novozhilov
parent 8e24256f95
commit c9e423bf64
5 changed files with 42 additions and 24 deletions
@@ -15,7 +15,7 @@ public final enum class E : R|kotlin/Enum<test/E>| {
public final val y: R|kotlin/Int|
public get(): R|kotlin/Int|
private constructor(x: R|kotlin/String|, y: R|kotlin/Int|): R|test/E|
private constructor(@R|test/A|() x: R|kotlin/String|, @R|test/B|() y: R|kotlin/Int|): R|test/E|
public final static fun values(): R|kotlin/Array<test/E>| {
}
@@ -17,10 +17,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi
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.deserialization.hasReceiver
import org.jetbrains.kotlin.metadata.deserialization.*
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
import org.jetbrains.kotlin.name.ClassId
@@ -145,28 +142,34 @@ class JvmBinaryAnnotationDeserializer(
containerSource: DeserializedContainerSource?,
callableProto: MessageLite,
valueParameterProto: ProtoBuf.ValueParameter,
classProto: ProtoBuf.Class?,
nameResolver: NameResolver,
typeTable: TypeTable,
kind: CallableKind,
parameterIndex: Int,
): List<FirAnnotationCall> {
val methodSignature = getCallableSignature(callableProto, nameResolver, typeTable, kind) ?: return emptyList()
val index = parameterIndex + computeJvmParameterIndexShift(callableProto)
val index = parameterIndex + computeJvmParameterIndexShift(classProto, callableProto)
val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(methodSignature, index)
return findJvmBinaryClassAndLoadMemberAnnotations(containerSource, paramSignature)
}
/*
* TODO: Support container proto and fix index shift for
* constructors of inner classes and enums
*
* See [AbstractBinaryClassAnnotationAndConstantLoader]
*/
private fun computeJvmParameterIndexShift(message: MessageLite): Int {
private fun computeJvmParameterIndexShift(classProto: ProtoBuf.Class?, message: MessageLite): Int {
return when (message) {
is ProtoBuf.Function -> if (message.hasReceiver()) 1 else 0
is ProtoBuf.Property -> if (message.hasReceiver()) 1 else 0
is ProtoBuf.Constructor -> 0
is ProtoBuf.Constructor -> {
assert(classProto != null) {
"Constructor call without information about enclosing Class: $message"
}
val kind = Flags.CLASS_KIND.get(classProto!!.flags) ?: ProtoBuf.Class.Kind.CLASS
val isInner = Flags.IS_INNER.get(classProto.flags)
when {
kind == ProtoBuf.Class.Kind.ENUM_CLASS -> 2
isInner -> 1
else -> 0
}
}
else -> throw UnsupportedOperationException("Unsupported message: ${message::class.java}")
}
}
@@ -135,6 +135,7 @@ abstract class AbstractAnnotationDeserializer(
containerSource: DeserializedContainerSource?,
callableProto: MessageLite,
valueParameterProto: ProtoBuf.ValueParameter,
classProto: ProtoBuf.Class?,
nameResolver: NameResolver,
typeTable: TypeTable,
kind: CallableKind,
@@ -100,7 +100,6 @@ fun deserializeClassToSymbol(
typeParameters += context.typeDeserializer.ownTypeParameters.map { it.fir }
if (status.isInner)
typeParameters += parentContext?.allTypeParameters?.map { buildOuterClassTypeParameterRef { this.symbol = it } }.orEmpty()
// annotations += context.annotationDeserializer.loadClassAnnotations(classProto, context.nameResolver)
val typeDeserializer = context.typeDeserializer
val classDeserializer = context.memberDeserializer
@@ -114,12 +113,21 @@ fun deserializeClassToSymbol(
buildResolvedTypeRef { type = it }
}
addDeclarations(classProto.functionList.map(classDeserializer::loadFunction))
addDeclarations(classProto.propertyList.map(classDeserializer::loadProperty))
addDeclarations(
classProto.functionList.map {
classDeserializer.loadFunction(it, classProto)
}
)
addDeclarations(
classProto.propertyList.map {
classDeserializer.loadProperty(it, classProto)
}
)
addDeclarations(
classProto.constructorList.map {
classDeserializer.loadConstructor(it, this)
classDeserializer.loadConstructor(it, classProto, this)
}
)
@@ -167,7 +175,8 @@ fun deserializeClassToSymbol(
ClassId.fromString(nameResolver.getQualifiedClassName(nameIndex))
}
}
(it.annotations as MutableList<FirAnnotationCall>) += context.annotationDeserializer.loadClassAnnotations(classProto, context.nameResolver)
(it.annotations as MutableList<FirAnnotationCall>) +=
context.annotationDeserializer.loadClassAnnotations(classProto, context.nameResolver)
}
}
@@ -177,7 +177,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
}
}
fun loadProperty(proto: ProtoBuf.Property): FirProperty {
fun loadProperty(proto: ProtoBuf.Property, classProto: ProtoBuf.Class? = null): FirProperty {
val flags = if (proto.hasFlags()) proto.flags else loadOldFlags(proto.oldFlags)
val callableName = c.nameResolver.getName(proto.name)
val symbol = FirPropertySymbol(CallableId(c.packageFqName, c.relativeClassName, callableName))
@@ -237,7 +237,8 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
valueParameters += local.memberDeserializer.valueParameters(
listOf(proto.setterValueParameter),
proto,
AbstractAnnotationDeserializer.CallableKind.PROPERTY_SETTER
AbstractAnnotationDeserializer.CallableKind.PROPERTY_SETTER,
classProto
)
}
} else {
@@ -287,7 +288,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
}
}
fun loadFunction(proto: ProtoBuf.Function, byteContent: ByteArray? = null): FirSimpleFunction {
fun loadFunction(proto: ProtoBuf.Function, classProto: ProtoBuf.Class? = null): FirSimpleFunction {
val flags = if (proto.hasFlags()) proto.flags else loadOldFlags(proto.oldFlags)
val receiverAnnotations =
@@ -329,7 +330,8 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
valueParameters += local.memberDeserializer.valueParameters(
proto.valueParameterList,
proto,
AbstractAnnotationDeserializer.CallableKind.OTHERS
AbstractAnnotationDeserializer.CallableKind.OTHERS,
classProto
)
annotations +=
c.annotationDeserializer.loadFunctionAnnotations(c.containerSource, proto, local.nameResolver, local.typeTable)
@@ -344,7 +346,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
return simpleFunction
}
fun loadConstructor(proto: ProtoBuf.Constructor, classBuilder: FirRegularClassBuilder): FirConstructor {
fun loadConstructor(proto: ProtoBuf.Constructor, classProto: ProtoBuf.Class, classBuilder: FirRegularClassBuilder): FirConstructor {
val flags = proto.flags
val relativeClassName = c.relativeClassName!!
val symbol = FirConstructorSymbol(CallableId(c.packageFqName, relativeClassName, relativeClassName.shortName()))
@@ -383,6 +385,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
proto.valueParameterList,
proto,
AbstractAnnotationDeserializer.CallableKind.OTHERS,
classProto,
addDefaultValue = classBuilder.symbol.classId == StandardClassIds.Enum
)
annotations +=
@@ -401,6 +404,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
valueParameters: List<ProtoBuf.ValueParameter>,
callableProto: MessageLite,
callableKind: AbstractAnnotationDeserializer.CallableKind,
classProto: ProtoBuf.Class?,
addDefaultValue: Boolean = false
): List<FirValueParameter> {
return valueParameters.mapIndexed { index, proto ->
@@ -423,6 +427,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
c.containerSource,
callableProto,
proto,
classProto,
c.nameResolver,
c.typeTable,
callableKind,