From 6442b61db8b84715f03e9d84df30e8156576de58 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 30 Jan 2015 14:05:25 +0100 Subject: [PATCH] Don't generate redundant initializers for 'var' properties. Since only 'val' properties store initializers as compile time constants in descriptors, we need to take the initializer expression from the PSI and try to evaluate it as a constant. #KT-6661 fixed --- .../jetbrains/kotlin/codegen/MemberCodegen.java | 15 ++++++++++++--- .../codegen/bytecodeText/redundantInitializer.kt | 7 +++++++ .../bytecodeText/redundantInitializerNumber.kt | 7 +++++++ .../kotlin/codegen/BytecodeTextTestGenerated.java | 12 ++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/codegen/bytecodeText/redundantInitializer.kt create mode 100644 compiler/testData/codegen/bytecodeText/redundantInitializerNumber.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index 976afe1c2d5..8808ba297ef 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -39,6 +39,8 @@ import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingContextUtils; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant; +import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant; +import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator; import org.jetbrains.kotlin.storage.LockBasedStorageManager; import org.jetbrains.kotlin.storage.NotNullLazyValue; import org.jetbrains.kotlin.types.ErrorUtils; @@ -313,14 +315,21 @@ public abstract class MemberCodegen compileTimeValue = propertyDescriptor.getCompileTimeInitializer(); + JetExpression initializer = property.getInitializer(); + + CompileTimeConstant initializerValue = + property.isVar() && initializer != null + ? ConstantExpressionEvaluator.OBJECT$.evaluate(initializer, state.getBindingTrace(), null) + : propertyDescriptor.getCompileTimeInitializer(); // we must write constant values for fields in light classes, // because Java's completion for annotation arguments uses this information - if (compileTimeValue == null) return state.getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES; + if (initializerValue == null) return state.getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES; //TODO: OPTIMIZATION: don't initialize static final fields - Object value = compileTimeValue.getValue(); + Object value = initializerValue instanceof IntegerValueTypeConstant + ? ((IntegerValueTypeConstant) initializerValue).getValue(propertyDescriptor.getType()) + : initializerValue.getValue(); JetType jetType = getPropertyOrDelegateType(property, propertyDescriptor); Type type = typeMapper.mapType(jetType); return !skipDefaultValue(propertyDescriptor, value, type); diff --git a/compiler/testData/codegen/bytecodeText/redundantInitializer.kt b/compiler/testData/codegen/bytecodeText/redundantInitializer.kt new file mode 100644 index 00000000000..b074ba3c380 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/redundantInitializer.kt @@ -0,0 +1,7 @@ +package a + +class A { + private var x: String? = null +} + +// 0 PUTFIELD diff --git a/compiler/testData/codegen/bytecodeText/redundantInitializerNumber.kt b/compiler/testData/codegen/bytecodeText/redundantInitializerNumber.kt new file mode 100644 index 00000000000..a63ee553776 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/redundantInitializerNumber.kt @@ -0,0 +1,7 @@ +package a + +class A { + private var x: Int = 0 +} + +// 0 PUTFIELD diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index c66ac10d5f4..e14aba3d76a 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -181,6 +181,18 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { doTest(fileName); } + @TestMetadata("redundantInitializer.kt") + public void testRedundantInitializer() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/redundantInitializer.kt"); + doTest(fileName); + } + + @TestMetadata("redundantInitializerNumber.kt") + public void testRedundantInitializerNumber() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/redundantInitializerNumber.kt"); + doTest(fileName); + } + @TestMetadata("stringBuilderAppend.kt") public void testStringBuilderAppend() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/stringBuilderAppend.kt");