Merge pull request #555 from JetBrains/rr/yole/putfield-null

Don't generate redundant initializers for 'var' properties.
This commit is contained in:
Alexander Udalov
2015-01-30 19:19:35 +03:00
4 changed files with 44 additions and 3 deletions
@@ -37,8 +37,12 @@ import org.jetbrains.kotlin.name.SpecialNames;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingContextUtils;
import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace;
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 +317,25 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(VARIABLE, property);
assert propertyDescriptor != null;
CompileTimeConstant<?> compileTimeValue = propertyDescriptor.getCompileTimeInitializer();
JetExpression initializer = property.getInitializer();
CompileTimeConstant<?> initializerValue;
if (property.isVar() && initializer != null) {
BindingTrace tempTrace = TemporaryBindingTrace.create(state.getBindingTrace(), "property initializer");
initializerValue = ConstantExpressionEvaluator.OBJECT$.evaluate(initializer, tempTrace, propertyDescriptor.getType());
}
else {
initializerValue = 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);
@@ -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);
}
@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");