ladybird/Tests/LibJS/Runtime/invalid-lhs-in-assignment.js
Andreas Kling 19c1cae030 LibJS: Preserve strict unresolvable assignment references
Resolve strict global-looking assignment targets before evaluating their
right-hand side instead of lowering them directly to SetGlobal. Preserve
the original unresolvable reference for PutValue so a RHS-created global
cannot hide the ReferenceError.

Add a runtime test for that ordering and update the bytecode expectation
for a strict top-level assignment that now uses SetResolvedBinding.
2026-05-22 14:30:35 +02:00

72 lines
2.4 KiB
JavaScript

test("assignment to function call", () => {
expect(() => {
function foo() {}
foo() = "foo";
}).toThrowWithMessage(ReferenceError, "Invalid left-hand side in assignment");
});
test("Postfix operator after function call", () => {
expect(() => {
function foo() {}
foo()++;
}).toThrow(ReferenceError);
});
test("assignment to function call in strict mode is a SyntaxError", () => {
expect("'use strict'; foo() = 'foo'").not.toEval();
});
test("strict assignment to unresolvable reference preserves initial reference", () => {
delete globalThis.__test_unresolvable_assignment;
expect(() => {
"use strict";
__test_unresolvable_assignment = (globalThis.__test_unresolvable_assignment = 5);
}).toThrowWithMessage(ReferenceError, "'__test_unresolvable_assignment' is not defined");
expect(globalThis.__test_unresolvable_assignment).toBe(5);
delete globalThis.__test_unresolvable_assignment;
});
test("assignment to inline function call", () => {
expect(() => {
(function () {})() = "foo";
}).toThrowWithMessage(ReferenceError, "Invalid left-hand side in assignment");
});
test("assignment to invalid LHS is syntax error", () => {
expect("1 += 1").not.toEval();
expect("1 -= 1").not.toEval();
expect("1 *= 1").not.toEval();
expect("1 /= 1").not.toEval();
expect("1 %= 1").not.toEval();
expect("1 **= 1").not.toEval();
expect("1 &= 1").not.toEval();
expect("1 |= 1").not.toEval();
expect("1 ^= 1").not.toEval();
expect("1 <<= 1").not.toEval();
expect("1 >>= 1").not.toEval();
expect("1 >>>= 1").not.toEval();
expect("1 = 1").not.toEval();
expect("1 &&= 1").not.toEval();
expect("1 ||= 1").not.toEval();
expect("1 ??= 1").not.toEval();
});
test("assignment to call LHS is only syntax error for new operators", () => {
expect("f() += 1").toEval();
expect("f() -= 1").toEval();
expect("f() *= 1").toEval();
expect("f() /= 1").toEval();
expect("f() %= 1").toEval();
expect("f() **= 1").toEval();
expect("f() &= 1").toEval();
expect("f() |= 1").toEval();
expect("f() ^= 1").toEval();
expect("f() <<= 1").toEval();
expect("f() >>= 1").toEval();
expect("f() >>>= 1").toEval();
expect("f() = 1").toEval();
expect("f() &&= 1").not.toEval();
expect("f() ||= 1").not.toEval();
expect("f() ??= 1").not.toEval();
});