Problem
obj.#x += 1 (compound assignment) and obj.#x++ (update expression) on private fields/methods are not implemented. PR #532 added obj.#x = val (plain assignment) via a new PrivateMemberAssign AST variant, but compound and update paths bypass that variant entirely.
What works
class C {
#x = 1;
setX(v) { this.#x = v; } // plain assignment → PrivateMemberAssign → set_private_field ✓
getX() { return this.#x; } // PrivateMember read → get_private_field ✓
}
What fails
class C {
#x = 1;
add(v) { this.#x += v; } // CompoundAssign(op, PrivateMember(...), ...) → no handler
inc() { this.#x++; } // UpdateExpr(_, PrivateMember(...), ...) → no handler
}
Root cause
The parser produces CompoundAssign(AddAssign, PrivateMember(obj, "x"), value, loc) for obj.#x += val and UpdateExpr(PlusPlus, PrivateMember(obj, "x"), false, loc) for obj.#x++. These are dispatched to eval_compound_assign (in operators.mbt) and eval_update (in eval_expr.mbt) respectively — neither has a PrivateMember arm for the LHS target.
Required changes
-
interpreter/runtime/operators.mbt: eval_compound_assign needs a PrivateMember arm that:
- Evaluates the LHS
PrivateMember(obj, name)
- Gets
[[PrivateBrand]] from env
- Reads the current value via
get_private_field
- Computes the result with
eval_binary_op
- Writes back via
set_private_field
-
interpreter/runtime/eval_expr.mbt: eval_update (or its UpdateExpr dispatch) needs a PrivateMember arm that:
- Evaluates the LHS
- Gets brand, reads, updates, writes back
Reference
PR #532 (plain assignment implementation), issue #528 (parent tracking issue).
Problem
obj.#x += 1(compound assignment) andobj.#x++(update expression) on private fields/methods are not implemented. PR #532 addedobj.#x = val(plain assignment) via a newPrivateMemberAssignAST variant, but compound and update paths bypass that variant entirely.What works
What fails
Root cause
The parser produces
CompoundAssign(AddAssign, PrivateMember(obj, "x"), value, loc)forobj.#x += valandUpdateExpr(PlusPlus, PrivateMember(obj, "x"), false, loc)forobj.#x++. These are dispatched toeval_compound_assign(inoperators.mbt) andeval_update(ineval_expr.mbt) respectively — neither has aPrivateMemberarm for the LHS target.Required changes
interpreter/runtime/operators.mbt:eval_compound_assignneeds aPrivateMemberarm that:PrivateMember(obj, name)[[PrivateBrand]]from envget_private_fieldeval_binary_opset_private_fieldinterpreter/runtime/eval_expr.mbt:eval_update(or itsUpdateExprdispatch) needs aPrivateMemberarm that:Reference
PR #532 (plain assignment implementation), issue #528 (parent tracking issue).