in packages/jinja/src/runtime.ts [1176:1213]
private evaluateSet(node: SetStatement, environment: Environment): NullValue {
const rhs = node.value ? this.evaluate(node.value, environment) : this.evaluateBlock(node.body, environment);
if (node.assignee.type === "Identifier") {
const variableName = (node.assignee as Identifier).value;
environment.setVariable(variableName, rhs);
} else if (node.assignee.type === "TupleLiteral") {
const tuple = node.assignee as TupleLiteral;
if (!(rhs instanceof ArrayValue)) {
throw new Error(`Cannot unpack non-iterable type in set: ${rhs.type}`);
}
const arr = rhs.value;
if (arr.length !== tuple.value.length) {
throw new Error(`Too ${tuple.value.length > arr.length ? "few" : "many"} items to unpack in set`);
}
for (let i = 0; i < tuple.value.length; ++i) {
const elem = tuple.value[i];
if (elem.type !== "Identifier") {
throw new Error(`Cannot unpack to non-identifier in set: ${elem.type}`);
}
environment.setVariable((elem as Identifier).value, arr[i]);
}
} else if (node.assignee.type === "MemberExpression") {
const member = node.assignee as MemberExpression;
const object = this.evaluate(member.object, environment);
if (!(object instanceof ObjectValue)) {
throw new Error("Cannot assign to member of non-object");
}
if (member.property.type !== "Identifier") {
throw new Error("Cannot assign to member with non-identifier property");
}
object.value.set((member.property as Identifier).value, rhs);
} else {
throw new Error(`Invalid LHS inside assignment expression: ${JSON.stringify(node.assignee)}`);
}
return new NullValue();
}