Refactor plugin-generated call to EnumSerializer():
support new values() argument. Get rid of old @JvmOverloads requirements in runtime.
This commit is contained in:
+2
-6
@@ -588,15 +588,11 @@ interface IrBuilderExtension {
|
||||
typeArgs = listOf(thisIrType)
|
||||
}
|
||||
enumSerializerId -> {
|
||||
serializerClass = module.getClassFromInternalSerializationPackage("CommonEnumSerializer")
|
||||
serializerClass = module.getClassFromInternalSerializationPackage(SpecialBuiltins.enumSerializer)
|
||||
args = kType.toClassDescriptor!!.let { enumDesc ->
|
||||
listOf(
|
||||
irString(enumDesc.serialName()),
|
||||
irCall(findEnumValuesMethod(enumDesc)),
|
||||
createArrayOfExpression(
|
||||
compilerContext.irBuiltIns.stringType,
|
||||
getEnumMembersNames(enumDesc).map { irString(it) }.toList()
|
||||
)
|
||||
irCall(findEnumValuesMethod(enumDesc))
|
||||
)
|
||||
}
|
||||
typeArgs = listOf(thisIrType)
|
||||
|
||||
+11
-2
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtPureClassOrObject
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -160,8 +161,16 @@ internal fun AbstractSerialGenerator.serializerInstance(
|
||||
ExpressionVisitor.getObjectKClass(context, kType.toClassDescriptor!!)
|
||||
)
|
||||
serializerClass.classId == enumSerializerId -> listOf(
|
||||
ExpressionVisitor.getObjectKClass(context, kType.toClassDescriptor!!),
|
||||
JsStringLiteral(kType.serialName())
|
||||
JsStringLiteral(kType.serialName()),
|
||||
// EnumClass.values() invocation
|
||||
JsInvocation(
|
||||
context.getInnerNameForDescriptor(
|
||||
DescriptorUtils.getFunctionByName(
|
||||
kType.toClassDescriptor!!.staticScope,
|
||||
DescriptorUtils.ENUM_VALUES
|
||||
)
|
||||
).makeRef()
|
||||
)
|
||||
)
|
||||
serializerClass.classId == objectSerializerId -> listOf(
|
||||
JsStringLiteral(kType.serialName()),
|
||||
|
||||
+14
-5
@@ -83,11 +83,11 @@ internal fun InstructionAdapter.genValidateProperty(index: Int, bitMaskAddress:
|
||||
iconst(0)
|
||||
}
|
||||
|
||||
internal fun InstructionAdapter.genExceptionThrow(exceptionClass: String, message: String) {
|
||||
anew(Type.getObjectType(exceptionClass))
|
||||
internal fun InstructionAdapter.genMissingFieldExceptionThrow(fieldName: String) {
|
||||
anew(Type.getObjectType(serializationExceptionMissingFieldName))
|
||||
dup()
|
||||
aconst(message)
|
||||
invokespecial(exceptionClass, "<init>", "(Ljava/lang/String;)V", false)
|
||||
aconst(fieldName)
|
||||
invokespecial(serializationExceptionMissingFieldName, "<init>", "(Ljava/lang/String;)V", false)
|
||||
checkcast(Type.getObjectType("java/lang/Throwable"))
|
||||
athrow()
|
||||
}
|
||||
@@ -287,7 +287,16 @@ internal fun AbstractSerialGenerator.stackValueSerializerInstance(codegen: Class
|
||||
|
||||
val serialName = kType.serialName()
|
||||
when (serializer.classId) {
|
||||
enumSerializerId, contextSerializerId, polymorphicSerializerId -> {
|
||||
enumSerializerId -> {
|
||||
aconst(serialName)
|
||||
signature.append("Ljava/lang/String;")
|
||||
val enumJavaType = codegen.typeMapper.mapType(kType, null, TypeMappingMode.GENERIC_ARGUMENT)
|
||||
val javaEnumArray = Type.getType("[Ljava/lang/Enum;")
|
||||
invokestatic(enumJavaType.internalName, "values","()[${enumJavaType.descriptor}", false)
|
||||
checkcast(javaEnumArray)
|
||||
signature.append(javaEnumArray.descriptor)
|
||||
}
|
||||
contextSerializerId, polymorphicSerializerId -> {
|
||||
// a special way to instantiate enum -- need a enum KClass reference
|
||||
// GENERIC_ARGUMENT forces boxing in order to obtain KClass
|
||||
aconst(codegen.typeMapper.mapType(kType, null, TypeMappingMode.GENERIC_ARGUMENT))
|
||||
|
||||
+1
-1
@@ -191,7 +191,7 @@ class SerializableCodegenImpl(
|
||||
genValidateProperty(i, bitMaskOff(i))
|
||||
val nonThrowLabel = Label()
|
||||
ificmpne(nonThrowLabel)
|
||||
genExceptionThrow(serializationExceptionMissingFieldName, prop.name)
|
||||
genMissingFieldExceptionThrow(prop.name)
|
||||
visitLabel(nonThrowLabel)
|
||||
// setting field
|
||||
load(0, thisAsmType)
|
||||
|
||||
+5
-11
@@ -406,11 +406,8 @@ open class SerializerCodegenImpl(
|
||||
)
|
||||
if (!serializableDescriptor.isInternalSerializable) {
|
||||
//validate all required (constructor) fields
|
||||
val nonThrowLabel = Label()
|
||||
val throwLabel = Label()
|
||||
for ((i, property) in properties.serializableConstructorProperties.withIndex()) {
|
||||
if (property.optional || property.transient) {
|
||||
// todo: Normal reporting of error
|
||||
if (!property.isConstructorParameterWithDefault)
|
||||
throw CompilationException(
|
||||
"Property ${property.name} was declared as optional/transient but has no default value",
|
||||
@@ -419,15 +416,12 @@ open class SerializerCodegenImpl(
|
||||
)
|
||||
} else {
|
||||
genValidateProperty(i, bitMaskOff(i))
|
||||
// todo: print name of each variable?
|
||||
ificmpeq(throwLabel)
|
||||
val nonThrowLabel = Label()
|
||||
ificmpne(nonThrowLabel)
|
||||
genMissingFieldExceptionThrow(property.name)
|
||||
visitLabel(nonThrowLabel)
|
||||
}
|
||||
}
|
||||
goTo(nonThrowLabel)
|
||||
// throwing an exception
|
||||
visitLabel(throwLabel)
|
||||
genExceptionThrow(serializationExceptionName, "Not all required constructor fields were specified")
|
||||
visitLabel(nonThrowLabel)
|
||||
}
|
||||
// create object with constructor
|
||||
anew(serializableAsmType)
|
||||
@@ -564,7 +558,7 @@ open class SerializerCodegenImpl(
|
||||
// throw
|
||||
// set
|
||||
ificmpne(nextLabel)
|
||||
genExceptionThrow(serializationExceptionMissingFieldName, property.name)
|
||||
genMissingFieldExceptionThrow(property.name)
|
||||
visitLabel(nextLabel)
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -57,7 +57,8 @@ class SerializerForEnumsCodegen(
|
||||
// regular .serialName() produces fqName here, which is kinda inconvenient for enum entry
|
||||
val serialName = entry.annotations.serialNameValue ?: entry.name.toString()
|
||||
aconst(serialName)
|
||||
invokevirtual(descImplType.internalName, CallingConventions.addElement, "(Ljava/lang/String;)V", false)
|
||||
iconst(0)
|
||||
invokevirtual(descImplType.internalName, CallingConventions.addElement, "(Ljava/lang/String;Z)V", false)
|
||||
// pushing annotations
|
||||
addSyntheticAnnotationsToDescriptor(descriptorVar, entry, CallingConventions.addAnnotation)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user