execute method
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();
}