mirror of
https://github.com/RGBCube/serenity
synced 2025-05-23 19:05:08 +00:00
LibJS: Set name of anonymous functions during assignment
This commit is contained in:
parent
5e66f1900b
commit
25cf0da2fb
3 changed files with 56 additions and 6 deletions
|
@ -46,6 +46,23 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
|
static void update_function_name(Value& value, const FlyString& name)
|
||||||
|
{
|
||||||
|
if (!value.is_object())
|
||||||
|
return;
|
||||||
|
auto& object = value.as_object();
|
||||||
|
if (object.is_function()) {
|
||||||
|
auto& function = static_cast<ScriptFunction&>(object);
|
||||||
|
if (function.name().is_empty())
|
||||||
|
function.set_name(name);
|
||||||
|
} else if (object.is_array()) {
|
||||||
|
auto& array = static_cast<Array&>(object);
|
||||||
|
for (size_t i = 0; i < array.elements().size(); ++i) {
|
||||||
|
update_function_name(array.elements()[i], name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Value ScopeNode::execute(Interpreter& interpreter) const
|
Value ScopeNode::execute(Interpreter& interpreter) const
|
||||||
{
|
{
|
||||||
return interpreter.run(*this);
|
return interpreter.run(*this);
|
||||||
|
@ -861,6 +878,7 @@ Value AssignmentExpression::execute(Interpreter& interpreter) const
|
||||||
if (reference.is_unresolvable())
|
if (reference.is_unresolvable())
|
||||||
return interpreter.throw_exception<ReferenceError>("Invalid left-hand side in assignment");
|
return interpreter.throw_exception<ReferenceError>("Invalid left-hand side in assignment");
|
||||||
|
|
||||||
|
update_function_name(rhs_result, reference.name().as_string());
|
||||||
reference.put(interpreter, rhs_result);
|
reference.put(interpreter, rhs_result);
|
||||||
|
|
||||||
if (interpreter.exception())
|
if (interpreter.exception())
|
||||||
|
@ -965,7 +983,9 @@ Value VariableDeclaration::execute(Interpreter& interpreter) const
|
||||||
auto initalizer_result = init->execute(interpreter);
|
auto initalizer_result = init->execute(interpreter);
|
||||||
if (interpreter.exception())
|
if (interpreter.exception())
|
||||||
return {};
|
return {};
|
||||||
interpreter.set_variable(declarator.id().string(), initalizer_result, true);
|
auto variable_name = declarator.id().string();
|
||||||
|
update_function_name(initalizer_result, variable_name);
|
||||||
|
interpreter.set_variable(variable_name, initalizer_result, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return js_undefined();
|
return js_undefined();
|
||||||
|
@ -1075,6 +1095,7 @@ Value ObjectExpression::execute(Interpreter& interpreter) const
|
||||||
auto value = property.value().execute(interpreter);
|
auto value = property.value().execute(interpreter);
|
||||||
if (interpreter.exception())
|
if (interpreter.exception())
|
||||||
return {};
|
return {};
|
||||||
|
update_function_name(value, key);
|
||||||
object->put(key, value);
|
object->put(key, value);
|
||||||
}
|
}
|
||||||
return object;
|
return object;
|
||||||
|
|
|
@ -45,6 +45,7 @@ public:
|
||||||
virtual Value construct(Interpreter&) override;
|
virtual Value construct(Interpreter&) override;
|
||||||
|
|
||||||
virtual const FlyString& name() const override { return m_name; };
|
virtual const FlyString& name() const override { return m_name; };
|
||||||
|
void set_name(const FlyString& name) { m_name = name; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual bool is_script_function() const final { return true; }
|
virtual bool is_script_function() const final { return true; }
|
||||||
|
|
|
@ -1,16 +1,44 @@
|
||||||
load("test-common.js");
|
load("test-common.js");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var f = function () { }
|
assert((function () { }).name === "");
|
||||||
assert(f.name === "");
|
|
||||||
assert((f.name = "f") === "f");
|
|
||||||
assert(f.name === "");
|
|
||||||
|
|
||||||
function foo() { }
|
var foo = function () { }
|
||||||
assert(foo.name === "foo");
|
assert(foo.name === "foo");
|
||||||
assert((foo.name = "bar") === "bar");
|
assert((foo.name = "bar") === "bar");
|
||||||
assert(foo.name === "foo");
|
assert(foo.name === "foo");
|
||||||
|
|
||||||
|
var a, b;
|
||||||
|
a = b = function () { }
|
||||||
|
assert(a.name === "b");
|
||||||
|
assert(b.name === "b");
|
||||||
|
|
||||||
|
var arr = [
|
||||||
|
function () { },
|
||||||
|
function () { },
|
||||||
|
function () { }
|
||||||
|
];
|
||||||
|
assert(arr[0].name === "arr");
|
||||||
|
assert(arr[1].name === "arr");
|
||||||
|
assert(arr[2].name === "arr");
|
||||||
|
|
||||||
|
var f;
|
||||||
|
var o = { a: function () { } };
|
||||||
|
assert(o.a.name === "a");
|
||||||
|
f = o.a;
|
||||||
|
assert(f.name === "a");
|
||||||
|
assert(o.a.name === "a");
|
||||||
|
o = { ...o, b: f };
|
||||||
|
assert(o.a.name === "a");
|
||||||
|
assert(o.b.name === "a");
|
||||||
|
o.c = function () { };
|
||||||
|
assert(o.c.name === "c");
|
||||||
|
|
||||||
|
function bar() { }
|
||||||
|
assert(bar.name === "bar");
|
||||||
|
assert((bar.name = "baz") === "baz");
|
||||||
|
assert(bar.name === "bar");
|
||||||
|
|
||||||
assert(console.log.name === "log");
|
assert(console.log.name === "log");
|
||||||
assert((console.log.name = "warn") === "warn");
|
assert((console.log.name = "warn") === "warn");
|
||||||
assert(console.log.name === "log");
|
assert(console.log.name === "log");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue