join_vars folds an assignment into an object literal with a computed accessor key, skipping the setter
Bug report or Feature request?
Bug report.
Version (complete output of terser -V or specific git commit)
terser 5.49.0 (also reproduces on master, 3433d00)
Complete CLI command or minify() options used
terser test.js -c — also happens with plain minify(code) defaults.
terser input
const k = "x";
const o = {
set [k](v) { console.log("setter ran:", v); }
};
o.x = 1;terser output or error
const k="x",o={set[k](v){console.log("setter ran:",v)},x:1};Running that prints nothing at all — the setter is never invoked.
Expected result
setter ran: 1, which is what node prints for the input.
The getter form loses a value rather than a call:
const k = "x";
const o = { get [k]() { return 4; } };
o.x = 8;
console.log(o.x); // node: 4, minified: 8join_object_assignments in lib/compress/tighten-body.js folds o.x = 1 into the
literal. Before doing so it checks that no existing property already defines x, but
the check is node.key.name != prop, and key.name is only meaningful for a
non-computed accessor, where key is an AST_SymbolMethod. With a computed key it
reads .name off whatever expression sits in the brackets — here the AST_SymbolRef
k, whose name is "k" — so the collision is never seen. A static set x(v) is
handled correctly, which is why this only shows up with [k].
I have a patch that bails out unless every key is statically known (a string, or the
AST_SymbolMethod of a non-computed accessor), so static accessors keep folding as
they do today. Full compress + mocha suites pass with it, plus the ufuzz run from CI.
Happy to send it as a PR if you want it.
Source: terser/terser