Delegated properties now cannot be used before initialization #KT-10869 Fixed

This commit is contained in:
Mikhail Glukhikh
2016-02-01 19:06:59 +03:00
parent 65f754ffca
commit 45298e0bad
10 changed files with 95 additions and 21 deletions
@@ -360,6 +360,14 @@ public class ControlFlowInformationProvider {
}
}
private boolean isDefinitelyInitialized(@NotNull PropertyDescriptor propertyDescriptor) {
if (propertyDescriptor.isLateInit()) return true;
if (trace.get(BACKING_FIELD_REQUIRED, propertyDescriptor) == Boolean.TRUE) return false;
PsiElement property = DescriptorToSourceUtils.descriptorToDeclaration(propertyDescriptor);
if (property instanceof KtProperty && ((KtProperty) property).hasDelegate()) return false;
return true;
}
private void checkIsInitialized(
@NotNull VariableInitContext ctxt,
@NotNull KtElement element,
@@ -370,11 +378,8 @@ public class ControlFlowInformationProvider {
boolean isDefinitelyInitialized = ctxt.exitInitState.definitelyInitialized();
VariableDescriptor variableDescriptor = ctxt.variableDescriptor;
if (variableDescriptor instanceof PropertyDescriptor) {
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variableDescriptor;
if (propertyDescriptor.isLateInit() || !trace.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
isDefinitelyInitialized = true;
}
if (!isDefinitelyInitialized && variableDescriptor instanceof PropertyDescriptor) {
isDefinitelyInitialized = isDefinitelyInitialized((PropertyDescriptor) variableDescriptor);
}
if (!isDefinitelyInitialized && !varWithUninitializedErrorGenerated.contains(variableDescriptor)) {
if (!(variableDescriptor instanceof PropertyDescriptor)) {
@@ -1001,6 +1001,8 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
}
val delegate = property.delegateExpression
if (delegate != null) {
// We do not want to have getDeferredValue(delegate) here, because delegate value will be read anyway later
visitAssignment(property, getDeferredValue(null), property)
generateInstructions(delegate)
if (builder.getBoundValue(delegate) != null) {
createSyntheticValue(property, MagicKind.VALUE_CONSUMER, delegate)