FIR Java enhancement: fix JVM signature generation for type parameters

This commit is contained in:
Mikhail Glukhikh
2019-10-23 09:48:53 +03:00
parent 47cf7373af
commit be6100527b
@@ -338,19 +338,27 @@ internal fun FirFunction<*>.computeJvmDescriptor(): String = buildString {
// TODO: primitive types, arrays, etc. // TODO: primitive types, arrays, etc.
private fun StringBuilder.appendErasedType(typeRef: FirTypeRef) { private fun StringBuilder.appendErasedType(typeRef: FirTypeRef) {
fun appendClass(klass: JavaClass) {
klass.fqName?.let {
append("L")
append(it.asString().replace(".", "/"))
}
}
when (typeRef) { when (typeRef) {
is FirResolvedTypeRef -> appendConeType(typeRef.type) is FirResolvedTypeRef -> appendConeType(typeRef.type)
is FirJavaTypeRef -> { is FirJavaTypeRef -> {
when (val javaType = typeRef.type) { when (val javaType = typeRef.type) {
is JavaClassifierType -> { is JavaClassifierType -> {
when (val classifier = javaType.classifier) { when (val classifier = javaType.classifier) {
is JavaClass -> classifier.fqName?.let { is JavaClass -> appendClass(classifier)
append("L")
append(it.asString().replace(".", "/"))
}
is JavaTypeParameter -> { is JavaTypeParameter -> {
append("L") val representative = classifier.upperBounds.firstOrNull { it.classifier is JavaClass }
append(classifier.name) if (representative == null) {
append("Ljava/lang/Object")
} else {
appendClass(representative.classifier as JavaClass)
}
} }
else -> return else -> return
} }
@@ -362,16 +370,30 @@ private fun StringBuilder.appendErasedType(typeRef: FirTypeRef) {
} }
private fun StringBuilder.appendConeType(coneType: ConeKotlinType) { private fun StringBuilder.appendConeType(coneType: ConeKotlinType) {
fun appendClassLikeType(type: ConeClassLikeType) {
append("L")
val classId = type.lookupTag.classId
append(classId.packageFqName.asString().replace(".", "/"))
append("/")
append(classId.relativeClassName)
}
if (coneType is ConeClassErrorType) return if (coneType is ConeClassErrorType) return
append("L")
when (coneType) { when (coneType) {
is ConeClassLikeType -> { is ConeClassLikeType -> {
val classId = coneType.lookupTag.classId appendClassLikeType(coneType)
append(classId.packageFqName.asString().replace(".", "/")) }
append("/") is ConeTypeParameterType -> {
append(classId.relativeClassName) val representative = coneType.lookupTag.typeParameterSymbol.fir.bounds.firstOrNull {
(it as? FirResolvedTypeRef)?.type is ConeClassLikeType
}
if (representative == null) {
append("Ljava/lang/Object")
} else {
appendClassLikeType(representative.coneTypeUnsafe())
}
append(coneType.lookupTag.name)
} }
is ConeTypeParameterType -> append(coneType.lookupTag.name)
} }
append(";") append(";")
} }