NoArg: Fix IllegalAccessError on instantiating sealed class child via Java reflection (KT-18245)

This commit is contained in:
Yan Zhulanow
2017-06-28 22:39:38 +03:00
parent 53e193d130
commit 9a5a003d0a
3 changed files with 39 additions and 2 deletions
@@ -44,15 +44,24 @@ class NoArgExpressionCodegenExtension(val invokeInitializers: Boolean = false) :
val constructorDescriptor = createNoArgConstructorDescriptor(descriptor)
val isParentASealedClass = (descriptor.containingDeclaration as? ClassDescriptor)?.modality == Modality.SEALED
functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, constructorDescriptor, object: CodegenBased(state) {
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
codegen.v.load(0, AsmTypes.OBJECT_TYPE)
codegen.v.visitMethodInsn(Opcodes.INVOKESPECIAL, superClassInternalName, "<init>", "()V", false)
if (isParentASealedClass) {
codegen.v.aconst(null)
codegen.v.visitMethodInsn(Opcodes.INVOKESPECIAL, superClassInternalName, "<init>",
"(Lkotlin/jvm/internal/DefaultConstructorMarker;)V", false)
}
else {
codegen.v.visitMethodInsn(Opcodes.INVOKESPECIAL, superClassInternalName, "<init>", "()V", false)
}
if (invokeInitializers) {
generateInitializers(codegen)
}
codegen.v.visitInsn(Opcodes.RETURN)
}
})
+22
View File
@@ -0,0 +1,22 @@
// WITH_RUNTIME
annotation class NoArg
sealed class Test {
abstract val test: String
@NoArg
data class Test1(override val test: String) : Test()
@NoArg
data class Test2(override val test: String) : Test()
}
fun box(): String {
Test::class.java.declaredConstructors.forEach { it.isAccessible = true }
Test.Test1::class.java.declaredConstructors.forEach { it.isAccessible = true }
val instance = Test.Test1::class.java.newInstance() // Error
return "OK"
}
@@ -48,6 +48,12 @@ public class BlackBoxCodegenTestForNoArgGenerated extends AbstractBlackBoxCodege
doTest(fileName);
}
@TestMetadata("kt18245.kt")
public void testKt18245() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("plugins/noarg/noarg-cli/testData/box/kt18245.kt");
doTest(fileName);
}
@TestMetadata("kt18667.kt")
public void testKt18667() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("plugins/noarg/noarg-cli/testData/box/kt18667.kt");