ReviewOS

zig-utils/zig-js

Parser: reject deletion of optional private-field references as an early error

#919
Closed glennmichael123 opened this 9 days ago ·
9 days ago

Parent: #904; related #899 and #918.

The parser rejects direct private-field deletion but misses an optional-chain wrapper. parseUnary checks only .member; parseMemberTail returns .optional_chain for optional accesses. Consequently a class containing delete obj?.#x or delete null?.#x is accepted, and earlier eval statements execute instead of being prevented by the required early SyntaxError.

Example:

var touched = 0;
try { eval('touched = 1; class C { #x; m(o) { delete o?.#x; } }'); }
catch (error) { /* must be SyntaxError, touched must remain 0 */ }

ECMAScript 13.5.1.1 explicitly covers private OptionalChain references and parenthesized forms: https://tc39.es/ecma262/2026/multipage/ecmascript-language-expressions.html#sec-delete-operator-static-semantics-early-errors

An 18-case before-fix probe shows eight optional-private early-error violations in both tree-walker and required VM. Node/V8 rejects them; the installed JSC accepts them, so JSC's acceptance must not become the specification oracle here. Two direct-private cases already reject but lose the specific diagnostic and operator location. Eight valid controls cover call results, public/computed outer properties, sequence values, private reads in computed keys, and a public string key spelled '#x'.

Fix the private-reference classification at the delete operator, without recursively rejecting private reads that only supply a value to a valid outer operation. Preserve a specific private-deletion diagnostic and the owned delete-operator position through nested templates. Add script/module and tree/VM early-error non-execution tests, keep every valid control, and measure the pinned class/delete/optional-chain corpus before and after. This is a semantics correction, not a blanket JSC-parity claim.

9 days ago

Landed in https://github.com/zig-utils/zig-js/commit/6256244884be309974ad72df75e7fabe5846fb08. The shared parser now rejects optional private-field deletion before evaluation and retains its diagnostic name/location, while preserving valid public-property, call-result, and sequence controls. Verification: 70 focused units passed without failures or leaks; six pinned test262 subtrees retained 8,617 passes and zero failures before/after. The focused tree-walker and required-VM probe improved from 10/18 to 18/18 specification outcomes. Eight optional-private acceptance discrepancies in the installed JSC are deliberately not copied. This does not claim full-suite verification or complete JSC diagnostic parity. Parent #904 and related #899 remain open.

Sign in to comment on this issue.