(dest: Ast.Expression, scope: Scope, callStack: readonly CallInfo[])
| 1711 | |
| 1712 | @autobind |
| 1713 | private async getReference(dest: Ast.Expression, scope: Scope, callStack: readonly CallInfo[]): Promise<Reference | Control> { |
| 1714 | switch (dest.type) { |
| 1715 | case 'identifier': { |
| 1716 | return Reference.variable(dest.name, scope); |
| 1717 | } |
| 1718 | case 'index': { |
| 1719 | const assignee = await this._eval(dest.target, scope, callStack); |
| 1720 | if (isControl(assignee)) { |
| 1721 | return assignee; |
| 1722 | } |
| 1723 | const i = await this._eval(dest.index, scope, callStack); |
| 1724 | if (isControl(i)) { |
| 1725 | return i; |
| 1726 | } |
| 1727 | if (isArray(assignee)) { |
| 1728 | assertNumber(i); |
| 1729 | return Reference.index(assignee, i.value); |
| 1730 | } else if (isObject(assignee)) { |
| 1731 | assertString(i); |
| 1732 | return Reference.prop(assignee, i.value); |
| 1733 | } else { |
| 1734 | throw new AiScriptRuntimeError(`Cannot read prop (${reprValue(i)}) of ${assignee.type}.`); |
| 1735 | } |
| 1736 | } |
| 1737 | case 'prop': { |
| 1738 | const assignee = await this._eval(dest.target, scope, callStack); |
| 1739 | if (isControl(assignee)) { |
| 1740 | return assignee; |
| 1741 | } |
| 1742 | assertObject(assignee); |
| 1743 | |
| 1744 | return Reference.prop(assignee, dest.name); |
| 1745 | } |
| 1746 | case 'arr': { |
| 1747 | const items: Reference[] = []; |
| 1748 | for (const item of dest.value) { |
| 1749 | const ref = await this.getReference(item, scope, callStack); |
| 1750 | if (isControl(ref)) { |
| 1751 | return ref; |
| 1752 | } |
| 1753 | items.push(ref); |
| 1754 | } |
| 1755 | return Reference.arr(items); |
| 1756 | } |
| 1757 | case 'obj': { |
| 1758 | const entries = new Map<string, Reference>(); |
| 1759 | for (const [key, item] of dest.value.entries()) { |
| 1760 | const ref = await this.getReference(item, scope, callStack); |
| 1761 | if (isControl(ref)) { |
| 1762 | return ref; |
| 1763 | } |
| 1764 | entries.set(key, ref); |
| 1765 | } |
| 1766 | return Reference.obj(entries); |
| 1767 | } |
| 1768 | default: { |
| 1769 | throw new AiScriptRuntimeError('The left-hand side of an assignment expression must be a variable or a property/index access.'); |
| 1770 | } |
no test coverage detected