mirror of
https://github.com/RGBCube/serenity
synced 2025-05-14 09:14:58 +00:00
LibJS: Don't update names of resulting functions in object expression
The only cases where the name should be set is if the function comes from a direct anonymous function expression.
This commit is contained in:
parent
897c7f7cc2
commit
2bbea62176
4 changed files with 63 additions and 10 deletions
|
@ -3095,18 +3095,21 @@ Completion ObjectExpression::execute(Interpreter& interpreter) const
|
|||
continue;
|
||||
}
|
||||
|
||||
if (value.is_function() && property.is_method())
|
||||
auto property_key = TRY(PropertyKey::from_value(vm, key));
|
||||
|
||||
if (property.is_method()) {
|
||||
VERIFY(value.is_function());
|
||||
static_cast<ECMAScriptFunctionObject&>(value.as_function()).set_home_object(object);
|
||||
|
||||
auto property_key = TRY(PropertyKey::from_value(vm, key));
|
||||
auto name = TRY(get_function_property_name(property_key));
|
||||
if (property.type() == ObjectProperty::Type::Getter) {
|
||||
name = DeprecatedString::formatted("get {}", name);
|
||||
} else if (property.type() == ObjectProperty::Type::Setter) {
|
||||
name = DeprecatedString::formatted("set {}", name);
|
||||
}
|
||||
auto name = MUST(get_function_property_name(property_key));
|
||||
if (property.type() == ObjectProperty::Type::Getter) {
|
||||
name = DeprecatedString::formatted("get {}", name);
|
||||
} else if (property.type() == ObjectProperty::Type::Setter) {
|
||||
name = DeprecatedString::formatted("set {}", name);
|
||||
}
|
||||
|
||||
update_function_name(value, name);
|
||||
update_function_name(value, name);
|
||||
}
|
||||
|
||||
switch (property.type()) {
|
||||
case ObjectProperty::Type::Getter:
|
||||
|
|
|
@ -1779,7 +1779,10 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
|
|||
}
|
||||
if (is_proto && property_type == ObjectProperty::Type::KeyValue)
|
||||
property_type = ObjectProperty::Type::ProtoSetter;
|
||||
properties.append(create_ast_node<ObjectProperty>({ m_source_code, rule_start.position(), position() }, *property_key, parse_expression(2), property_type, false));
|
||||
|
||||
auto rhs_expression = parse_expression(2);
|
||||
bool is_method = is<FunctionExpression>(*rhs_expression);
|
||||
properties.append(create_ast_node<ObjectProperty>({ m_source_code, rule_start.position(), position() }, *property_key, move(rhs_expression), property_type, is_method));
|
||||
} else if (property_key && property_value) {
|
||||
if (m_state.strict_mode && is<StringLiteral>(*property_key)) {
|
||||
auto& string_literal = static_cast<StringLiteral const&>(*property_key);
|
||||
|
|
|
@ -67,3 +67,11 @@ describe("normal behavior", () => {
|
|||
expect(o.foo).toBe("bar");
|
||||
});
|
||||
});
|
||||
|
||||
test("does not override frozen function name", () => {
|
||||
const func = Object.freeze(function () {
|
||||
return 12;
|
||||
});
|
||||
const obj = Object.freeze({ name: func });
|
||||
expect(obj.name()).toBe(12);
|
||||
});
|
||||
|
|
|
@ -215,3 +215,42 @@ describe("errors", () => {
|
|||
expect("({ ...foo: bar })").not.toEval();
|
||||
});
|
||||
});
|
||||
|
||||
describe("naming of anon functions", () => {
|
||||
test("method has name", () => {
|
||||
expect({ func() {} }.func.name).toBe("func");
|
||||
});
|
||||
|
||||
test("getter has name", () => {
|
||||
expect(Object.getOwnPropertyDescriptor({ get func() {} }, "func").get.name).toBe(
|
||||
"get func"
|
||||
);
|
||||
});
|
||||
|
||||
test("setter has name", () => {
|
||||
expect(Object.getOwnPropertyDescriptor({ set func(v) {} }, "func").set.name).toBe(
|
||||
"set func"
|
||||
);
|
||||
});
|
||||
|
||||
test("anon function property", () => {
|
||||
expect({ func: function () {} }.func.name).toBe("func");
|
||||
});
|
||||
|
||||
test("anon function from within parenthesis", () => {
|
||||
expect({ func: function () {} }.func.name).toBe("func");
|
||||
});
|
||||
|
||||
test("anon function from indirect expression", () => {
|
||||
expect({ func: (0, function () {}) }.func.name).toBe("");
|
||||
});
|
||||
|
||||
test("function from function call does not get named", () => {
|
||||
function f() {
|
||||
return function () {};
|
||||
}
|
||||
|
||||
expect(f().name).toBe("");
|
||||
expect({ func: f() }.func.name).toBe("");
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue