Support cross-module usages of @JvmRecord classes

The problem is that JvmRecord has SOURCE retention
Probably, increasing its retention might be a more reliable solution
(or in some other way serializing that the class is a record)

Just checking supertypes seems like a reasonable approximation:
only records kotlin are allowed to extend j.l.Record.
But the relevant diagnostic has been added only since 1.4.30,
so potentially there could have been exist a non-record class with
such supertype compiled by 1.4.20, but this case seems to be ill-formed
and marginal anyway.

For Java classes, it's irrelevant since they don't have member properties
(only synthetic extensions)

^KT-43677 In Progress
This commit is contained in:
Denis.Zharkov
2020-12-03 17:59:14 +03:00
parent ac0604377d
commit dc1a1c5821
10 changed files with 156 additions and 8 deletions
@@ -41,7 +41,7 @@ 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.NameUtils
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_RECORD_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.JAVA_LANG_RECORD_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
@@ -84,8 +84,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
if (property != null) {
val propertyName = property.name.asString()
val propertyParent = property.parentAsClass
if (propertyParent.isAnnotationClass || propertyParent.hasAnnotation(JVM_RECORD_ANNOTATION_FQ_NAME))
return propertyName
if (propertyParent.isAnnotationClass || propertyParent.superTypes.any { it.isJavaLangRecord() }) return propertyName
// The enum property getters <get-name> and <get-ordinal> have special names which also
// apply to their fake overrides. Unfortunately, getJvmMethodNameIfSpecial does not handle
@@ -102,6 +101,8 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
return mangleMemberNameIfRequired(function.name.asString(), function)
}
private fun IrType.isJavaLangRecord() = getClass()!!.hasEqualFqName(JAVA_LANG_RECORD_FQ_NAME)
private fun mangleMemberNameIfRequired(name: String, function: IrSimpleFunction): String {
val newName = JvmCodegenUtil.sanitizeNameIfNeeded(name, context.state.languageVersionSettings)
@@ -17,7 +17,9 @@ import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.impl.*
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.isPropertyAccessor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import org.jetbrains.kotlin.types.typeUtil.makeNullable
@@ -74,6 +76,9 @@ val IrType.classifierOrNull: IrClassifierSymbol?
val IrType.classOrNull: IrClassSymbol?
get() = classifierOrNull as? IrClassSymbol
val IrType.classFqName: FqName?
get() = classOrNull?.owner?.fqNameWhenAvailable
val IrTypeArgument.typeOrNull: IrType? get() = (this as? IrTypeProjection)?.type
fun IrType.makeNotNull() =