private evaluateSet()

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