mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 15:58:11 +00:00
LibJS: Use a synthetic constructor if class with parent doesn't have one
We already did this but it called the @@iterator method of %Array.prototype% visible to the user for example by overriding that method. This should not be visible so we use a special version of SuperCall now.
This commit is contained in:
parent
b79f03182d
commit
ae349ec6a8
4 changed files with 100 additions and 4 deletions
|
@ -1313,9 +1313,16 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_
|
|||
if (!super_class.is_null()) {
|
||||
// Set constructor to the result of parsing the source text
|
||||
// constructor(... args){ super (...args);}
|
||||
// However: The most notable distinction is that while the aforementioned ECMAScript
|
||||
// source text observably calls the @@iterator method on %Array.prototype%,
|
||||
// this function does not.
|
||||
// So we use a custom version of SuperCall which doesn't use the @@iterator
|
||||
// method on %Array.prototype% visibly.
|
||||
FlyString argument_name = "args";
|
||||
auto super_call = create_ast_node<SuperCall>(
|
||||
{ m_state.current_token.filename(), rule_start.position(), position() },
|
||||
Vector { CallExpression::Argument { create_ast_node<Identifier>({ m_state.current_token.filename(), rule_start.position(), position() }, "args"), true } });
|
||||
SuperCall::IsPartOfSyntheticConstructor::Yes,
|
||||
CallExpression::Argument { create_ast_node<Identifier>({ m_state.current_token.filename(), rule_start.position(), position() }, "args"), true });
|
||||
// NOTE: While the JS approximation above doesn't do `return super(...args)`, the
|
||||
// abstract closure is expected to capture and return the result, so we do need a
|
||||
// return statement here to create the correct completion.
|
||||
|
@ -1323,7 +1330,7 @@ NonnullRefPtr<ClassExpression> Parser::parse_class_expression(bool expect_class_
|
|||
|
||||
constructor = create_ast_node<FunctionExpression>(
|
||||
{ m_state.current_token.filename(), rule_start.position(), position() }, class_name, "",
|
||||
move(constructor_body), Vector { FunctionNode::Parameter { FlyString { "args" }, nullptr, true } }, 0, FunctionKind::Normal,
|
||||
move(constructor_body), Vector { FunctionNode::Parameter { move(argument_name), nullptr, true } }, 0, FunctionKind::Normal,
|
||||
/* is_strict_mode */ true, /* might_need_arguments_object */ false, /* contains_direct_call_to_eval */ false);
|
||||
} else {
|
||||
constructor = create_ast_node<FunctionExpression>(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue