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
This commit is contained in:
@@ -39,6 +39,8 @@ import org.jetbrains.kotlin.resolve.BindingContext;
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
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.LockBasedStorageManager;
|
||||||
import org.jetbrains.kotlin.storage.NotNullLazyValue;
|
import org.jetbrains.kotlin.storage.NotNullLazyValue;
|
||||||
import org.jetbrains.kotlin.types.ErrorUtils;
|
import org.jetbrains.kotlin.types.ErrorUtils;
|
||||||
@@ -313,14 +315,21 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
|
|||||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(VARIABLE, property);
|
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(VARIABLE, property);
|
||||||
assert propertyDescriptor != null;
|
assert propertyDescriptor != null;
|
||||||
|
|
||||||
CompileTimeConstant<?> 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,
|
// we must write constant values for fields in light classes,
|
||||||
// because Java's completion for annotation arguments uses this information
|
// 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
|
//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);
|
JetType jetType = getPropertyOrDelegateType(property, propertyDescriptor);
|
||||||
Type type = typeMapper.mapType(jetType);
|
Type type = typeMapper.mapType(jetType);
|
||||||
return !skipDefaultValue(propertyDescriptor, value, type);
|
return !skipDefaultValue(propertyDescriptor, value, type);
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package a
|
||||||
|
|
||||||
|
class A {
|
||||||
|
private var x: String? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0 PUTFIELD
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package a
|
||||||
|
|
||||||
|
class A {
|
||||||
|
private var x: Int = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0 PUTFIELD
|
||||||
@@ -181,6 +181,18 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("stringBuilderAppend.kt")
|
||||||
public void testStringBuilderAppend() throws Exception {
|
public void testStringBuilderAppend() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/stringBuilderAppend.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/stringBuilderAppend.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user