Fix class literals of objects in super constructor calls

In an expression such as "Obj::class" where Obj is an object, it's fine to
consider Obj either an expression or a type and generate either
Obj.INSTANCE.getClass() or Obj.class correspondingly. However,
the former fails in the object's super constructor call because the INSTANCE
field is not yet initialized. Thus, we force generation of Obj.class in case
when Obj is an object.

Note that this has been reproduced in our project, see
KotlinMetadataVersionIndex
This commit is contained in:
Alexander Udalov
2016-07-15 00:24:29 +03:00
parent 495ed13fce
commit 70e01fac18
3 changed files with 26 additions and 2 deletions
@@ -3290,10 +3290,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
@Override
public Unit invoke(InstructionAdapter v) {
KotlinType type = lhs.getType();
if (lhs instanceof DoubleColonLHS.Expression) {
if (lhs instanceof DoubleColonLHS.Expression && !((DoubleColonLHS.Expression) lhs).isObject()) {
JavaClassProperty.INSTANCE.generateImpl(v, gen(receiverExpression));
}
else if (lhs instanceof DoubleColonLHS.Type) {
else {
if (TypeUtils.isTypeParameter(type)) {
assert TypeUtils.isReifiedTypeParameter(type) :
"Non-reified type parameter under ::class should be rejected by type checker: " + type;
@@ -0,0 +1,18 @@
// WITH_RUNTIME
import kotlin.test.assertEquals
abstract class S<T>(val klass: Class<T>) {
val result = klass.simpleName
}
object OK : S<OK>(OK::class.java)
class C {
companion object Companion : S<Companion>(Companion::class.java)
}
fun box(): String {
assertEquals("Companion", C.Companion.result)
return OK.result
}
@@ -2364,6 +2364,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("objectSuperConstructorCall.kt")
public void testObjectSuperConstructorCall() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classLiteral/bound/objectSuperConstructorCall.kt");
doTest(fileName);
}
@TestMetadata("primitives.kt")
public void testPrimitives() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classLiteral/bound/primitives.kt");