in packages/jinja/src/runtime.ts [1135:1174]
private evaluateMemberExpression(expr: MemberExpression, environment: Environment): AnyRuntimeValue {
const object = this.evaluate(expr.object, environment);
let property;
if (expr.computed) {
if (expr.property.type === "SliceExpression") {
return this.evaluateSliceExpression(object, expr.property as SliceExpression, environment);
} else {
property = this.evaluate(expr.property, environment);
}
} else {
property = new StringValue((expr.property as Identifier).value);
}
let value;
if (object instanceof ObjectValue) {
if (!(property instanceof StringValue)) {
throw new Error(`Cannot access property with non-string: got ${property.type}`);
}
value = object.value.get(property.value) ?? object.builtins.get(property.value);
} else if (object instanceof ArrayValue || object instanceof StringValue) {
if (property instanceof IntegerValue) {
value = object.value.at(property.value);
if (object instanceof StringValue) {
value = new StringValue(object.value.at(property.value));
}
} else if (property instanceof StringValue) {
value = object.builtins.get(property.value);
} else {
throw new Error(`Cannot access property with non-string/non-number: got ${property.type}`);
}
} else {
if (!(property instanceof StringValue)) {
throw new Error(`Cannot access property with non-string: got ${property.type}`);
}
value = object.builtins.get(property.value);
}
return value instanceof RuntimeValue ? value : new UndefinedValue();
}