Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
index 260316710d52a9320eb70ed3af577fc4236aeb4f..712e5cd7a6bf875ecb956fb445f9fa01403bbe0f 100644 |
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
@@ -122,6 +122,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>, |
BaseImplementationOfNewMixin<ir.Primitive, dynamic>, |
BaseImplementationOfCompoundsMixin<ir.Primitive, dynamic>, |
+ BaseImplementationOfSetIfNullsMixin<ir.Primitive, dynamic>, |
BaseImplementationOfIndexCompoundsMixin<ir.Primitive, dynamic> |
implements SemanticSendVisitor<ir.Primitive, dynamic> { |
final TreeElements elements; |
@@ -1350,6 +1351,21 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
return rhs.kind == CompoundKind.POSTFIX ? value : result; |
} |
+ ir.Primitive translateSetIfNull( |
+ ast.SendSet node, |
+ {ir.Primitive getValue(), |
+ ast.Node rhs, |
+ void setValue(ir.Primitive value)}) { |
+ ir.Primitive value = getValue(); |
+ // Unlike other compound operators if-null conditionally will not do the |
+ // assignment operation. |
+ return irBuilder.buildIfNull(value, nested(() { |
+ ir.Primitive newValue = build(rhs); |
+ setValue(newValue); |
+ return newValue; |
+ })); |
+ } |
+ |
@override |
ir.Primitive handleDynamicSet( |
ast.SendSet node, |
@@ -1453,6 +1469,17 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
} |
@override |
+ ir.Primitive handleTypeLiteralConstantSetIfNulls( |
+ ast.SendSet node, |
+ ConstantExpression constant, |
+ ast.Node rhs, |
+ _) { |
+ // The type literal is never `null`. |
+ return buildConstantExpression(constant, |
+ sourceInformationBuilder.buildGet(node)); |
+ } |
+ |
+ @override |
ir.Primitive handleDynamicCompounds( |
ast.SendSet node, |
ast.Node receiver, |
@@ -1482,6 +1509,36 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
: helper(); |
} |
+ @override |
+ ir.Primitive handleDynamicSetIfNulls( |
+ ast.Send node, |
+ ast.Node receiver, |
+ Name name, |
+ ast.Node rhs, |
+ _) { |
+ ir.Primitive target = translateReceiver(receiver); |
+ ir.Primitive helper() { |
+ return translateSetIfNull( |
+ node, |
+ getValue: () => irBuilder.buildDynamicGet( |
+ target, |
+ new Selector.getter(name), |
+ elements.getGetterTypeMaskInComplexSendSet(node), |
+ sourceInformationBuilder.buildGet(node)), |
+ rhs: rhs, |
+ setValue: (ir.Primitive result) { |
+ irBuilder.buildDynamicSet( |
+ target, |
+ new Selector.setter(name), |
+ elements.getTypeMask(node), |
+ result); |
+ }); |
+ } |
+ return node.isConditional |
+ ? irBuilder.buildIfNotNullSend(target, nested(helper)) |
+ : helper(); |
+ } |
+ |
ir.Primitive buildLocalNoSuchSetter(LocalElement local, ir.Primitive value) { |
Selector selector = new Selector.setter( |
new Name(local.name, local.library, isSetter: true)); |
@@ -1514,6 +1571,32 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
}); |
} |
+ @override |
+ ir.Primitive handleLocalSetIfNulls( |
+ ast.SendSet node, |
+ LocalElement local, |
+ ast.Node rhs, |
+ _, |
+ {bool isSetterValid}) { |
+ return translateSetIfNull( |
+ node, |
+ getValue: () { |
+ if (local.isFunction) { |
+ return irBuilder.buildLocalFunctionGet(local); |
+ } else { |
+ return irBuilder.buildLocalVariableGet(local); |
+ } |
+ }, |
+ rhs: rhs, |
+ setValue: (ir.Primitive result) { |
+ if (isSetterValid) { |
+ irBuilder.buildLocalVariableSet(local, result); |
+ } else { |
+ return buildLocalNoSuchSetter(local, result); |
+ } |
+ }); |
+ } |
+ |
ir.Primitive buildStaticNoSuchGetter(Element element) { |
return buildStaticNoSuchMethod( |
new Selector.getter(new Name(element.name, element.library)), |
@@ -1559,9 +1642,45 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
case CompoundSetter.SETTER: |
return irBuilder.buildStaticSetterSet(setter, result); |
case CompoundSetter.INVALID: |
- // TODO(johnniwinther): Ensure [setter] is non null. |
- return buildStaticNoSuchSetter( |
- setter != null ? setter : getter, result); |
+ return buildStaticNoSuchSetter(setter, result); |
+ } |
+ }); |
+ } |
+ |
+ @override |
+ ir.Primitive handleStaticSetIfNulls( |
+ ast.SendSet node, |
+ Element getter, |
+ CompoundGetter getterKind, |
+ Element setter, |
+ CompoundSetter setterKind, |
+ ast.Node rhs, |
+ _) { |
+ return translateSetIfNull( |
+ node, |
+ getValue: () { |
+ switch (getterKind) { |
+ case CompoundGetter.FIELD: |
+ SourceInformation src = sourceInformationBuilder.buildGet(node); |
+ return irBuilder.buildStaticFieldGet(getter, src); |
+ case CompoundGetter.GETTER: |
+ return irBuilder.buildStaticGetterGet( |
+ getter, sourceInformationBuilder.buildGet(node)); |
+ case CompoundGetter.METHOD: |
+ return irBuilder.buildStaticFunctionGet(getter); |
+ case CompoundGetter.UNRESOLVED: |
+ return buildStaticNoSuchGetter(getter); |
+ } |
+ }, |
+ rhs: rhs, |
+ setValue: (ir.Primitive result) { |
+ switch (setterKind) { |
+ case CompoundSetter.FIELD: |
+ return irBuilder.buildStaticFieldSet(setter, result); |
+ case CompoundSetter.SETTER: |
+ return irBuilder.buildStaticSetterSet(setter, result); |
+ case CompoundSetter.INVALID: |
+ return buildStaticNoSuchSetter(setter, result); |
} |
}); |
} |
@@ -1603,9 +1722,48 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
case CompoundGetter.METHOD: |
return irBuilder.buildSuperMethodGet(getter); |
case CompoundGetter.UNRESOLVED: |
- // TODO(johnniwinther): Ensure [getter] is not null. |
return buildSuperNoSuchGetter( |
- getter != null ? getter : setter, |
+ getter, |
+ elements.getGetterTypeMaskInComplexSendSet(node)); |
+ } |
+ }, |
+ rhs: rhs, |
+ setValue: (ir.Primitive result) { |
+ switch (setterKind) { |
+ case CompoundSetter.FIELD: |
+ return irBuilder.buildSuperFieldSet(setter, result); |
+ case CompoundSetter.SETTER: |
+ return irBuilder.buildSuperSetterSet(setter, result); |
+ case CompoundSetter.INVALID: |
+ return buildSuperNoSuchSetter( |
+ setter, elements.getTypeMask(node), result); |
+ } |
+ }); |
+ } |
+ |
+ @override |
+ ir.Primitive handleSuperSetIfNulls( |
+ ast.SendSet node, |
+ Element getter, |
+ CompoundGetter getterKind, |
+ Element setter, |
+ CompoundSetter setterKind, |
+ ast.Node rhs, |
+ _) { |
+ return translateSetIfNull( |
+ node, |
+ getValue: () { |
+ switch (getterKind) { |
+ case CompoundGetter.FIELD: |
+ return irBuilder.buildSuperFieldGet(getter); |
+ case CompoundGetter.GETTER: |
+ return irBuilder.buildSuperGetterGet( |
+ getter, sourceInformationBuilder.buildGet(node)); |
+ case CompoundGetter.METHOD: |
+ return irBuilder.buildSuperMethodGet(getter); |
+ case CompoundGetter.UNRESOLVED: |
+ return buildSuperNoSuchGetter( |
+ getter, |
elements.getGetterTypeMaskInComplexSendSet(node)); |
} |
}, |
@@ -1641,6 +1799,17 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
} |
@override |
+ ir.Primitive visitTypeVariableTypeLiteralSetIfNull( |
+ ast.Send node, |
+ TypeVariableElement element, |
+ ast.Node rhs, |
+ _) { |
+ // The type variable is never `null`. |
+ return translateTypeVariableTypeLiteral(element, |
+ sourceInformationBuilder.buildGet(node)); |
+ } |
+ |
+ @override |
ir.Primitive handleIndexCompounds( |
ast.SendSet node, |
ast.Node receiver, |