[parser] Refactor of ParseClass* and ParseNativeDeclaration
This patch moves the following parsing method to ParserBase: - ParseClassDeclaration - ParseClassLiteral - ParseNativeDeclaration R=adamk@chromium.org, marja@chromium.org BUG= LOG=N Review-Url: https://codereview.chromium.org/2368083002 Cr-Commit-Position: refs/heads/master@{#39814}
This commit is contained in:
parent
b15dd963a3
commit
7818355363
@ -133,7 +133,8 @@ struct FormalParametersBase {
|
||||
// typedef ObjectLiteralProperty;
|
||||
// typedef ClassLiteralProperty;
|
||||
// typedef ExpressionList;
|
||||
// typedef PropertyList;
|
||||
// typedef ObjectPropertyList;
|
||||
// typedef ClassPropertyList;
|
||||
// typedef FormalParameters;
|
||||
// typedef Statement;
|
||||
// typedef StatementList;
|
||||
@ -161,7 +162,6 @@ class ParserBase {
|
||||
typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT;
|
||||
typedef typename Types::ClassLiteralProperty ClassLiteralPropertyT;
|
||||
typedef typename Types::ExpressionList ExpressionListT;
|
||||
typedef typename Types::PropertyList PropertyListT;
|
||||
typedef typename Types::FormalParameters FormalParametersT;
|
||||
typedef typename Types::Statement StatementT;
|
||||
typedef typename Types::StatementList StatementListT;
|
||||
@ -671,6 +671,25 @@ class ParserBase {
|
||||
DeclarationParsingResult parsing_result;
|
||||
};
|
||||
|
||||
struct ClassInfo {
|
||||
public:
|
||||
explicit ClassInfo(ParserBase* parser)
|
||||
: proxy(nullptr),
|
||||
extends(parser->impl()->EmptyExpression()),
|
||||
properties(parser->impl()->NewClassPropertyList(4)),
|
||||
instance_field_initializers(parser->impl()->NewExpressionList(0)),
|
||||
constructor(parser->impl()->EmptyFunctionLiteral()),
|
||||
has_seen_constructor(false),
|
||||
static_initializer_var(nullptr) {}
|
||||
VariableProxy* proxy;
|
||||
ExpressionT extends;
|
||||
typename Types::ClassPropertyList properties;
|
||||
ExpressionListT instance_field_initializers;
|
||||
FunctionLiteralT constructor;
|
||||
bool has_seen_constructor;
|
||||
Variable* static_initializer_var;
|
||||
};
|
||||
|
||||
DeclarationScope* NewScriptScope() const {
|
||||
return new (zone()) DeclarationScope(zone(), ast_value_factory());
|
||||
}
|
||||
@ -1174,6 +1193,10 @@ class ParserBase {
|
||||
FunctionKind kind, FunctionBodyType type,
|
||||
bool accept_IN, int pos, bool* ok);
|
||||
ExpressionT ParseAsyncFunctionLiteral(bool* ok);
|
||||
ExpressionT ParseClassLiteral(IdentifierT name,
|
||||
Scanner::Location class_name_location,
|
||||
bool name_is_strict_reserved,
|
||||
int class_token_pos, bool* ok);
|
||||
ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
|
||||
ExpressionT ParseSuperExpression(bool is_new, bool* ok);
|
||||
ExpressionT ParseNewTargetExpression(bool* ok);
|
||||
@ -1195,6 +1218,9 @@ class ParserBase {
|
||||
StatementT ParseHoistableDeclaration(int pos, ParseFunctionFlags flags,
|
||||
ZoneList<const AstRawString*>* names,
|
||||
bool default_export, bool* ok);
|
||||
StatementT ParseClassDeclaration(ZoneList<const AstRawString*>* names,
|
||||
bool default_export, bool* ok);
|
||||
StatementT ParseNativeDeclaration(bool* ok);
|
||||
|
||||
// Under some circumstances, we allow preparsing to abort if the preparsed
|
||||
// function is "long and trivial", and fully parse instead. Our current
|
||||
@ -1783,7 +1809,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression(
|
||||
case Token::CLASS: {
|
||||
BindingPatternUnexpectedToken();
|
||||
Consume(Token::CLASS);
|
||||
int class_token_position = position();
|
||||
int class_token_pos = position();
|
||||
IdentifierT name = impl()->EmptyIdentifier();
|
||||
bool is_strict_reserved_name = false;
|
||||
Scanner::Location class_name_location = Scanner::Location::invalid();
|
||||
@ -1792,9 +1818,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression(
|
||||
CHECK_OK);
|
||||
class_name_location = scanner()->location();
|
||||
}
|
||||
return impl()->ParseClassLiteral(name, class_name_location,
|
||||
is_strict_reserved_name,
|
||||
class_token_position, ok);
|
||||
return ParseClassLiteral(name, class_name_location,
|
||||
is_strict_reserved_name, class_token_pos, ok);
|
||||
}
|
||||
|
||||
case Token::TEMPLATE_SPAN:
|
||||
@ -2456,7 +2481,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral(
|
||||
// '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
|
||||
|
||||
int pos = peek_position();
|
||||
PropertyListT properties = impl()->NewPropertyList(4);
|
||||
typename Types::ObjectPropertyList properties =
|
||||
impl()->NewObjectPropertyList(4);
|
||||
int number_of_boilerplate_properties = 0;
|
||||
bool has_computed_names = false;
|
||||
ObjectLiteralChecker checker(this);
|
||||
@ -3700,6 +3726,72 @@ ParserBase<Impl>::ParseHoistableDeclaration(
|
||||
is_async, names, ok);
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseClassDeclaration(
|
||||
ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
|
||||
// ClassDeclaration ::
|
||||
// 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
|
||||
// 'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
|
||||
//
|
||||
// The anonymous form is allowed iff [default_export] is true.
|
||||
//
|
||||
// 'class' is expected to be consumed by the caller.
|
||||
//
|
||||
// A ClassDeclaration
|
||||
//
|
||||
// class C { ... }
|
||||
//
|
||||
// has the same semantics as:
|
||||
//
|
||||
// let C = class C { ... };
|
||||
//
|
||||
// so rewrite it as such.
|
||||
|
||||
int class_token_pos = position();
|
||||
IdentifierT name = impl()->EmptyIdentifier();
|
||||
bool is_strict_reserved = false;
|
||||
IdentifierT variable_name = impl()->EmptyIdentifier();
|
||||
if (default_export && (peek() == Token::EXTENDS || peek() == Token::LBRACE)) {
|
||||
impl()->GetDefaultStrings(&name, &variable_name);
|
||||
} else {
|
||||
name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
|
||||
CHECK_OK_CUSTOM(NullStatement));
|
||||
variable_name = name;
|
||||
}
|
||||
|
||||
ExpressionClassifier no_classifier(this);
|
||||
ExpressionT value =
|
||||
ParseClassLiteral(name, scanner()->location(), is_strict_reserved,
|
||||
class_token_pos, CHECK_OK_CUSTOM(NullStatement));
|
||||
int end_pos = position();
|
||||
return impl()->DeclareClass(variable_name, value, names, class_token_pos,
|
||||
end_pos, ok);
|
||||
}
|
||||
|
||||
// Language extension which is only enabled for source files loaded
|
||||
// through the API's extension mechanism. A native function
|
||||
// declaration is resolved by looking up the function through a
|
||||
// callback provided by the extension.
|
||||
template <typename Impl>
|
||||
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseNativeDeclaration(
|
||||
bool* ok) {
|
||||
int pos = peek_position();
|
||||
Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement));
|
||||
// Allow "eval" or "arguments" for backward compatibility.
|
||||
IdentifierT name = ParseIdentifier(kAllowRestrictedIdentifiers,
|
||||
CHECK_OK_CUSTOM(NullStatement));
|
||||
Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullStatement));
|
||||
if (peek() != Token::RPAREN) {
|
||||
do {
|
||||
ParseIdentifier(kAllowRestrictedIdentifiers,
|
||||
CHECK_OK_CUSTOM(NullStatement));
|
||||
} while (Check(Token::COMMA));
|
||||
}
|
||||
Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullStatement));
|
||||
Expect(Token::SEMICOLON, CHECK_OK_CUSTOM(NullStatement));
|
||||
return impl()->DeclareNative(name, pos, ok);
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
typename ParserBase<Impl>::StatementT
|
||||
ParserBase<Impl>::ParseAsyncFunctionDeclaration(
|
||||
@ -3931,11 +4023,71 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
|
||||
function_literal->set_should_be_used_once_hint();
|
||||
}
|
||||
|
||||
impl()->InferFunctionName(function_literal);
|
||||
impl()->AddFunctionForNameInference(function_literal);
|
||||
|
||||
return function_literal;
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
|
||||
IdentifierT name, Scanner::Location class_name_location,
|
||||
bool name_is_strict_reserved, int class_token_pos, bool* ok) {
|
||||
// All parts of a ClassDeclaration and ClassExpression are strict code.
|
||||
if (name_is_strict_reserved) {
|
||||
impl()->ReportMessageAt(class_name_location,
|
||||
MessageTemplate::kUnexpectedStrictReserved);
|
||||
*ok = false;
|
||||
return impl()->EmptyExpression();
|
||||
}
|
||||
if (impl()->IsEvalOrArguments(name)) {
|
||||
impl()->ReportMessageAt(class_name_location,
|
||||
MessageTemplate::kStrictEvalArguments);
|
||||
*ok = false;
|
||||
return impl()->EmptyExpression();
|
||||
}
|
||||
|
||||
BlockState block_state(zone(), &scope_state_);
|
||||
RaiseLanguageMode(STRICT);
|
||||
|
||||
ClassInfo class_info(this);
|
||||
impl()->DeclareClassVariable(name, block_state.scope(), &class_info,
|
||||
class_token_pos, CHECK_OK);
|
||||
|
||||
if (Check(Token::EXTENDS)) {
|
||||
block_state.set_start_position(scanner()->location().end_pos);
|
||||
ExpressionClassifier extends_classifier(this);
|
||||
class_info.extends = ParseLeftHandSideExpression(CHECK_OK);
|
||||
impl()->RewriteNonPattern(CHECK_OK);
|
||||
impl()->AccumulateFormalParameterContainmentErrors();
|
||||
} else {
|
||||
block_state.set_start_position(scanner()->location().end_pos);
|
||||
}
|
||||
|
||||
ClassLiteralChecker checker(this);
|
||||
|
||||
Expect(Token::LBRACE, CHECK_OK);
|
||||
|
||||
const bool has_extends = !impl()->IsEmptyExpression(class_info.extends);
|
||||
while (peek() != Token::RBRACE) {
|
||||
if (Check(Token::SEMICOLON)) continue;
|
||||
FuncNameInferrer::State fni_state(fni_);
|
||||
bool is_computed_name = false; // Classes do not care about computed
|
||||
// property names here.
|
||||
ExpressionClassifier property_classifier(this);
|
||||
ClassLiteralPropertyT property = ParseClassPropertyDefinition(
|
||||
&checker, has_extends, &is_computed_name,
|
||||
&class_info.has_seen_constructor, CHECK_OK);
|
||||
impl()->RewriteNonPattern(CHECK_OK);
|
||||
impl()->AccumulateFormalParameterContainmentErrors();
|
||||
|
||||
impl()->DeclareClassProperty(name, property, &class_info, CHECK_OK);
|
||||
impl()->InferFunctionName();
|
||||
}
|
||||
|
||||
Expect(Token::RBRACE, CHECK_OK);
|
||||
return impl()->RewriteClassLiteral(name, &class_info, class_token_pos, ok);
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
void ParserBase<Impl>::ParseAsyncFunctionBody(Scope* scope, StatementListT body,
|
||||
FunctionKind kind,
|
||||
@ -4287,7 +4439,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatementListItem(
|
||||
return ParseHoistableDeclaration(nullptr, false, ok);
|
||||
case Token::CLASS:
|
||||
Consume(Token::CLASS);
|
||||
return impl()->ParseClassDeclaration(nullptr, false, ok);
|
||||
return ParseClassDeclaration(nullptr, false, ok);
|
||||
case Token::VAR:
|
||||
case Token::CONST:
|
||||
return ParseVariableStatement(kStatementListItem, nullptr, ok);
|
||||
@ -4565,7 +4717,7 @@ ParserBase<Impl>::ParseExpressionOrLabelledStatement(
|
||||
if (extension_ != nullptr && peek() == Token::FUNCTION &&
|
||||
!scanner()->HasAnyLineTerminatorBeforeNext() && impl()->IsNative(expr) &&
|
||||
!scanner()->literal_contains_escapes()) {
|
||||
return impl()->ParseNativeDeclaration(ok);
|
||||
return ParseNativeDeclaration(ok);
|
||||
}
|
||||
|
||||
// Parsed expression statement, followed by semicolon.
|
||||
|
@ -1534,94 +1534,6 @@ Variable* Parser::Declare(Declaration* declaration,
|
||||
return variable;
|
||||
}
|
||||
|
||||
// Language extension which is only enabled for source files loaded
|
||||
// through the API's extension mechanism. A native function
|
||||
// declaration is resolved by looking up the function through a
|
||||
// callback provided by the extension.
|
||||
Statement* Parser::ParseNativeDeclaration(bool* ok) {
|
||||
int pos = peek_position();
|
||||
Expect(Token::FUNCTION, CHECK_OK);
|
||||
// Allow "eval" or "arguments" for backward compatibility.
|
||||
const AstRawString* name =
|
||||
ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
|
||||
Expect(Token::LPAREN, CHECK_OK);
|
||||
bool done = (peek() == Token::RPAREN);
|
||||
while (!done) {
|
||||
ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
|
||||
done = (peek() == Token::RPAREN);
|
||||
if (!done) {
|
||||
Expect(Token::COMMA, CHECK_OK);
|
||||
}
|
||||
}
|
||||
Expect(Token::RPAREN, CHECK_OK);
|
||||
Expect(Token::SEMICOLON, CHECK_OK);
|
||||
|
||||
// Make sure that the function containing the native declaration
|
||||
// isn't lazily compiled. The extension structures are only
|
||||
// accessible while parsing the first time not when reparsing
|
||||
// because of lazy compilation.
|
||||
GetClosureScope()->ForceEagerCompilation();
|
||||
|
||||
// TODO(1240846): It's weird that native function declarations are
|
||||
// introduced dynamically when we meet their declarations, whereas
|
||||
// other functions are set up when entering the surrounding scope.
|
||||
Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK);
|
||||
NativeFunctionLiteral* lit =
|
||||
factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
|
||||
return factory()->NewExpressionStatement(
|
||||
factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
|
||||
kNoSourcePosition),
|
||||
pos);
|
||||
}
|
||||
|
||||
Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
|
||||
bool default_export, bool* ok) {
|
||||
// ClassDeclaration ::
|
||||
// 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
|
||||
// 'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
|
||||
//
|
||||
// The anonymous form is allowed iff [default_export] is true.
|
||||
//
|
||||
// 'class' is expected to be consumed by the caller.
|
||||
//
|
||||
// A ClassDeclaration
|
||||
//
|
||||
// class C { ... }
|
||||
//
|
||||
// has the same semantics as:
|
||||
//
|
||||
// let C = class C { ... };
|
||||
//
|
||||
// so rewrite it as such.
|
||||
|
||||
int pos = position();
|
||||
|
||||
const AstRawString* name;
|
||||
bool is_strict_reserved;
|
||||
const AstRawString* variable_name;
|
||||
if (default_export && (peek() == Token::EXTENDS || peek() == Token::LBRACE)) {
|
||||
name = ast_value_factory()->default_string();
|
||||
is_strict_reserved = false;
|
||||
variable_name = ast_value_factory()->star_default_star_string();
|
||||
} else {
|
||||
name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
|
||||
variable_name = name;
|
||||
}
|
||||
|
||||
ExpressionClassifier no_classifier(this);
|
||||
Expression* value = ParseClassLiteral(name, scanner()->location(),
|
||||
is_strict_reserved, pos, CHECK_OK);
|
||||
|
||||
Declaration* decl = DeclareVariable(variable_name, LET, pos, CHECK_OK);
|
||||
decl->proxy()->var()->set_initializer_position(position());
|
||||
Assignment* assignment =
|
||||
factory()->NewAssignment(Token::INIT, decl->proxy(), value, pos);
|
||||
Statement* assignment_statement =
|
||||
factory()->NewExpressionStatement(assignment, kNoSourcePosition);
|
||||
if (names) names->Add(variable_name, zone());
|
||||
return assignment_statement;
|
||||
}
|
||||
|
||||
Block* Parser::BuildInitializationBlock(
|
||||
DeclarationParsingResult* parsing_result,
|
||||
ZoneList<const AstRawString*>* names, bool* ok) {
|
||||
@ -1677,6 +1589,40 @@ Statement* Parser::DeclareFunction(const AstRawString* variable_name,
|
||||
return factory()->NewEmptyStatement(kNoSourcePosition);
|
||||
}
|
||||
|
||||
Statement* Parser::DeclareClass(const AstRawString* variable_name,
|
||||
Expression* value,
|
||||
ZoneList<const AstRawString*>* names,
|
||||
int class_token_pos, int end_pos, bool* ok) {
|
||||
Declaration* decl =
|
||||
DeclareVariable(variable_name, LET, class_token_pos, CHECK_OK);
|
||||
decl->proxy()->var()->set_initializer_position(end_pos);
|
||||
Assignment* assignment = factory()->NewAssignment(Token::INIT, decl->proxy(),
|
||||
value, class_token_pos);
|
||||
Statement* assignment_statement =
|
||||
factory()->NewExpressionStatement(assignment, kNoSourcePosition);
|
||||
if (names) names->Add(variable_name, zone());
|
||||
return assignment_statement;
|
||||
}
|
||||
|
||||
Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) {
|
||||
// Make sure that the function containing the native declaration
|
||||
// isn't lazily compiled. The extension structures are only
|
||||
// accessible while parsing the first time not when reparsing
|
||||
// because of lazy compilation.
|
||||
GetClosureScope()->ForceEagerCompilation();
|
||||
|
||||
// TODO(1240846): It's weird that native function declarations are
|
||||
// introduced dynamically when we meet their declarations, whereas
|
||||
// other functions are set up when entering the surrounding scope.
|
||||
Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK);
|
||||
NativeFunctionLiteral* lit =
|
||||
factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
|
||||
return factory()->NewExpressionStatement(
|
||||
factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
|
||||
kNoSourcePosition),
|
||||
pos);
|
||||
}
|
||||
|
||||
ZoneList<const AstRawString*>* Parser::DeclareLabel(
|
||||
ZoneList<const AstRawString*>* labels, VariableProxy* var, bool* ok) {
|
||||
const AstRawString* label = var->raw_name();
|
||||
@ -3519,163 +3465,136 @@ FunctionLiteral* Parser::InsertClassFieldInitializer(
|
||||
return constructor;
|
||||
}
|
||||
|
||||
Expression* Parser::ParseClassLiteral(const AstRawString* name,
|
||||
Scanner::Location class_name_location,
|
||||
bool name_is_strict_reserved, int pos,
|
||||
bool* ok) {
|
||||
// All parts of a ClassDeclaration and ClassExpression are strict code.
|
||||
if (name_is_strict_reserved) {
|
||||
ReportMessageAt(class_name_location,
|
||||
MessageTemplate::kUnexpectedStrictReserved);
|
||||
*ok = false;
|
||||
return nullptr;
|
||||
}
|
||||
if (IsEvalOrArguments(name)) {
|
||||
ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
|
||||
*ok = false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BlockState block_state(zone(), &scope_state_);
|
||||
RaiseLanguageMode(STRICT);
|
||||
// If a class name is specified, this method declares the class variable
|
||||
// and sets class_info->proxy to point to that name.
|
||||
void Parser::DeclareClassVariable(const AstRawString* name, Scope* block_scope,
|
||||
ClassInfo* class_info, int class_token_pos,
|
||||
bool* ok) {
|
||||
#ifdef DEBUG
|
||||
scope()->SetScopeName(name);
|
||||
#endif
|
||||
|
||||
VariableProxy* proxy = nullptr;
|
||||
if (name != nullptr) {
|
||||
proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
|
||||
// TODO(verwaest): declare via block_state.
|
||||
Declaration* declaration =
|
||||
factory()->NewVariableDeclaration(proxy, block_state.scope(), pos);
|
||||
class_info->proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
|
||||
Declaration* declaration = factory()->NewVariableDeclaration(
|
||||
class_info->proxy, block_scope, class_token_pos);
|
||||
Declare(declaration, DeclarationDescriptor::NORMAL, CONST,
|
||||
Variable::DefaultInitializationFlag(CONST), CHECK_OK);
|
||||
Variable::DefaultInitializationFlag(CONST), ok);
|
||||
}
|
||||
}
|
||||
|
||||
// This method declares a property of the given class. It updates the
|
||||
// following fields of class_info, as appropriate:
|
||||
// - constructor
|
||||
// - static_initializer_var
|
||||
// - instance_field_initializers
|
||||
// - properties
|
||||
void Parser::DeclareClassProperty(const AstRawString* class_name,
|
||||
ClassLiteralProperty* property,
|
||||
ClassInfo* class_info, bool* ok) {
|
||||
if (class_info->has_seen_constructor && class_info->constructor == nullptr) {
|
||||
class_info->constructor = GetPropertyValue(property)->AsFunctionLiteral();
|
||||
DCHECK_NOT_NULL(class_info->constructor);
|
||||
class_info->constructor->set_raw_name(
|
||||
class_name != nullptr ? class_name
|
||||
: ast_value_factory()->empty_string());
|
||||
return;
|
||||
}
|
||||
|
||||
Expression* extends = nullptr;
|
||||
if (Check(Token::EXTENDS)) {
|
||||
block_state.set_start_position(scanner()->location().end_pos);
|
||||
ExpressionClassifier extends_classifier(this);
|
||||
extends = ParseLeftHandSideExpression(CHECK_OK);
|
||||
RewriteNonPattern(CHECK_OK);
|
||||
impl()->AccumulateFormalParameterContainmentErrors();
|
||||
} else {
|
||||
block_state.set_start_position(scanner()->location().end_pos);
|
||||
if (property->kind() == ClassLiteralProperty::FIELD) {
|
||||
DCHECK(allow_harmony_class_fields());
|
||||
if (property->is_static()) {
|
||||
if (class_info->static_initializer_var == nullptr) {
|
||||
class_info->static_initializer_var =
|
||||
NewTemporary(ast_value_factory()->empty_string());
|
||||
}
|
||||
// TODO(bakkot) only do this conditionally
|
||||
Expression* function = InstallHomeObject(
|
||||
property->value(),
|
||||
factory()->NewVariableProxy(class_info->static_initializer_var));
|
||||
ZoneList<Expression*>* args =
|
||||
new (zone()) ZoneList<Expression*>(2, zone());
|
||||
args->Add(function, zone());
|
||||
args->Add(factory()->NewVariableProxy(class_info->static_initializer_var),
|
||||
zone());
|
||||
Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall, args,
|
||||
kNoSourcePosition);
|
||||
property->set_value(call);
|
||||
} else {
|
||||
// if (is_computed_name) { // TODO(bakkot) figure out why this is
|
||||
// necessary for non-computed names in full-codegen
|
||||
ZoneList<Expression*>* to_name_args =
|
||||
new (zone()) ZoneList<Expression*>(1, zone());
|
||||
to_name_args->Add(property->key(), zone());
|
||||
property->set_key(factory()->NewCallRuntime(
|
||||
Runtime::kToName, to_name_args, kNoSourcePosition));
|
||||
//}
|
||||
const AstRawString* name = ClassFieldVariableName(
|
||||
true, ast_value_factory(),
|
||||
class_info->instance_field_initializers->length());
|
||||
VariableProxy* name_proxy =
|
||||
factory()->NewVariableProxy(name, NORMAL_VARIABLE);
|
||||
Declaration* name_declaration = factory()->NewVariableDeclaration(
|
||||
name_proxy, scope(), kNoSourcePosition);
|
||||
Variable* name_var =
|
||||
Declare(name_declaration, DeclarationDescriptor::NORMAL, CONST,
|
||||
kNeedsInitialization, ok, scope());
|
||||
DCHECK(*ok);
|
||||
if (!*ok) return;
|
||||
class_info->instance_field_initializers->Add(property->value(), zone());
|
||||
property->set_value(factory()->NewVariableProxy(name_var));
|
||||
}
|
||||
}
|
||||
class_info->properties->Add(property, zone());
|
||||
}
|
||||
|
||||
|
||||
ClassLiteralChecker checker(this);
|
||||
ZoneList<ClassLiteral::Property*>* properties = NewClassPropertyList(4);
|
||||
ZoneList<Expression*>* instance_field_initializers =
|
||||
new (zone()) ZoneList<Expression*>(0, zone());
|
||||
FunctionLiteral* constructor = nullptr;
|
||||
bool has_seen_constructor = false;
|
||||
Variable* static_initializer_var = nullptr;
|
||||
|
||||
// This method rewrites a class literal into a do-expression.
|
||||
// It uses the following fields of class_info:
|
||||
// - constructor (if missing, it updates it with a default constructor)
|
||||
// - proxy
|
||||
// - extends
|
||||
// - static_initializer_var
|
||||
// - instance_field_initializers
|
||||
// - properties
|
||||
Expression* Parser::RewriteClassLiteral(const AstRawString* name,
|
||||
ClassInfo* class_info, int pos,
|
||||
bool* ok) {
|
||||
int end_pos = scanner()->location().end_pos;
|
||||
Block* do_block = factory()->NewBlock(nullptr, 1, false, pos);
|
||||
Variable* result_var = NewTemporary(ast_value_factory()->empty_string());
|
||||
DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos);
|
||||
|
||||
Expect(Token::LBRACE, CHECK_OK);
|
||||
|
||||
const bool has_extends = extends != nullptr;
|
||||
while (peek() != Token::RBRACE) {
|
||||
if (Check(Token::SEMICOLON)) continue;
|
||||
FuncNameInferrer::State fni_state(fni_);
|
||||
bool is_computed_name = false; // Classes do not care about computed
|
||||
// property names here.
|
||||
ExpressionClassifier property_classifier(this);
|
||||
ClassLiteral::Property* property =
|
||||
ParseClassPropertyDefinition(&checker, has_extends, &is_computed_name,
|
||||
&has_seen_constructor, CHECK_OK);
|
||||
RewriteNonPattern(CHECK_OK);
|
||||
impl()->AccumulateFormalParameterContainmentErrors();
|
||||
|
||||
if (has_seen_constructor && constructor == nullptr) {
|
||||
constructor = GetPropertyValue(property)->AsFunctionLiteral();
|
||||
DCHECK_NOT_NULL(constructor);
|
||||
constructor->set_raw_name(
|
||||
name != nullptr ? name : ast_value_factory()->empty_string());
|
||||
} else {
|
||||
if (property->kind() == ClassLiteralProperty::FIELD) {
|
||||
DCHECK(allow_harmony_class_fields());
|
||||
if (property->is_static()) {
|
||||
if (static_initializer_var == nullptr) {
|
||||
static_initializer_var =
|
||||
NewTemporary(ast_value_factory()->empty_string());
|
||||
}
|
||||
// TODO(bakkot) only do this conditionally
|
||||
Expression* function = InstallHomeObject(
|
||||
property->value(),
|
||||
factory()->NewVariableProxy(static_initializer_var));
|
||||
ZoneList<Expression*>* args =
|
||||
new (zone()) ZoneList<Expression*>(2, zone());
|
||||
args->Add(function, zone());
|
||||
args->Add(factory()->NewVariableProxy(static_initializer_var),
|
||||
zone());
|
||||
Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall,
|
||||
args, kNoSourcePosition);
|
||||
property->set_value(call);
|
||||
} else {
|
||||
// if (is_computed_name) { // TODO(bakkot) figure out why this is
|
||||
// necessary for non-computed names in full-codegen
|
||||
ZoneList<Expression*>* to_name_args =
|
||||
new (zone()) ZoneList<Expression*>(1, zone());
|
||||
to_name_args->Add(property->key(), zone());
|
||||
property->set_key(factory()->NewCallRuntime(
|
||||
Runtime::kToName, to_name_args, kNoSourcePosition));
|
||||
//}
|
||||
const AstRawString* name = ClassFieldVariableName(
|
||||
true, ast_value_factory(), instance_field_initializers->length());
|
||||
VariableProxy* name_proxy =
|
||||
factory()->NewVariableProxy(name, NORMAL_VARIABLE);
|
||||
Declaration* name_declaration = factory()->NewVariableDeclaration(
|
||||
name_proxy, scope(), kNoSourcePosition);
|
||||
Variable* name_var =
|
||||
Declare(name_declaration, DeclarationDescriptor::NORMAL, CONST,
|
||||
kNeedsInitialization, ok, scope());
|
||||
DCHECK(ok);
|
||||
if (!ok) return nullptr;
|
||||
instance_field_initializers->Add(property->value(), zone());
|
||||
property->set_value(factory()->NewVariableProxy(name_var));
|
||||
}
|
||||
}
|
||||
properties->Add(property, zone());
|
||||
}
|
||||
|
||||
DCHECK_NOT_NULL(fni_);
|
||||
fni_->Infer();
|
||||
}
|
||||
|
||||
Expect(Token::RBRACE, CHECK_OK);
|
||||
int end_pos = scanner()->location().end_pos;
|
||||
|
||||
bool has_instance_fields = instance_field_initializers->length() > 0;
|
||||
bool has_extends = class_info->extends != nullptr;
|
||||
bool has_instance_fields =
|
||||
class_info->instance_field_initializers->length() > 0;
|
||||
DCHECK(!has_instance_fields || allow_harmony_class_fields());
|
||||
bool has_default_constructor = constructor == nullptr;
|
||||
bool has_default_constructor = class_info->constructor == nullptr;
|
||||
if (has_default_constructor) {
|
||||
constructor = DefaultConstructor(name, has_extends, has_instance_fields,
|
||||
pos, end_pos, block_state.language_mode());
|
||||
class_info->constructor =
|
||||
DefaultConstructor(name, has_extends, has_instance_fields, pos, end_pos,
|
||||
scope()->language_mode());
|
||||
}
|
||||
|
||||
if (has_instance_fields && extends == nullptr) {
|
||||
constructor = InsertClassFieldInitializer(constructor);
|
||||
constructor->set_requires_class_field_init(true);
|
||||
if (has_instance_fields && !has_extends) {
|
||||
class_info->constructor =
|
||||
InsertClassFieldInitializer(class_info->constructor);
|
||||
class_info->constructor->set_requires_class_field_init(true);
|
||||
} // The derived case is handled by rewriting super calls.
|
||||
|
||||
block_state.set_end_position(end_pos);
|
||||
scope()->set_end_position(end_pos);
|
||||
|
||||
if (name != nullptr) {
|
||||
DCHECK_NOT_NULL(proxy);
|
||||
proxy->var()->set_initializer_position(end_pos);
|
||||
DCHECK_NOT_NULL(class_info->proxy);
|
||||
class_info->proxy->var()->set_initializer_position(end_pos);
|
||||
}
|
||||
|
||||
ClassLiteral* class_literal = factory()->NewClassLiteral(
|
||||
proxy, extends, constructor, properties, pos, end_pos);
|
||||
class_info->proxy, class_info->extends, class_info->constructor,
|
||||
class_info->properties, pos, end_pos);
|
||||
|
||||
if (static_initializer_var != nullptr) {
|
||||
if (class_info->static_initializer_var != nullptr) {
|
||||
class_literal->set_static_initializer_proxy(
|
||||
factory()->NewVariableProxy(static_initializer_var));
|
||||
factory()->NewVariableProxy(class_info->static_initializer_var));
|
||||
}
|
||||
|
||||
do_block->statements()->Add(
|
||||
@ -3686,8 +3605,7 @@ Expression* Parser::ParseClassLiteral(const AstRawString* name,
|
||||
pos),
|
||||
zone());
|
||||
if (allow_harmony_class_fields() &&
|
||||
(has_instance_fields ||
|
||||
(extends != nullptr && !has_default_constructor))) {
|
||||
(has_instance_fields || (has_extends && !has_default_constructor))) {
|
||||
// Default constructors for derived classes without fields will not try to
|
||||
// read this variable, so there's no need to create it.
|
||||
const AstRawString* init_fn_name =
|
||||
@ -3697,7 +3615,7 @@ Expression* Parser::ParseClassLiteral(const AstRawString* name,
|
||||
Expression* initializer =
|
||||
has_instance_fields
|
||||
? static_cast<Expression*>(SynthesizeClassFieldInitializer(
|
||||
instance_field_initializers->length()))
|
||||
class_info->instance_field_initializers->length()))
|
||||
: factory()->NewBooleanLiteral(false, kNoSourcePosition);
|
||||
Assignment* assignment = factory()->NewAssignment(
|
||||
Token::INIT, factory()->NewVariableProxy(init_fn_var), initializer,
|
||||
@ -3706,7 +3624,7 @@ Expression* Parser::ParseClassLiteral(const AstRawString* name,
|
||||
factory()->NewExpressionStatement(assignment, kNoSourcePosition),
|
||||
zone());
|
||||
}
|
||||
for (int i = 0; i < instance_field_initializers->length(); ++i) {
|
||||
for (int i = 0; i < class_info->instance_field_initializers->length(); ++i) {
|
||||
const AstRawString* function_name =
|
||||
ClassFieldVariableName(false, ast_value_factory(), i);
|
||||
VariableProxy* function_proxy =
|
||||
@ -3716,15 +3634,14 @@ Expression* Parser::ParseClassLiteral(const AstRawString* name,
|
||||
Variable* function_var =
|
||||
Declare(function_declaration, DeclarationDescriptor::NORMAL, CONST,
|
||||
kNeedsInitialization, ok, scope());
|
||||
DCHECK(ok);
|
||||
if (!ok) return nullptr;
|
||||
if (!*ok) return nullptr;
|
||||
Property* prototype_property = factory()->NewProperty(
|
||||
factory()->NewVariableProxy(result_var),
|
||||
factory()->NewStringLiteral(ast_value_factory()->prototype_string(),
|
||||
kNoSourcePosition),
|
||||
kNoSourcePosition);
|
||||
Expression* function_value = InstallHomeObject(
|
||||
instance_field_initializers->at(i),
|
||||
class_info->instance_field_initializers->at(i),
|
||||
prototype_property); // TODO(bakkot) ideally this would be conditional,
|
||||
// especially in trivial cases
|
||||
Assignment* function_assignment = factory()->NewAssignment(
|
||||
@ -3734,13 +3651,12 @@ Expression* Parser::ParseClassLiteral(const AstRawString* name,
|
||||
function_assignment, kNoSourcePosition),
|
||||
zone());
|
||||
}
|
||||
do_block->set_scope(block_state.FinalizedBlockScope());
|
||||
do_expr->set_represented_function(constructor);
|
||||
do_block->set_scope(scope()->FinalizeBlockScope());
|
||||
do_expr->set_represented_function(class_info->constructor);
|
||||
|
||||
return do_expr;
|
||||
}
|
||||
|
||||
|
||||
Literal* Parser::GetLiteralUndefined(int position) {
|
||||
return factory()->NewUndefinedLiteral(position);
|
||||
}
|
||||
|
@ -152,7 +152,8 @@ struct ParserTypes<Parser> {
|
||||
typedef ObjectLiteral::Property* ObjectLiteralProperty;
|
||||
typedef ClassLiteral::Property* ClassLiteralProperty;
|
||||
typedef ZoneList<v8::internal::Expression*>* ExpressionList;
|
||||
typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
|
||||
typedef ZoneList<ObjectLiteral::Property*>* ObjectPropertyList;
|
||||
typedef ZoneList<ClassLiteral::Property*>* ClassPropertyList;
|
||||
typedef ParserFormalParameters FormalParameters;
|
||||
typedef v8::internal::Statement* Statement;
|
||||
typedef ZoneList<v8::internal::Statement*>* StatementList;
|
||||
@ -269,9 +270,6 @@ class Parser : public ParserBase<Parser> {
|
||||
};
|
||||
ZoneList<const NamedImport*>* ParseNamedImports(int pos, bool* ok);
|
||||
Statement* ParseFunctionDeclaration(bool* ok);
|
||||
Statement* ParseClassDeclaration(ZoneList<const AstRawString*>* names,
|
||||
bool default_export, bool* ok);
|
||||
Statement* ParseNativeDeclaration(bool* ok);
|
||||
Block* BuildInitializationBlock(DeclarationParsingResult* parsing_result,
|
||||
ZoneList<const AstRawString*>* names,
|
||||
bool* ok);
|
||||
@ -297,6 +295,21 @@ class Parser : public ParserBase<Parser> {
|
||||
FunctionLiteral* function, int pos,
|
||||
bool is_generator, bool is_async,
|
||||
ZoneList<const AstRawString*>* names, bool* ok);
|
||||
V8_INLINE Statement* DeclareClass(const AstRawString* variable_name,
|
||||
Expression* value,
|
||||
ZoneList<const AstRawString*>* names,
|
||||
int class_token_pos, int end_pos, bool* ok);
|
||||
V8_INLINE void DeclareClassVariable(const AstRawString* name,
|
||||
Scope* block_scope, ClassInfo* class_info,
|
||||
int class_token_pos, bool* ok);
|
||||
V8_INLINE void DeclareClassProperty(const AstRawString* class_name,
|
||||
ClassLiteralProperty* property,
|
||||
ClassInfo* class_info, bool* ok);
|
||||
V8_INLINE Expression* RewriteClassLiteral(const AstRawString* name,
|
||||
ClassInfo* class_info, int pos,
|
||||
bool* ok);
|
||||
V8_INLINE Statement* DeclareNative(const AstRawString* name, int pos,
|
||||
bool* ok);
|
||||
|
||||
Expression* ParseYieldStarExpression(bool* ok);
|
||||
|
||||
@ -419,11 +432,6 @@ class Parser : public ParserBase<Parser> {
|
||||
FunctionLiteral* SynthesizeClassFieldInitializer(int count);
|
||||
FunctionLiteral* InsertClassFieldInitializer(FunctionLiteral* constructor);
|
||||
|
||||
Expression* ParseClassLiteral(const AstRawString* name,
|
||||
Scanner::Location class_name_location,
|
||||
bool name_is_strict_reserved, int pos,
|
||||
bool* ok);
|
||||
|
||||
// Get odd-ball literals.
|
||||
Literal* GetLiteralUndefined(int position);
|
||||
|
||||
@ -739,10 +747,16 @@ class Parser : public ParserBase<Parser> {
|
||||
fni_->PushEnclosingName(name);
|
||||
}
|
||||
|
||||
V8_INLINE void InferFunctionName(FunctionLiteral* func_to_infer) {
|
||||
V8_INLINE void AddFunctionForNameInference(FunctionLiteral* func_to_infer) {
|
||||
DCHECK_NOT_NULL(fni_);
|
||||
fni_->AddFunction(func_to_infer);
|
||||
}
|
||||
|
||||
V8_INLINE void InferFunctionName() {
|
||||
DCHECK_NOT_NULL(fni_);
|
||||
fni_->Infer();
|
||||
}
|
||||
|
||||
// If we assign a function literal to a property we pretenure the
|
||||
// literal so it can be added as a constant function property.
|
||||
V8_INLINE static void CheckAssigningFunctionLiteralToProperty(
|
||||
@ -936,7 +950,7 @@ class Parser : public ParserBase<Parser> {
|
||||
V8_INLINE ZoneList<Expression*>* NewExpressionList(int size) const {
|
||||
return new (zone()) ZoneList<Expression*>(size, zone());
|
||||
}
|
||||
V8_INLINE ZoneList<ObjectLiteral::Property*>* NewPropertyList(
|
||||
V8_INLINE ZoneList<ObjectLiteral::Property*>* NewObjectPropertyList(
|
||||
int size) const {
|
||||
return new (zone()) ZoneList<ObjectLiteral::Property*>(size, zone());
|
||||
}
|
||||
|
@ -135,18 +135,6 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
|
||||
// That means that contextual checks (like a label being declared where
|
||||
// it is used) are generally omitted.
|
||||
|
||||
PreParser::Statement PreParser::ParseClassDeclaration(
|
||||
ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
|
||||
int pos = position();
|
||||
bool is_strict_reserved = false;
|
||||
Identifier name =
|
||||
ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
|
||||
ExpressionClassifier no_classifier(this);
|
||||
ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos,
|
||||
CHECK_OK);
|
||||
return Statement::Default();
|
||||
}
|
||||
|
||||
PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
|
||||
Consume(Token::FUNCTION);
|
||||
int pos = position();
|
||||
@ -251,57 +239,6 @@ PreParser::LazyParsingResult PreParser::ParseLazyFunctionLiteralBody(
|
||||
return kLazyParsingComplete;
|
||||
}
|
||||
|
||||
PreParserExpression PreParser::ParseClassLiteral(
|
||||
PreParserIdentifier name, Scanner::Location class_name_location,
|
||||
bool name_is_strict_reserved, int pos, bool* ok) {
|
||||
// All parts of a ClassDeclaration and ClassExpression are strict code.
|
||||
if (name_is_strict_reserved) {
|
||||
ReportMessageAt(class_name_location,
|
||||
MessageTemplate::kUnexpectedStrictReserved);
|
||||
*ok = false;
|
||||
return EmptyExpression();
|
||||
}
|
||||
if (IsEvalOrArguments(name)) {
|
||||
ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
|
||||
*ok = false;
|
||||
return EmptyExpression();
|
||||
}
|
||||
|
||||
LanguageMode class_language_mode = language_mode();
|
||||
BlockState block_state(zone(), &scope_state_);
|
||||
scope()->SetLanguageMode(
|
||||
static_cast<LanguageMode>(class_language_mode | STRICT));
|
||||
// TODO(marja): Make PreParser use scope names too.
|
||||
// this->scope()->SetScopeName(name);
|
||||
|
||||
bool has_extends = Check(Token::EXTENDS);
|
||||
if (has_extends) {
|
||||
ExpressionClassifier extends_classifier(this);
|
||||
ParseLeftHandSideExpression(CHECK_OK);
|
||||
ValidateExpression(CHECK_OK);
|
||||
impl()->AccumulateFormalParameterContainmentErrors();
|
||||
}
|
||||
|
||||
ClassLiteralChecker checker(this);
|
||||
bool has_seen_constructor = false;
|
||||
|
||||
Expect(Token::LBRACE, CHECK_OK);
|
||||
while (peek() != Token::RBRACE) {
|
||||
if (Check(Token::SEMICOLON)) continue;
|
||||
bool is_computed_name = false; // Classes do not care about computed
|
||||
// property names here.
|
||||
ExpressionClassifier property_classifier(this);
|
||||
ParseClassPropertyDefinition(&checker, has_extends, &is_computed_name,
|
||||
&has_seen_constructor, CHECK_OK);
|
||||
ValidateExpression(CHECK_OK);
|
||||
impl()->AccumulateFormalParameterContainmentErrors();
|
||||
}
|
||||
|
||||
Expect(Token::RBRACE, CHECK_OK);
|
||||
|
||||
return Expression::Default();
|
||||
}
|
||||
|
||||
PreParserExpression PreParser::ExpressionFromIdentifier(
|
||||
PreParserIdentifier name, int start_position, int end_position,
|
||||
InferName infer) {
|
||||
|
@ -728,7 +728,8 @@ struct ParserTypes<PreParser> {
|
||||
typedef PreParserExpression ObjectLiteralProperty;
|
||||
typedef PreParserExpression ClassLiteralProperty;
|
||||
typedef PreParserExpressionList ExpressionList;
|
||||
typedef PreParserExpressionList PropertyList;
|
||||
typedef PreParserExpressionList ObjectPropertyList;
|
||||
typedef PreParserExpressionList ClassPropertyList;
|
||||
typedef PreParserFormalParameters FormalParameters;
|
||||
typedef PreParserStatement Statement;
|
||||
typedef PreParserStatementList StatementList;
|
||||
@ -837,8 +838,6 @@ class PreParser : public ParserBase<PreParser> {
|
||||
// By making the 'exception handling' explicit, we are forced to check
|
||||
// for failure at the call sites.
|
||||
Statement ParseFunctionDeclaration(bool* ok);
|
||||
Statement ParseClassDeclaration(ZoneList<const AstRawString*>* names,
|
||||
bool default_export, bool* ok);
|
||||
Expression ParseConditionalExpression(bool accept_IN, bool* ok);
|
||||
Expression ParseObjectLiteral(bool* ok);
|
||||
|
||||
@ -860,11 +859,6 @@ class PreParser : public ParserBase<PreParser> {
|
||||
LanguageMode language_mode, bool* ok);
|
||||
LazyParsingResult ParseLazyFunctionLiteralBody(bool may_abort, bool* ok);
|
||||
|
||||
PreParserExpression ParseClassLiteral(PreParserIdentifier name,
|
||||
Scanner::Location class_name_location,
|
||||
bool name_is_strict_reserved, int pos,
|
||||
bool* ok);
|
||||
|
||||
struct TemplateLiteralState {};
|
||||
|
||||
V8_INLINE TemplateLiteralState OpenTemplateLiteral(int pos) {
|
||||
@ -946,11 +940,6 @@ class PreParser : public ParserBase<PreParser> {
|
||||
return labels;
|
||||
}
|
||||
|
||||
V8_INLINE PreParserStatement ParseNativeDeclaration(bool* ok) {
|
||||
UNREACHABLE();
|
||||
return PreParserStatement::Default();
|
||||
}
|
||||
|
||||
// TODO(nikolaos): The preparser currently does not keep track of labels.
|
||||
V8_INLINE bool ContainsLabel(ZoneList<const AstRawString*>* labels,
|
||||
PreParserIdentifier label) {
|
||||
@ -997,6 +986,29 @@ class PreParser : public ParserBase<PreParser> {
|
||||
return Statement::Default();
|
||||
}
|
||||
|
||||
V8_INLINE PreParserStatement
|
||||
DeclareClass(PreParserIdentifier variable_name, PreParserExpression value,
|
||||
ZoneList<const AstRawString*>* names, int class_token_pos,
|
||||
int end_pos, bool* ok) {
|
||||
return PreParserStatement::Default();
|
||||
}
|
||||
V8_INLINE void DeclareClassVariable(PreParserIdentifier name,
|
||||
Scope* block_scope, ClassInfo* class_info,
|
||||
int class_token_pos, bool* ok) {}
|
||||
V8_INLINE void DeclareClassProperty(PreParserIdentifier class_name,
|
||||
PreParserExpression property,
|
||||
ClassInfo* class_info, bool* ok) {}
|
||||
V8_INLINE PreParserExpression RewriteClassLiteral(PreParserIdentifier name,
|
||||
ClassInfo* class_info,
|
||||
int pos, bool* ok) {
|
||||
return PreParserExpression::Default();
|
||||
}
|
||||
|
||||
V8_INLINE PreParserStatement DeclareNative(PreParserIdentifier name, int pos,
|
||||
bool* ok) {
|
||||
return PreParserStatement::Default();
|
||||
}
|
||||
|
||||
V8_INLINE void QueueDestructuringAssignmentForRewriting(
|
||||
PreParserExpression assignment) {}
|
||||
V8_INLINE void QueueNonPatternForRewriting(PreParserExpression expr,
|
||||
@ -1103,7 +1115,9 @@ class PreParser : public ParserBase<PreParser> {
|
||||
V8_INLINE static void PushVariableName(PreParserIdentifier id) {}
|
||||
V8_INLINE void PushPropertyName(PreParserExpression expression) {}
|
||||
V8_INLINE void PushEnclosingName(PreParserIdentifier name) {}
|
||||
V8_INLINE static void InferFunctionName(PreParserExpression expression) {}
|
||||
V8_INLINE static void AddFunctionForNameInference(
|
||||
PreParserExpression expression) {}
|
||||
V8_INLINE static void InferFunctionName() {}
|
||||
|
||||
V8_INLINE static void CheckAssigningFunctionLiteralToProperty(
|
||||
PreParserExpression left, PreParserExpression right) {}
|
||||
@ -1318,7 +1332,11 @@ class PreParser : public ParserBase<PreParser> {
|
||||
return PreParserExpressionList();
|
||||
}
|
||||
|
||||
V8_INLINE PreParserExpressionList NewPropertyList(int size) const {
|
||||
V8_INLINE PreParserExpressionList NewObjectPropertyList(int size) const {
|
||||
return PreParserExpressionList();
|
||||
}
|
||||
|
||||
V8_INLINE PreParserExpressionList NewClassPropertyList(int size) const {
|
||||
return PreParserExpressionList();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user