From 187ca71dc625d068c885af5a035bf56ce6b0d7f1 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Wed, 16 Aug 2017 14:46:38 +0300 Subject: [PATCH] NoArg: Fix compatibility with sealed classes with non-zero-parameter constructors (KT-19687) Also check if a class has a sealed super class properly. --- .../src/NoArgExpressionCodegenExtension.kt | 9 ++++++-- .../noarg/noarg-cli/testData/box/kt18245.kt | 23 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/plugins/noarg/noarg-cli/src/NoArgExpressionCodegenExtension.kt b/plugins/noarg/noarg-cli/src/NoArgExpressionCodegenExtension.kt index 32fccd04444..9dc8c6c11c5 100644 --- a/plugins/noarg/noarg-cli/src/NoArgExpressionCodegenExtension.kt +++ b/plugins/noarg/noarg-cli/src/NoArgExpressionCodegenExtension.kt @@ -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 ()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, "", "(Lkotlin/jvm/internal/DefaultConstructorMarker;)V", false) diff --git a/plugins/noarg/noarg-cli/testData/box/kt18245.kt b/plugins/noarg/noarg-cli/testData/box/kt18245.kt index 2de048987d2..a733b5f5c9b 100644 --- a/plugins/noarg/noarg-cli/testData/box/kt18245.kt +++ b/plugins/noarg/noarg-cli/testData/box/kt18245.kt @@ -18,5 +18,28 @@ fun box(): String { val instance = Test.Test1::class.java.newInstance() // Error + Demo.Foo::class.java.newInstance() + Demo.Free::class.java.newInstance() + + A.Free::class.java.newInstance() + return "OK" +} + +@NoArg +sealed class Demo(val name : String) { + @NoArg + class Free(name: String) + + @NoArg + class Foo(name: String) : Demo(name) + + @NoArg + class Bar(name: String) : Demo(name) +} + +@NoArg +abstract class A(val name: String) { + @NoArg + class Free(name: String) : A(name) } \ No newline at end of file