From 0f1589fd5041cf7f0ca7dabe05cb8c2abe1491de Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Mon, 30 May 2016 16:00:51 +0300 Subject: [PATCH] Fix for KT-12200: initial property assignment ignored #KT-12200 Fixed --- .../kotlin/codegen/MemberCodegen.java | 16 +------- .../codegen/box/properties/kt12200.kt | 30 ++++++++++++++ .../codegen/box/properties/kt12200Const.kt | 40 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 12 ++++++ 4 files changed, 84 insertions(+), 14 deletions(-) create mode 100644 compiler/testData/codegen/box/properties/kt12200.kt create mode 100644 compiler/testData/codegen/box/properties/kt12200Const.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index eb8534e1fe4..84db748ae40 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -409,7 +409,8 @@ public abstract class MemberCodegen initializerValue = computeInitializerValue(property, propertyDescriptor, initializer); + ConstantValue initializerValue = + initializer != null ? ExpressionCodegen.getCompileTimeConstant(initializer, bindingContext) : null; // we must write constant values for fields in light classes, // because Java's completion for annotation arguments uses this information if (initializerValue == null) return state.getClassBuilderMode() == ClassBuilderMode.FULL; @@ -420,19 +421,6 @@ public abstract class MemberCodegen computeInitializerValue( - @NotNull KtProperty property, - @NotNull PropertyDescriptor propertyDescriptor, - @Nullable KtExpression initializer - ) { - if (property.isVar() && initializer != null) { - BindingTrace tempTrace = TemporaryBindingTrace.create(state.getBindingTrace(), "property initializer"); - return constantExpressionEvaluator.evaluateToConstantValue(initializer, tempTrace, propertyDescriptor.getType()); - } - return propertyDescriptor.getCompileTimeInitializer(); - } - @NotNull private KotlinType getPropertyOrDelegateType(@NotNull KtProperty property, @NotNull PropertyDescriptor descriptor) { KtExpression delegateExpression = property.getDelegateExpression(); diff --git a/compiler/testData/codegen/box/properties/kt12200.kt b/compiler/testData/codegen/box/properties/kt12200.kt new file mode 100644 index 00000000000..14ea60ec09e --- /dev/null +++ b/compiler/testData/codegen/box/properties/kt12200.kt @@ -0,0 +1,30 @@ +//WITH_RUNTIME + +class ThingTemplate { + val prop = 0 +} + +class ThingVal(template: ThingTemplate) { + val prop = template.prop +} + +class ThingVar(template: ThingTemplate) { + var prop = template.prop +} + + +fun box() : String { + val template = ThingTemplate(); + val javaClass = ThingTemplate::class.java + val field = javaClass.getDeclaredField("prop")!! + field.isAccessible = true + field.set(template, 1) + + val thingVal = ThingVal(template) + if (thingVal.prop != 1) return "fail 1" + + val thingVar = ThingVar(template) + if (thingVar.prop != 1) return "fail 2" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/properties/kt12200Const.kt b/compiler/testData/codegen/box/properties/kt12200Const.kt new file mode 100644 index 00000000000..dbdbcbff4b7 --- /dev/null +++ b/compiler/testData/codegen/box/properties/kt12200Const.kt @@ -0,0 +1,40 @@ +//WITH_RUNTIME +//FULL_JDK +//NOTE this test should be removed if Kotlin const properties will became inlined + +import java.lang.reflect.Field +import java.lang.reflect.Modifier + +object ThingTemplate { + const val prop = 0 +} + +class ThingVal { + val prop = ThingTemplate.prop +} + +class ThingVar { + var prop = ThingTemplate.prop +} + + +fun box() : String { + val template = ThingTemplate; + val javaClass = ThingTemplate::class.java + val field = javaClass.getDeclaredField("prop")!! + field.isAccessible = true + + val modifiersField = Field::class.java!!.getDeclaredField("modifiers") + modifiersField.isAccessible = true + modifiersField.setInt(field, field.modifiers and Modifier.FINAL.inv()) + + field.set(null, 1) + + val thingVal = ThingVal() + if (thingVal.prop != 1) return "fail 1" + + val thingVar = ThingVar() + if (thingVar.prop != 1) return "fail 2" + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 8302fc2bed2..841038c6fa9 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -9964,6 +9964,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("kt12200.kt") + public void testKt12200() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/kt12200.kt"); + doTest(fileName); + } + + @TestMetadata("kt12200Const.kt") + public void testKt12200Const() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/kt12200Const.kt"); + doTest(fileName); + } + @TestMetadata("kt1398.kt") public void testKt1398() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/kt1398.kt");