execute method

  1. @override
JinjaValue execute(
  1. Context ctx
)
override

Executes the statement within the given ctx and returns the result as a JinjaValue.

Implementation

@override
JinjaValue execute(Context ctx) {
  JinjaValue rhs;
  if (value != null) {
    rhs = value!.execute(ctx);
  } else {
    // Block set: capture output of body
    rhs = _execCaptured(body, ctx);
  }

  if (assignee is Identifier) {
    ctx.set((assignee as Identifier).name, rhs);
  } else if (assignee is TupleLiteral) {
    // Unpack
    final tuple = assignee as TupleLiteral;
    if (!rhs.isList) throw Exception('Cannot unpack non-list');
    final list = rhs.asList;
    for (int i = 0; i < tuple.items.length; i++) {
      final target = tuple.items[i];
      if (target is Identifier) {
        ctx.set(
          target.name,
          i < list.length ? list[i] : const JinjaUndefined(),
        );
      }
    }
  } else if (assignee is MemberExpression) {
    // Set property: foo.bar = val
    final mem = assignee as MemberExpression;
    if (mem.computed) {
      throw Exception('Computed property assignment not supported');
    }
    if (mem.property is! Identifier) {
      throw Exception('Expected identifier property');
    }

    final obj = mem.object.execute(ctx);
    if (obj is JinjaMap) {
      obj.items[val((mem.property as Identifier).name)] = rhs;
    } else {
      throw Exception('Cannot set attribute on ${obj.typeName}');
    }
  }

  return const JinjaNone();
}