NoArg: Fix compatibility with sealed classes with non-zero-parameter constructors (KT-19687)

Also check if a class has a sealed super class properly.
This commit is contained in:
Yan Zhulanow
2017-08-16 14:46:38 +03:00
committed by Yan Zhulanow
parent cea891c754
commit 187ca71dc6
2 changed files with 30 additions and 2 deletions
@@ -44,13 +44,18 @@ class NoArgExpressionCodegenExtension(val invokeInitializers: Boolean = false) :
val constructorDescriptor = createNoArgConstructorDescriptor(descriptor)
val isParentASealedClass = (descriptor.containingDeclaration as? ClassDescriptor)?.modality == Modality.SEALED
val superClass = descriptor.getSuperClassOrAny()
// If a parent sealed class has not a zero-parameter constructor, user must write @NoArg annotation for the parent class as well,
// and then we generate <init>()V
val isParentASealedClassWithDefaultConstructor =
superClass.modality == Modality.SEALED && superClass.constructors.any { it.isZeroParameterConstructor() }
functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, constructorDescriptor, object: CodegenBased(state) {
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
codegen.v.load(0, AsmTypes.OBJECT_TYPE)
if (isParentASealedClass) {
if (isParentASealedClassWithDefaultConstructor) {
codegen.v.aconst(null)
codegen.v.visitMethodInsn(Opcodes.INVOKESPECIAL, superClassInternalName, "<init>",
"(Lkotlin/jvm/internal/DefaultConstructorMarker;)V", false)