| Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
|
| diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
|
| index b84a3786c9f7e2776b3731a97ca3d1d63889649b..498fe3e8da415276616ed302f19ff09df2c43eb0 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
|
| @@ -364,6 +364,11 @@ abstract class IrBuilderMixin<N> {
|
| return (IrBuilder builder) => withBuilder(builder, () => build(node));
|
| }
|
|
|
| + /// Returns a closure that takes an [IrBuilder] and runs [f] in its context.
|
| + SubbuildFunction nested(f()) {
|
| + return (IrBuilder builder) => withBuilder(builder, f);
|
| + }
|
| +
|
| /// Returns a closure that takes an [IrBuilder] and builds the sequence of
|
| /// [nodes] in its context using [build].
|
| // TODO(johnniwinther): Type [nodes] as `Iterable<N>` when `NodeList` uses
|
| @@ -1003,6 +1008,19 @@ abstract class IrBuilder {
|
| return _buildInvokeDynamic(receiver, selector, arguments);
|
| }
|
|
|
| + /// Create an if-null expression. This is equivalent to a conditional
|
| + /// expression whose result is either [value] if [value] is not null, or
|
| + /// `right` if [value] is null. Only when [value] is null, [buildRight] is
|
| + /// evaluated to produce the `right` value.
|
| + ir.Primitive buildIfNull(ir.Primitive value,
|
| + ir.Primitive buildRight(IrBuilder builder));
|
| +
|
| + /// Create a conditional send. This is equivalent to a conditional expression
|
| + /// that checks if [receiver] is null, if so, it returns null, otherwise it
|
| + /// evaluates the [buildSend] expression.
|
| + ir.Primitive buildIfNotNullSend(ir.Primitive receiver,
|
| + ir.Primitive buildSend(IrBuilder builder));
|
| +
|
| /// Create a dynamic getter invocation on [receiver] where the getter name is
|
| /// defined by [selector].
|
| ir.Primitive buildDynamicGet(ir.Primitive receiver, Selector selector) {
|
| @@ -2323,6 +2341,18 @@ class DartIrBuilder extends IrBuilder {
|
| (k) => new ir.TypeOperator(receiver, type, k, isTypeTest: isTypeTest));
|
| return isNotCheck ? buildNegation(check) : check;
|
| }
|
| +
|
| + @override
|
| + ir.Primitive buildIfNull(ir.Primitive value,
|
| + ir.Primitive buildRight(IrBuilder builder)) {
|
| + throw "If-null (??) not implemented in cps_ir for dart output";
|
| + }
|
| +
|
| + @override
|
| + ir.Primitive buildIfNotNullSend(ir.Primitive receiver,
|
| + ir.Primitive buildSend(IrBuilder builder)) {
|
| + throw "Conditional sends (?.) not implemented in cps_ir for dart output";
|
| + }
|
| }
|
|
|
| /// State shared between JsIrBuilders within the same function.
|
| @@ -2695,6 +2725,26 @@ class JsIrBuilder extends IrBuilder {
|
| return isNotCheck ? buildNegation(check) : check;
|
| }
|
|
|
| + @override
|
| + ir.Primitive buildIfNull(ir.Primitive value,
|
| + ir.Primitive buildRight(IrBuilder builder)) {
|
| + ir.Primitive condition = _buildCheckNull(value);
|
| + return buildConditional(condition, buildRight, (_) => value);
|
| + }
|
| +
|
| + @override
|
| + ir.Primitive buildIfNotNullSend(ir.Primitive receiver,
|
| + ir.Primitive buildSend(IrBuilder builder)) {
|
| + ir.Primitive condition = _buildCheckNull(receiver);
|
| + return buildConditional(condition, (_) => receiver, buildSend);
|
| + }
|
| +
|
| + /// Creates a type test checking whether [value] is null.
|
| + ir.Primitive _buildCheckNull(ir.Primitive value) {
|
| + assert(isOpen);
|
| + ir.Primitive right = buildNullConstant();
|
| + return addPrimitive(new ir.Identical(value, right));
|
| + }
|
| }
|
|
|
|
|
|
|