Source code

Revision control

Copy as Markdown

Other Tools

// |reftest| skip-if(!xulRuntime.shell) -- needs evaluate
// Any copyright is dedicated to the Public Domain.
// Attempting to lexically redefine a var is a syntax error.
evaluate("var a;");
assertThrowsInstanceOf(() => evaluate("let a;"), SyntaxError);
// Attempting to lexically redefine a configurable global property that's not a
// var is okay.
this.b = 42;
assertEq(b, 42);
evaluate("let b = 17;");
assertEq(b, 17);
// Attempting to lexically redefine a configurable global property that wasn't
// a var initially but was later declared as one, isn't okay.
this.c = 8675309;
assertEq(c, 8675309);
evaluate("var c;");
assertThrowsInstanceOf(() => evaluate("let c;"), SyntaxError);
// Attempting to lexically redefine a var added by eval code isn't okay.
assertEq(typeof d, "undefined");
eval("var d = 33;");
assertEq(d, 33);
assertThrowsInstanceOf(() => evaluate("let d;"), SyntaxError);
// Attempting to lexically redefine a var added by eval code, then deleted *as a
// name*, is okay. (The |var| will add the name to the global environment
// record's [[VarNames]], but deletion will go through the global environment
// record's DeleteBinding and so will remove it.)
assertEq(typeof e, "undefined");
eval("var e = 'ohia';");
assertEq(e, "ohia");
delete e;
assertEq(this.hasOwnProperty("e"), false);
evaluate("let e = 3.141592654;");
assertEq(e, 3.141592654);
// Attempting to lexically redefine a var added by eval code, then deleted *as a
// property*, isn't okay. (Deletion by property doesn't go through the global
// environment record's DeleteBinding algorithm, and so the name isn't removed
// from [[VarNames]].) And it remains non-okay even if the var is subsequently
// deleted as a name, because if the property doesn't exist, it's not removed
// from [[VarNames]]. But if we add the global property again and then delete
// by name, it *will* get removed from [[VarNames]].
assertEq(typeof f, "undefined");
eval("var f = 8675309;");
assertEq(f, 8675309);
delete this.f;
assertEq(this.hasOwnProperty("f"), false);
assertThrowsInstanceOf(() => evaluate("let f;"), SyntaxError);
delete f;
assertThrowsInstanceOf(() => evaluate("let f;"), SyntaxError);
this.f = 999;
assertThrowsInstanceOf(() => evaluate("let f;"), SyntaxError);
delete f;
evaluate("let f;");
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");