| 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,
|
|
|