Commit 6c2c17cd authored by nikolaos's avatar nikolaos Committed by Commit bot

[parser] Apply an adaptation of the CRTP

This patch applies an adaptation of the Curiously Recurring Template
Pattern to the parser objects.  The result is roughly:

    // Common denominator, needed to avoid cyclic dependency.
    // Instances of this template will end up with very minimal
    // definitions, ideally containing just typedefs.
    template <typename Impl>
    class ParserBaseTraits;

    // The parser base object, which should just implement pure
    // parser behavior.  The Impl parameter is the actual derived
    // class (according to CRTP), which implements impure parser
    // behavior.
    template <typename Impl>
    class ParserBase : public ParserBaseTraits<Impl> { ... };

    // And then, for each parser variant:
    class Parser;

    template <>
    class ParserBaseTraits<Parser> { ... };

    class Parser : public ParserBase<Parser> { ... };

Using the CRTP, we will ultimately achieve two goals:
(1) clean up the traits objects, but most importantly
(2) clearly separate pure/impure parser implementation and facilitate
experimentation with different parser variants.

R=adamk@chromium.org, marja@chromium.org
BUG=
LOG=N

Review-Url: https://codereview.chromium.org/2267663002
Cr-Commit-Position: refs/heads/master@{#38819}
parent 1776fd09
......@@ -135,9 +135,38 @@ struct FormalParametersBase {
// Used in functions where the return type is ExpressionT.
#define CHECK_OK CHECK_OK_CUSTOM(EmptyExpression)
// Common base class template shared between parser and pre-parser.
// The Impl parameter is the actual class of the parser/pre-parser,
// following the Curiously Recurring Template Pattern (CRTP).
// The structure of the parser objects is roughly the following:
//
// // Common denominator, needed to avoid cyclic dependency.
// // Instances of this template will end up with very minimal
// // definitions, ideally containing just typedefs.
// template <typename Impl>
// class ParserBaseTraits;
// // The parser base object, which should just implement pure
// // parser behavior. The Impl parameter is the actual derived
// // class (according to CRTP), which implements impure parser
// // behavior.
// template <typename Impl>
// class ParserBase : public ParserBaseTraits<Impl> { ... };
//
// // And then, for each parser variant (e.g., parser, preparser, etc):
// class Parser;
//
// template <>
// class ParserBaseTraits<Parser> { ... };
//
// class Parser : public ParserBase<Parser> { ... };
//
// TODO(nikolaos): Currently the traits objects contain many things
// that will be moved to the implementation objects or to the parser
// base. The following comments will have to change, when this happens.
// Common base class shared between parser and pre-parser. Traits encapsulate
// the differences between Parser and PreParser:
// The traits class template encapsulates the differences between
// parser/pre-parser implementations. In particular:
// - Return types: For example, Parser functions return Expression* and
// PreParser functions return PreParserExpression.
......@@ -155,33 +184,40 @@ struct FormalParametersBase {
// pretenured, and PreParser doesn't care.
// The traits are expected to contain the following typedefs:
// struct Traits {
// template <>
// class ParserBaseTraits<Impl> {
// // In particular...
// struct Type {
// // Used by FunctionState and BlockState.
// typedef Scope;
// typedef GeneratorVariable;
// typedef AstProperties;
// typedef ExpressionClassifier;
// // Return types for traversing functions.
// typedef Identifier;
// typedef Expression;
// typedef YieldExpression;
// typedef FunctionLiteral;
// typedef ClassLiteral;
// typedef ObjectLiteralProperty;
// typedef Literal;
// typedef ObjectLiteralProperty;
// typedef ExpressionList;
// typedef PropertyList;
// typedef FormalParameter;
// typedef FormalParameters;
// typedef StatementList;
// // For constructing objects returned by the traversing functions.
// typedef Factory;
// };
// // ...
// };
template <typename Traits>
class ParserBase : public Traits {
template <typename Impl>
class ParserBaseTraits;
template <typename Impl>
class ParserBase : public ParserBaseTraits<Impl> {
public:
// Shorten type names defined by Traits.
typedef ParserBaseTraits<Impl> Traits;
typedef typename Traits::Type::Expression ExpressionT;
typedef typename Traits::Type::Identifier IdentifierT;
typedef typename Traits::Type::FormalParameter FormalParameterT;
......@@ -192,11 +228,14 @@ class ParserBase : public Traits {
typedef typename Traits::Type::StatementList StatementListT;
typedef typename Traits::Type::ExpressionClassifier ExpressionClassifier;
// All implementation-specific methods must be called through this.
Impl* impl() { return static_cast<Impl*>(this); }
const Impl* impl() const { return static_cast<const Impl*>(this); }
ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
v8::Extension* extension, AstValueFactory* ast_value_factory,
ParserRecorder* log, typename Traits::Type::Parser this_object)
: Traits(this_object),
scope_state_(nullptr),
ParserRecorder* log)
: scope_state_(nullptr),
function_state_(nullptr),
extension_(extension),
fni_(nullptr),
......@@ -515,8 +554,7 @@ class ParserBase : public Traits {
// to this function. Filled in by constructor.
bool this_function_is_parenthesized_;
friend class ParserTraits;
friend class PreParserTraits;
friend class ParserBaseTraits<Impl>;
friend class Checkpoint;
};
......@@ -1275,8 +1313,8 @@ class ParserBase : public Traits {
friend class DiscardableZoneScope;
};
template <class Traits>
ParserBase<Traits>::FunctionState::FunctionState(
template <typename Impl>
ParserBase<Impl>::FunctionState::FunctionState(
FunctionState** function_state_stack, ScopeState** scope_stack,
Scope* scope, FunctionKind kind)
: ScopeState(scope_stack, scope),
......@@ -1301,14 +1339,13 @@ ParserBase<Traits>::FunctionState::FunctionState(
}
}
template <class Traits>
ParserBase<Traits>::FunctionState::~FunctionState() {
template <typename Impl>
ParserBase<Impl>::FunctionState::~FunctionState() {
*function_state_stack_ = outer_function_state_;
}
template <class Traits>
void ParserBase<Traits>::GetUnexpectedTokenMessage(
template <typename Impl>
void ParserBase<Impl>::GetUnexpectedTokenMessage(
Token::Value token, MessageTemplate::Template* message,
Scanner::Location* location, const char** arg,
MessageTemplate::Template default_) {
......@@ -1366,15 +1403,13 @@ void ParserBase<Traits>::GetUnexpectedTokenMessage(
}
}
template <class Traits>
void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
template <typename Impl>
void ParserBase<Impl>::ReportUnexpectedToken(Token::Value token) {
return ReportUnexpectedTokenAt(scanner_->location(), token);
}
template <class Traits>
void ParserBase<Traits>::ReportUnexpectedTokenAt(
template <typename Impl>
void ParserBase<Impl>::ReportUnexpectedTokenAt(
Scanner::Location source_location, Token::Value token,
MessageTemplate::Template message) {
const char* arg;
......@@ -1382,9 +1417,8 @@ void ParserBase<Traits>::ReportUnexpectedTokenAt(
Traits::ReportMessageAt(source_location, message, arg);
}
template <class Traits>
typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
template <typename Impl>
typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier(
AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
ExpressionClassifier classifier(this);
auto result =
......@@ -1398,11 +1432,10 @@ typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
return result;
}
template <class Traits>
typename ParserBase<Traits>::IdentifierT
ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::IdentifierT
ParserBase<Impl>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
bool* ok) {
Token::Value next = Next();
if (next == Token::IDENTIFIER || next == Token::ASYNC ||
(next == Token::AWAIT && !parsing_module_ && !is_async_function())) {
......@@ -1457,9 +1490,9 @@ ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
}
}
template <class Traits>
typename ParserBase<Traits>::IdentifierT
ParserBase<Traits>::ParseIdentifierOrStrictReservedWord(
template <class Impl>
typename ParserBase<Impl>::IdentifierT
ParserBase<Impl>::ParseIdentifierOrStrictReservedWord(
FunctionKind function_kind, bool* is_strict_reserved, bool* ok) {
Token::Value next = Next();
if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_ &&
......@@ -1479,9 +1512,9 @@ ParserBase<Traits>::ParseIdentifierOrStrictReservedWord(
return this->GetSymbol(scanner());
}
template <class Traits>
typename ParserBase<Traits>::IdentifierT
ParserBase<Traits>::ParseIdentifierName(bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifierName(
bool* ok) {
Token::Value next = Next();
if (next != Token::IDENTIFIER && next != Token::ASYNC &&
next != Token::ENUM && next != Token::AWAIT && next != Token::LET &&
......@@ -1497,8 +1530,8 @@ ParserBase<Traits>::ParseIdentifierName(bool* ok) {
return this->GetSymbol(scanner());
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral(
bool* ok) {
int pos = peek_position();
if (!scanner()->ScanRegExpPattern()) {
......@@ -1523,11 +1556,9 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
bool* is_async, bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression(
ExpressionClassifier* classifier, bool* is_async, bool* ok) {
// PrimaryExpression ::
// 'this'
// 'null'
......@@ -1704,9 +1735,8 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
return this->EmptyExpression();
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression(
bool accept_IN, bool* ok) {
ExpressionClassifier classifier(this);
ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK);
......@@ -1714,8 +1744,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
return result;
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression(
bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
// Expression ::
// AssignmentExpression
......@@ -1779,9 +1809,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
return result;
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral(
ExpressionClassifier* classifier, bool* ok) {
// ArrayLiteral ::
// '[' Expression? (',' Expression?)* ']'
......@@ -1856,8 +1885,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
return result;
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
template <class Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name,
ExpressionClassifier* classifier, bool* ok) {
Token::Value token = peek();
......@@ -1913,9 +1942,9 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
: factory()->NewStringLiteral(*name, pos);
}
template <class Traits>
typename ParserBase<Traits>::ObjectLiteralPropertyT
ParserBase<Traits>::ParsePropertyDefinition(
template <typename Impl>
typename ParserBase<Impl>::ObjectLiteralPropertyT
ParserBase<Impl>::ParsePropertyDefinition(
ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
MethodKind method_kind, bool* is_computed_name, bool* has_seen_constructor,
ExpressionClassifier* classifier, IdentifierT* name, bool* ok) {
......@@ -2131,9 +2160,8 @@ ParserBase<Traits>::ParsePropertyDefinition(
return this->EmptyObjectLiteralProperty();
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral(
ExpressionClassifier* classifier, bool* ok) {
// ObjectLiteral ::
// '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
......@@ -2188,10 +2216,11 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
pos);
}
template <class Traits>
typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
Scanner::Location* first_spread_arg_loc, bool maybe_arrow,
ExpressionClassifier* classifier, bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::Traits::Type::ExpressionList
ParserBase<Impl>::ParseArguments(Scanner::Location* first_spread_arg_loc,
bool maybe_arrow,
ExpressionClassifier* classifier, bool* ok) {
// Arguments ::
// '(' (AssignmentExpression)*[','] ')'
......@@ -2271,11 +2300,11 @@ typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
}
// Precedence = 2
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
ExpressionClassifier* classifier,
bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN,
ExpressionClassifier* classifier,
bool* ok) {
// AssignmentExpression ::
// ConditionalExpression
// ArrowFunction
......@@ -2289,7 +2318,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
}
FuncNameInferrer::State fni_state(fni_);
ParserBase<Traits>::Checkpoint checkpoint(this);
Checkpoint checkpoint(this);
ExpressionClassifier arrow_formals_classifier(this,
classifier->duplicate_finder());
......@@ -2478,11 +2507,9 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
return result;
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseYieldExpression(bool accept_IN,
ExpressionClassifier* classifier,
bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression(
bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
// YieldExpression ::
// 'yield' ([no line terminator] '*'? AssignmentExpression)?
int pos = peek_position();
......@@ -2531,10 +2558,10 @@ ParserBase<Traits>::ParseYieldExpression(bool accept_IN,
return yield;
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseTailCallExpression(ExpressionClassifier* classifier,
bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseTailCallExpression(ExpressionClassifier* classifier,
bool* ok) {
// TailCallExpression::
// 'continue' MemberExpression Arguments
// 'continue' CallExpression Arguments
......@@ -2594,11 +2621,11 @@ ParserBase<Traits>::ParseTailCallExpression(ExpressionClassifier* classifier,
}
// Precedence = 3
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
ExpressionClassifier* classifier,
bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseConditionalExpression(bool accept_IN,
ExpressionClassifier* classifier,
bool* ok) {
// ConditionalExpression ::
// LogicalOrExpression
// LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
......@@ -2627,11 +2654,9 @@ ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
// Precedence >= 4
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
ExpressionClassifier* classifier,
bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
int prec, bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
DCHECK(prec >= 4);
ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK);
for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
......@@ -2685,11 +2710,9 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
return x;
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression(
ExpressionClassifier* classifier, bool* ok) {
// UnaryExpression ::
// PostfixExpression
// 'delete' UnaryExpression
......@@ -2765,11 +2788,9 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
}
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression(
ExpressionClassifier* classifier, bool* ok) {
// PostfixExpression ::
// LeftHandSideExpression ('++' | '--')?
......@@ -2798,10 +2819,10 @@ ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
return expression;
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseLeftHandSideExpression(
ExpressionClassifier* classifier, bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseLeftHandSideExpression(ExpressionClassifier* classifier,
bool* ok) {
// LeftHandSideExpression ::
// (NewExpression | MemberExpression) ...
......@@ -2946,9 +2967,9 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
}
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseMemberWithNewPrefixesExpression(
ExpressionClassifier* classifier, bool* is_async, bool* ok) {
// NewExpression ::
// ('new')+ MemberExpression
......@@ -3011,10 +3032,9 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
return this->ParseMemberExpression(classifier, is_async, ok);
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
bool* is_async, bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberExpression(
ExpressionClassifier* classifier, bool* is_async, bool* ok) {
// MemberExpression ::
// (PrimaryExpression | FunctionLiteral | ClassLiteral)
// ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
......@@ -3080,9 +3100,9 @@ ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
return result;
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseSuperExpression(
bool is_new, bool* ok) {
Expect(Token::SUPER, CHECK_OK);
int pos = position();
......@@ -3108,10 +3128,10 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) {
return this->EmptyExpression();
}
template <class Traits>
void ParserBase<Traits>::ExpectMetaProperty(Vector<const char> property_name,
const char* full_name, int pos,
bool* ok) {
template <typename Impl>
void ParserBase<Impl>::ExpectMetaProperty(Vector<const char> property_name,
const char* full_name, int pos,
bool* ok) {
Consume(Token::PERIOD);
ExpectContextualKeyword(property_name, CHECK_OK_CUSTOM(Void));
if (scanner()->literal_contains_escapes()) {
......@@ -3122,9 +3142,9 @@ void ParserBase<Traits>::ExpectMetaProperty(Vector<const char> property_name,
}
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseNewTargetExpression(bool* ok) {
int pos = position();
ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK);
......@@ -3138,9 +3158,9 @@ ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
return this->NewTargetExpression(pos);
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseMemberExpressionContinuation(
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseMemberExpressionContinuation(
ExpressionT expression, bool* is_async, ExpressionClassifier* classifier,
bool* ok) {
// Parses this part of MemberExpression:
......@@ -3214,10 +3234,10 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
return this->EmptyExpression();
}
template <class Traits>
void ParserBase<Traits>::ParseFormalParameter(
FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
template <typename Impl>
void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters,
ExpressionClassifier* classifier,
bool* ok) {
// FormalParameter[Yield,GeneratorParameter] :
// BindingElement[?Yield, ?GeneratorParameter]
bool is_rest = parameters->has_rest;
......@@ -3250,9 +3270,8 @@ void ParserBase<Traits>::ParseFormalParameter(
scanner()->location().end_pos, is_rest);
}
template <class Traits>
void ParserBase<Traits>::ParseFormalParameterList(
template <typename Impl>
void ParserBase<Impl>::ParseFormalParameterList(
FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
// FormalParameters[Yield] :
// [empty]
......@@ -3302,12 +3321,12 @@ void ParserBase<Traits>::ParseFormalParameterList(
}
}
template <class Traits>
void ParserBase<Traits>::CheckArityRestrictions(int param_count,
FunctionKind function_kind,
bool has_rest,
int formals_start_pos,
int formals_end_pos, bool* ok) {
template <typename Impl>
void ParserBase<Impl>::CheckArityRestrictions(int param_count,
FunctionKind function_kind,
bool has_rest,
int formals_start_pos,
int formals_end_pos, bool* ok) {
if (IsGetterFunction(function_kind)) {
if (param_count != 0) {
ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
......@@ -3328,9 +3347,8 @@ void ParserBase<Traits>::CheckArityRestrictions(int param_count,
}
}
template <class Traits>
bool ParserBase<Traits>::IsNextLetKeyword() {
template <typename Impl>
bool ParserBase<Impl>::IsNextLetKeyword() {
DCHECK(peek() == Token::LET);
Token::Value next_next = PeekAhead();
switch (next_next) {
......@@ -3354,8 +3372,8 @@ bool ParserBase<Traits>::IsNextLetKeyword() {
}
}
template <class Traits>
bool ParserBase<Traits>::IsTrivialExpression() {
template <typename Impl>
bool ParserBase<Impl>::IsTrivialExpression() {
Token::Value peek_token = peek();
if (peek_token == Token::SMI || peek_token == Token::NUMBER ||
peek_token == Token::NULL_LITERAL || peek_token == Token::TRUE_LITERAL ||
......@@ -3372,9 +3390,9 @@ bool ParserBase<Traits>::IsTrivialExpression() {
return false;
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseArrowFunctionLiteral(
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseArrowFunctionLiteral(
bool accept_IN, const FormalParametersT& formal_parameters, bool is_async,
const ExpressionClassifier& formals_classifier, bool* ok) {
if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
......@@ -3491,12 +3509,9 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
return function_literal;
}
template <typename Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
ExpressionClassifier* classifier,
bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
ExpressionT tag, int start, ExpressionClassifier* classifier, bool* ok) {
// A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
// text followed by a substitution expression), finalized by a single
// TEMPLATE_TAIL.
......@@ -3588,20 +3603,18 @@ ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
return Traits::CloseTemplateLiteral(&ts, start, tag);
}
template <typename Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::CheckAndRewriteReferenceExpression(
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::CheckAndRewriteReferenceExpression(
ExpressionT expression, int beg_pos, int end_pos,
MessageTemplate::Template message, bool* ok) {
return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos,
message, kReferenceError, ok);
}
template <typename Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::CheckAndRewriteReferenceExpression(
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::CheckAndRewriteReferenceExpression(
ExpressionT expression, int beg_pos, int end_pos,
MessageTemplate::Template message, ParseErrorType type, bool* ok) {
if (this->IsIdentifier(expression) && is_strict(language_mode()) &&
......@@ -3625,15 +3638,13 @@ ParserBase<Traits>::CheckAndRewriteReferenceExpression(
return this->EmptyExpression();
}
template <typename Traits>
bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) {
template <typename Impl>
bool ParserBase<Impl>::IsValidReferenceExpression(ExpressionT expression) {
return this->IsAssignableIdentifier(expression) || expression->IsProperty();
}
template <typename Traits>
void ParserBase<Traits>::CheckDestructuringElement(
template <typename Impl>
void ParserBase<Impl>::CheckDestructuringElement(
ExpressionT expression, ExpressionClassifier* classifier, int begin,
int end) {
if (!IsValidPattern(expression) && !expression->IsAssignment() &&
......@@ -3648,8 +3659,8 @@ void ParserBase<Traits>::CheckDestructuringElement(
#undef CHECK_OK
#undef CHECK_OK_CUSTOM
template <typename Traits>
void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
template <typename Impl>
void ParserBase<Impl>::ObjectLiteralChecker::CheckProperty(
Token::Value property, PropertyKind type, MethodKind method_type,
ExpressionClassifier* classifier, bool* ok) {
DCHECK(!IsStaticMethod(method_type));
......@@ -3667,8 +3678,8 @@ void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
}
}
template <typename Traits>
void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
template <typename Impl>
void ParserBase<Impl>::ClassLiteralChecker::CheckProperty(
Token::Value property, PropertyKind type, MethodKind method_type,
ExpressionClassifier* classifier, bool* ok) {
DCHECK(type == kMethodProperty || type == kAccessorProperty);
......
......@@ -297,75 +297,74 @@ class TargetScope BASE_EMBEDDED {
// ----------------------------------------------------------------------------
// Implementation of Parser
bool ParserTraits::IsEval(const AstRawString* identifier) const {
return identifier == parser_->ast_value_factory()->eval_string();
bool ParserBaseTraits<Parser>::IsEval(const AstRawString* identifier) const {
return identifier == delegate()->ast_value_factory()->eval_string();
}
bool ParserTraits::IsArguments(const AstRawString* identifier) const {
return identifier == parser_->ast_value_factory()->arguments_string();
bool ParserBaseTraits<Parser>::IsArguments(
const AstRawString* identifier) const {
return identifier == delegate()->ast_value_factory()->arguments_string();
}
bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
bool ParserBaseTraits<Parser>::IsEvalOrArguments(
const AstRawString* identifier) const {
return IsEval(identifier) || IsArguments(identifier);
}
bool ParserTraits::IsUndefined(const AstRawString* identifier) const {
return identifier == parser_->ast_value_factory()->undefined_string();
bool ParserBaseTraits<Parser>::IsUndefined(
const AstRawString* identifier) const {
return identifier == delegate()->ast_value_factory()->undefined_string();
}
bool ParserTraits::IsPrototype(const AstRawString* identifier) const {
return identifier == parser_->ast_value_factory()->prototype_string();
bool ParserBaseTraits<Parser>::IsPrototype(
const AstRawString* identifier) const {
return identifier == delegate()->ast_value_factory()->prototype_string();
}
bool ParserTraits::IsConstructor(const AstRawString* identifier) const {
return identifier == parser_->ast_value_factory()->constructor_string();
bool ParserBaseTraits<Parser>::IsConstructor(
const AstRawString* identifier) const {
return identifier == delegate()->ast_value_factory()->constructor_string();
}
bool ParserTraits::IsThisProperty(Expression* expression) {
bool ParserBaseTraits<Parser>::IsThisProperty(Expression* expression) {
DCHECK(expression != NULL);
Property* property = expression->AsProperty();
return property != NULL && property->obj()->IsVariableProxy() &&
property->obj()->AsVariableProxy()->is_this();
}
bool ParserTraits::IsIdentifier(Expression* expression) {
bool ParserBaseTraits<Parser>::IsIdentifier(Expression* expression) {
VariableProxy* operand = expression->AsVariableProxy();
return operand != NULL && !operand->is_this();
}
void ParserTraits::PushPropertyName(FuncNameInferrer* fni,
Expression* expression) {
void ParserBaseTraits<Parser>::PushPropertyName(FuncNameInferrer* fni,
Expression* expression) {
if (expression->IsPropertyName()) {
fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
} else {
fni->PushLiteralName(
parser_->ast_value_factory()->anonymous_function_string());
delegate()->ast_value_factory()->anonymous_function_string());
}
}
void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
Expression* right) {
void ParserBaseTraits<Parser>::CheckAssigningFunctionLiteralToProperty(
Expression* left, Expression* right) {
DCHECK(left != NULL);
if (left->IsProperty() && right->IsFunctionLiteral()) {
right->AsFunctionLiteral()->set_pretenure();
}
}
Expression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) {
Expression* ParserBaseTraits<Parser>::MarkExpressionAsAssigned(
Expression* expression) {
VariableProxy* proxy =
expression != NULL ? expression->AsVariableProxy() : NULL;
if (proxy != NULL) proxy->set_is_assigned();
return expression;
}
bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
bool ParserBaseTraits<Parser>::ShortcutNumericLiteralBinaryExpression(
Expression** x, Expression* y, Token::Value op, int pos,
AstNodeFactory* factory) {
if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
......@@ -435,10 +434,8 @@ bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
return false;
}
Expression* ParserTraits::BuildUnaryExpression(Expression* expression,
Token::Value op, int pos,
AstNodeFactory* factory) {
Expression* ParserBaseTraits<Parser>::BuildUnaryExpression(
Expression* expression, Token::Value op, int pos, AstNodeFactory* factory) {
DCHECK(expression != NULL);
if (expression->IsLiteral()) {
const AstValue* literal = expression->AsLiteral()->raw_value();
......@@ -480,10 +477,11 @@ Expression* ParserTraits::BuildUnaryExpression(Expression* expression,
return factory->NewUnaryOperation(op, expression, pos);
}
Expression* ParserTraits::BuildIteratorResult(Expression* value, bool done) {
Expression* ParserBaseTraits<Parser>::BuildIteratorResult(Expression* value,
bool done) {
int pos = kNoSourcePosition;
AstNodeFactory* factory = parser_->factory();
Zone* zone = parser_->zone();
AstNodeFactory* factory = delegate()->factory();
Zone* zone = delegate()->zone();
if (value == nullptr) value = factory->NewUndefinedLiteral(pos);
......@@ -495,24 +493,21 @@ Expression* ParserTraits::BuildIteratorResult(Expression* value, bool done) {
pos);
}
Expression* ParserTraits::NewThrowReferenceError(
Expression* ParserBaseTraits<Parser>::NewThrowReferenceError(
MessageTemplate::Template message, int pos) {
return parser_->NewThrowError(Runtime::kNewReferenceError, message,
parser_->ast_value_factory()->empty_string(),
pos);
return delegate()->NewThrowError(
Runtime::kNewReferenceError, message,
delegate()->ast_value_factory()->empty_string(), pos);
}
Expression* ParserTraits::NewThrowSyntaxError(MessageTemplate::Template message,
const AstRawString* arg,
int pos) {
return parser_->NewThrowError(Runtime::kNewSyntaxError, message, arg, pos);
Expression* ParserBaseTraits<Parser>::NewThrowSyntaxError(
MessageTemplate::Template message, const AstRawString* arg, int pos) {
return delegate()->NewThrowError(Runtime::kNewSyntaxError, message, arg, pos);
}
Expression* ParserTraits::NewThrowTypeError(MessageTemplate::Template message,
const AstRawString* arg, int pos) {
return parser_->NewThrowError(Runtime::kNewTypeError, message, arg, pos);
Expression* ParserBaseTraits<Parser>::NewThrowTypeError(
MessageTemplate::Template message, const AstRawString* arg, int pos) {
return delegate()->NewThrowError(Runtime::kNewTypeError, message, arg, pos);
}
Expression* Parser::NewThrowError(Runtime::FunctionId id,
......@@ -525,68 +520,66 @@ Expression* Parser::NewThrowError(Runtime::FunctionId id,
return factory()->NewThrow(call_constructor, pos);
}
void ParserTraits::ReportMessageAt(Scanner::Location source_location,
MessageTemplate::Template message,
const char* arg, ParseErrorType error_type) {
if (parser_->stack_overflow()) {
void ParserBaseTraits<Parser>::ReportMessageAt(
Scanner::Location source_location, MessageTemplate::Template message,
const char* arg, ParseErrorType error_type) {
if (delegate()->stack_overflow()) {
// Suppress the error message (syntax error or such) in the presence of a
// stack overflow. The isolate allows only one pending exception at at time
// and we want to report the stack overflow later.
return;
}
parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
source_location.end_pos,
message, arg, error_type);
delegate()->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
source_location.end_pos,
message, arg, error_type);
}
void ParserTraits::ReportMessageAt(Scanner::Location source_location,
MessageTemplate::Template message,
const AstRawString* arg,
ParseErrorType error_type) {
if (parser_->stack_overflow()) {
void ParserBaseTraits<Parser>::ReportMessageAt(
Scanner::Location source_location, MessageTemplate::Template message,
const AstRawString* arg, ParseErrorType error_type) {
if (delegate()->stack_overflow()) {
// Suppress the error message (syntax error or such) in the presence of a
// stack overflow. The isolate allows only one pending exception at at time
// and we want to report the stack overflow later.
return;
}
parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
source_location.end_pos,
message, arg, error_type);
delegate()->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
source_location.end_pos,
message, arg, error_type);
}
const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) const {
const AstRawString* ParserBaseTraits<Parser>::GetSymbol(
Scanner* scanner) const {
const AstRawString* result =
parser_->scanner()->CurrentSymbol(parser_->ast_value_factory());
delegate()->scanner()->CurrentSymbol(delegate()->ast_value_factory());
DCHECK(result != NULL);
return result;
}
const AstRawString* ParserTraits::GetNumberAsSymbol(Scanner* scanner) const {
double double_value = parser_->scanner()->DoubleValue();
const AstRawString* ParserBaseTraits<Parser>::GetNumberAsSymbol(
Scanner* scanner) const {
double double_value = delegate()->scanner()->DoubleValue();
char array[100];
const char* string = DoubleToCString(double_value, ArrayVector(array));
return parser_->ast_value_factory()->GetOneByteString(string);
return delegate()->ast_value_factory()->GetOneByteString(string);
}
const AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) const {
return parser_->scanner()->NextSymbol(parser_->ast_value_factory());
const AstRawString* ParserBaseTraits<Parser>::GetNextSymbol(
Scanner* scanner) const {
return delegate()->scanner()->NextSymbol(delegate()->ast_value_factory());
}
Expression* ParserTraits::ThisExpression(int pos) {
return parser_->NewUnresolved(parser_->ast_value_factory()->this_string(),
pos, pos + 4, Variable::THIS);
Expression* ParserBaseTraits<Parser>::ThisExpression(int pos) {
return delegate()->NewUnresolved(
delegate()->ast_value_factory()->this_string(), pos, pos + 4,
Variable::THIS);
}
Expression* ParserTraits::NewSuperPropertyReference(AstNodeFactory* factory,
int pos) {
Expression* ParserBaseTraits<Parser>::NewSuperPropertyReference(
AstNodeFactory* factory, int pos) {
// this_function[home_object_symbol]
VariableProxy* this_function_proxy = parser_->NewUnresolved(
parser_->ast_value_factory()->this_function_string(), pos);
VariableProxy* this_function_proxy = delegate()->NewUnresolved(
delegate()->ast_value_factory()->this_function_string(), pos);
Expression* home_object_symbol_literal =
factory->NewSymbolLiteral("home_object_symbol", kNoSourcePosition);
Expression* home_object = factory->NewProperty(
......@@ -595,42 +588,41 @@ Expression* ParserTraits::NewSuperPropertyReference(AstNodeFactory* factory,
ThisExpression(pos)->AsVariableProxy(), home_object, pos);
}
Expression* ParserTraits::NewSuperCallReference(AstNodeFactory* factory,
int pos) {
VariableProxy* new_target_proxy = parser_->NewUnresolved(
parser_->ast_value_factory()->new_target_string(), pos);
VariableProxy* this_function_proxy = parser_->NewUnresolved(
parser_->ast_value_factory()->this_function_string(), pos);
Expression* ParserBaseTraits<Parser>::NewSuperCallReference(
AstNodeFactory* factory, int pos) {
VariableProxy* new_target_proxy = delegate()->NewUnresolved(
delegate()->ast_value_factory()->new_target_string(), pos);
VariableProxy* this_function_proxy = delegate()->NewUnresolved(
delegate()->ast_value_factory()->this_function_string(), pos);
return factory->NewSuperCallReference(ThisExpression(pos)->AsVariableProxy(),
new_target_proxy, this_function_proxy,
pos);
}
Expression* ParserTraits::NewTargetExpression(int pos) {
Expression* ParserBaseTraits<Parser>::NewTargetExpression(int pos) {
static const int kNewTargetStringLength = 10;
auto proxy =
parser_->NewUnresolved(parser_->ast_value_factory()->new_target_string(),
pos, pos + kNewTargetStringLength);
auto proxy = delegate()->NewUnresolved(
delegate()->ast_value_factory()->new_target_string(), pos,
pos + kNewTargetStringLength);
proxy->set_is_new_target();
return proxy;
}
Expression* ParserTraits::FunctionSentExpression(AstNodeFactory* factory,
int pos) const {
Expression* ParserBaseTraits<Parser>::FunctionSentExpression(
AstNodeFactory* factory, int pos) const {
// We desugar function.sent into %_GeneratorGetInputOrDebugPos(generator).
Zone* zone = parser_->zone();
Zone* zone = delegate()->zone();
ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(1, zone);
VariableProxy* generator = factory->NewVariableProxy(
parser_->function_state_->generator_object_variable());
delegate()->function_state_->generator_object_variable());
args->Add(generator, zone);
return factory->NewCallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos,
args, pos);
}
Literal* ParserTraits::ExpressionFromLiteral(Token::Value token, int pos,
Scanner* scanner,
AstNodeFactory* factory) const {
Literal* ParserBaseTraits<Parser>::ExpressionFromLiteral(
Token::Value token, int pos, Scanner* scanner,
AstNodeFactory* factory) const {
switch (token) {
case Token::NULL_LITERAL:
return factory->NewNullLiteral(pos);
......@@ -653,78 +645,72 @@ Literal* ParserTraits::ExpressionFromLiteral(Token::Value token, int pos,
return NULL;
}
Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name,
int start_position,
int end_position,
InferName infer) {
if (infer == InferName::kYes && parser_->fni_ != NULL) {
parser_->fni_->PushVariableName(name);
Expression* ParserBaseTraits<Parser>::ExpressionFromIdentifier(
const AstRawString* name, int start_position, int end_position,
InferName infer) {
if (infer == InferName::kYes && delegate()->fni_ != NULL) {
delegate()->fni_->PushVariableName(name);
}
return parser_->NewUnresolved(name, start_position, end_position);
return delegate()->NewUnresolved(name, start_position, end_position);
}
Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner,
AstNodeFactory* factory) const {
Expression* ParserBaseTraits<Parser>::ExpressionFromString(
int pos, Scanner* scanner, AstNodeFactory* factory) const {
const AstRawString* symbol = GetSymbol(scanner);
if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
if (delegate()->fni_ != NULL) delegate()->fni_->PushLiteralName(symbol);
return factory->NewStringLiteral(symbol, pos);
}
Expression* ParserTraits::GetIterator(Expression* iterable,
AstNodeFactory* factory, int pos) {
Expression* ParserBaseTraits<Parser>::GetIterator(Expression* iterable,
AstNodeFactory* factory,
int pos) {
Expression* iterator_symbol_literal =
factory->NewSymbolLiteral("iterator_symbol", kNoSourcePosition);
Expression* prop =
factory->NewProperty(iterable, iterator_symbol_literal, pos);
Zone* zone = parser_->zone();
Zone* zone = delegate()->zone();
ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone);
return factory->NewCall(prop, args, pos);
}
Literal* ParserTraits::GetLiteralTheHole(int position,
AstNodeFactory* factory) const {
Literal* ParserBaseTraits<Parser>::GetLiteralTheHole(
int position, AstNodeFactory* factory) const {
return factory->NewTheHoleLiteral(kNoSourcePosition);
}
Expression* ParserTraits::ParseV8Intrinsic(bool* ok) {
return parser_->ParseV8Intrinsic(ok);
Expression* ParserBaseTraits<Parser>::ParseV8Intrinsic(bool* ok) {
return delegate()->ParseV8Intrinsic(ok);
}
FunctionLiteral* ParserTraits::ParseFunctionLiteral(
FunctionLiteral* ParserBaseTraits<Parser>::ParseFunctionLiteral(
const AstRawString* name, Scanner::Location function_name_location,
FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_position, FunctionLiteral::FunctionType type,
LanguageMode language_mode, bool* ok) {
return parser_->ParseFunctionLiteral(
return delegate()->ParseFunctionLiteral(
name, function_name_location, function_name_validity, kind,
function_token_position, type, language_mode, ok);
}
Expression* ParserTraits::ParseClassLiteral(
Expression* ParserBaseTraits<Parser>::ParseClassLiteral(
Type::ExpressionClassifier* classifier, const AstRawString* name,
Scanner::Location class_name_location, bool name_is_strict_reserved,
int pos, bool* ok) {
return parser_->ParseClassLiteral(classifier, name, class_name_location,
name_is_strict_reserved, pos, ok);
return delegate()->ParseClassLiteral(classifier, name, class_name_location,
name_is_strict_reserved, pos, ok);
}
void ParserTraits::MarkTailPosition(Expression* expression) {
void ParserBaseTraits<Parser>::MarkTailPosition(Expression* expression) {
expression->MarkTail();
}
void ParserTraits::MarkCollectedTailCallExpressions() {
parser_->MarkCollectedTailCallExpressions();
void ParserBaseTraits<Parser>::MarkCollectedTailCallExpressions() {
delegate()->MarkCollectedTailCallExpressions();
}
Parser::Parser(ParseInfo* info)
: ParserBase<ParserTraits>(info->zone(), &scanner_, info->stack_limit(),
info->extension(), info->ast_value_factory(),
NULL, this),
: ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
info->extension(), info->ast_value_factory(), NULL),
scanner_(info->unicode_cache()),
reusable_preparser_(NULL),
original_scope_(NULL),
......@@ -954,7 +940,7 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
}
if (ok) {
ParserTraits::RewriteDestructuringAssignments();
ParserBaseTraits<Parser>::RewriteDestructuringAssignments();
result = factory()->NewScriptOrEvalFunctionLiteral(
scope, body, function_state.materialized_literal_count(),
function_state.expected_property_count());
......@@ -2337,7 +2323,8 @@ Block* Parser::ParseVariableDeclarations(
}
}
ParserTraits::SetFunctionNameFromIdentifierRef(value, pattern);
ParserBaseTraits<Parser>::SetFunctionNameFromIdentifierRef(value,
pattern);
// End position of the initializer is after the assignment expression.
initializer_position = scanner()->location().end_pos;
......@@ -3997,12 +3984,12 @@ void Parser::ParseArrowFunctionFormalParameters(
AddFormalParameter(parameters, expr, initializer, end_pos, is_rest);
}
void ParserTraits::ParseAsyncArrowSingleExpressionBody(
void ParserBaseTraits<Parser>::ParseAsyncArrowSingleExpressionBody(
ZoneList<Statement*>* body, bool accept_IN,
Type::ExpressionClassifier* classifier, int pos, bool* ok) {
parser_->DesugarAsyncFunctionBody(
parser_->ast_value_factory()->empty_string(), parser_->scope(), body,
classifier, kAsyncArrowFunction,
delegate()->DesugarAsyncFunctionBody(
delegate()->ast_value_factory()->empty_string(), delegate()->scope(),
body, classifier, kAsyncArrowFunction,
Parser::FunctionBodyType::kSingleExpression, accept_IN, pos, ok);
}
......@@ -4043,7 +4030,7 @@ void Parser::DesugarAsyncFunctionBody(const AstRawString* function_name,
} else {
return_value =
ParseAssignmentExpression(accept_IN, classifier, CHECK_OK_VOID);
ParserTraits::RewriteNonPattern(classifier, CHECK_OK_VOID);
ParserBaseTraits<Parser>::RewriteNonPattern(classifier, CHECK_OK_VOID);
}
return_value = BuildPromiseResolve(return_value, return_value->position());
......@@ -4070,13 +4057,13 @@ DoExpression* Parser::ParseDoExpression(bool* ok) {
return expr;
}
void ParserTraits::ParseArrowFunctionFormalParameterList(
void ParserBaseTraits<Parser>::ParseArrowFunctionFormalParameterList(
ParserFormalParameters* parameters, Expression* expr,
const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
const Scope::Snapshot& scope_snapshot, bool* ok) {
if (expr->IsEmptyParentheses()) return;
parser_->ParseArrowFunctionFormalParameters(
delegate()->ParseArrowFunctionFormalParameters(
parameters, expr, params_loc.end_pos, CHECK_OK_VOID);
scope_snapshot.Reparent(parameters->scope);
......@@ -4087,7 +4074,7 @@ void ParserTraits::ParseArrowFunctionFormalParameterList(
return;
}
Type::ExpressionClassifier classifier(parser_);
Type::ExpressionClassifier classifier(delegate());
if (!parameters->is_simple) {
classifier.RecordNonSimpleParameter();
}
......@@ -4101,9 +4088,9 @@ void ParserTraits::ParseArrowFunctionFormalParameterList(
DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
}
void ParserTraits::ReindexLiterals(const ParserFormalParameters& parameters) {
if (parser_->function_state_->materialized_literal_count() > 0) {
void ParserBaseTraits<Parser>::ReindexLiterals(
const ParserFormalParameters& parameters) {
if (delegate()->function_state_->materialized_literal_count() > 0) {
AstLiteralReindexer reindexer;
for (const auto p : parameters.params) {
......@@ -4112,7 +4099,7 @@ void ParserTraits::ReindexLiterals(const ParserFormalParameters& parameters) {
}
DCHECK(reindexer.count() <=
parser_->function_state_->materialized_literal_count());
delegate()->function_state_->materialized_literal_count());
}
}
......@@ -4347,7 +4334,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
if (body) {
// If body can be inspected, rewrite queued destructuring assignments
ParserTraits::RewriteDestructuringAssignments();
ParserBaseTraits<Parser>::RewriteDestructuringAssignments();
}
has_duplicate_parameters =
!formals_classifier.is_valid_formal_parameter_list_without_duplicates();
......@@ -5369,9 +5356,9 @@ void Parser::ParseOnBackground(ParseInfo* info) {
}
}
ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
return new (zone()) ParserTraits::TemplateLiteral(zone(), pos);
ParserBaseTraits<Parser>::TemplateLiteralState Parser::OpenTemplateLiteral(
int pos) {
return new (zone()) ParserBaseTraits<Parser>::TemplateLiteral(zone(), pos);
}
......@@ -5636,9 +5623,9 @@ void Parser::MarkCollectedTailCallExpressions() {
}
}
Expression* ParserTraits::ExpressionListToExpression(
Expression* ParserBaseTraits<Parser>::ExpressionListToExpression(
ZoneList<Expression*>* args) {
AstNodeFactory* factory = parser_->factory();
AstNodeFactory* factory = delegate()->factory();
Expression* expr = args->at(0);
for (int i = 1; i < args->length(); ++i) {
expr = factory->NewBinaryOperation(Token::COMMA, expr, args->at(i),
......@@ -5647,40 +5634,40 @@ Expression* ParserTraits::ExpressionListToExpression(
return expr;
}
void ParserTraits::RewriteDestructuringAssignments() {
parser_->RewriteDestructuringAssignments();
void ParserBaseTraits<Parser>::RewriteDestructuringAssignments() {
delegate()->RewriteDestructuringAssignments();
}
Expression* ParserTraits::RewriteExponentiation(Expression* left,
Expression* right, int pos) {
return parser_->RewriteExponentiation(left, right, pos);
Expression* ParserBaseTraits<Parser>::RewriteExponentiation(Expression* left,
Expression* right,
int pos) {
return delegate()->RewriteExponentiation(left, right, pos);
}
Expression* ParserTraits::RewriteAssignExponentiation(Expression* left,
Expression* right,
int pos) {
return parser_->RewriteAssignExponentiation(left, right, pos);
Expression* ParserBaseTraits<Parser>::RewriteAssignExponentiation(
Expression* left, Expression* right, int pos) {
return delegate()->RewriteAssignExponentiation(left, right, pos);
}
void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier,
bool* ok) {
parser_->RewriteNonPattern(classifier, ok);
void ParserBaseTraits<Parser>::RewriteNonPattern(
Type::ExpressionClassifier* classifier, bool* ok) {
delegate()->RewriteNonPattern(classifier, ok);
}
Expression* ParserTraits::RewriteAwaitExpression(Expression* value,
int await_pos) {
Expression* ParserBaseTraits<Parser>::RewriteAwaitExpression(Expression* value,
int await_pos) {
// yield %AsyncFunctionAwait(.generator_object, <operand>)
Variable* generator_object_variable =
parser_->function_state_->generator_object_variable();
delegate()->function_state_->generator_object_variable();
// If generator_object_variable is null,
if (!generator_object_variable) return value;
auto factory = parser_->factory();
auto factory = delegate()->factory();
const int nopos = kNoSourcePosition;
Variable* temp_var =
parser_->NewTemporary(parser_->ast_value_factory()->empty_string());
delegate()->NewTemporary(delegate()->ast_value_factory()->empty_string());
VariableProxy* temp_proxy = factory->NewVariableProxy(temp_var);
Block* do_block = factory->NewBlock(nullptr, 2, false, nopos);
......@@ -5697,7 +5684,7 @@ Expression* ParserTraits::RewriteAwaitExpression(Expression* value,
factory->NewVariableProxy(generator_object_variable);
async_function_await_args->Add(generator_object, zone());
async_function_await_args->Add(temp_proxy, zone());
Expression* async_function_await = parser_->factory()->NewCallRuntime(
Expression* async_function_await = delegate()->factory()->NewCallRuntime(
Context::ASYNC_FUNCTION_AWAIT_INDEX, async_function_await_args, nopos);
// Wrap await to provide a break location between value evaluation and yield.
Expression* await_assignment = factory->NewAssignment(
......@@ -5711,17 +5698,16 @@ Expression* ParserTraits::RewriteAwaitExpression(Expression* value,
Yield::kOnExceptionRethrow);
}
ZoneList<Expression*>* ParserTraits::GetNonPatternList() const {
return parser_->function_state_->non_patterns_to_rewrite();
ZoneList<Expression*>* ParserBaseTraits<Parser>::GetNonPatternList() const {
return delegate()->function_state_->non_patterns_to_rewrite();
}
ZoneList<typename ParserTraits::Type::ExpressionClassifier::Error>*
ParserTraits::GetReportedErrorList() const {
return parser_->function_state_->GetReportedErrorList();
ZoneList<typename ParserBaseTraits<Parser>::Type::ExpressionClassifier::Error>*
ParserBaseTraits<Parser>::GetReportedErrorList() const {
return delegate()->function_state_->GetReportedErrorList();
}
Zone* ParserTraits::zone() const { return parser_->zone(); }
Zone* ParserBaseTraits<Parser>::zone() const { return delegate()->zone(); }
class NonPatternRewriter : public AstExpressionRewriter {
public:
......@@ -5921,21 +5907,20 @@ Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
return factory()->NewDoExpression(do_block, result, lit->position());
}
void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) {
void ParserBaseTraits<Parser>::QueueDestructuringAssignmentForRewriting(
Expression* expr) {
DCHECK(expr->IsRewritableExpression());
parser_->function_state_->AddDestructuringAssignment(
Parser::DestructuringAssignment(expr, parser_->scope()));
delegate()->function_state_->AddDestructuringAssignment(
Parser::DestructuringAssignment(expr, delegate()->scope()));
}
void ParserTraits::QueueNonPatternForRewriting(Expression* expr, bool* ok) {
void ParserBaseTraits<Parser>::QueueNonPatternForRewriting(Expression* expr,
bool* ok) {
DCHECK(expr->IsRewritableExpression());
parser_->function_state_->AddNonPatternForRewriting(expr, ok);
delegate()->function_state_->AddNonPatternForRewriting(expr, ok);
}
void ParserTraits::SetFunctionNameFromPropertyName(
void ParserBaseTraits<Parser>::SetFunctionNameFromPropertyName(
ObjectLiteralProperty* property, const AstRawString* name) {
Expression* value = property->value();
......@@ -5951,10 +5936,10 @@ void ParserTraits::SetFunctionNameFromPropertyName(
if (is_getter || is_setter) {
DCHECK_NOT_NULL(name);
const AstRawString* prefix =
is_getter ? parser_->ast_value_factory()->get_space_string()
: parser_->ast_value_factory()->set_space_string();
is_getter ? delegate()->ast_value_factory()->get_space_string()
: delegate()->ast_value_factory()->set_space_string();
function->set_raw_name(
parser_->ast_value_factory()->NewConsString(prefix, name));
delegate()->ast_value_factory()->NewConsString(prefix, name));
return;
}
}
......@@ -5965,14 +5950,13 @@ void ParserTraits::SetFunctionNameFromPropertyName(
DCHECK(!value->IsAnonymousFunctionDefinition() ||
property->kind() == ObjectLiteralProperty::COMPUTED);
parser_->SetFunctionName(value, name);
delegate()->SetFunctionName(value, name);
}
void ParserTraits::SetFunctionNameFromIdentifierRef(Expression* value,
Expression* identifier) {
void ParserBaseTraits<Parser>::SetFunctionNameFromIdentifierRef(
Expression* value, Expression* identifier) {
if (!identifier->IsVariableProxy()) return;
parser_->SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
delegate()->SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
}
void Parser::SetFunctionName(Expression* value, const AstRawString* name) {
......
......@@ -137,14 +137,12 @@ struct ParserFormalParameters : FormalParametersBase {
const Parameter& at(int i) const { return params[i]; }
};
class ParserTraits {
template <>
class ParserBaseTraits<Parser> {
public:
struct Type {
// TODO(marja): To be removed. The Traits object should contain all the data
// it needs.
typedef v8::internal::Parser* Parser;
typedef ParserBaseTraits<Parser> ParserTraits;
struct Type {
typedef Variable GeneratorVariable;
typedef v8::internal::AstProperties AstProperties;
......@@ -170,7 +168,12 @@ class ParserTraits {
typedef AstNodeFactory Factory;
};
explicit ParserTraits(Parser* parser) : parser_(parser) {}
// TODO(nikolaos): The traits methods should not need to call methods
// of the implementation object.
Parser* delegate() { return reinterpret_cast<Parser*>(this); }
const Parser* delegate() const {
return reinterpret_cast<const Parser*>(this);
}
// Helper functions for recursive descent.
bool IsEval(const AstRawString* identifier) const;
......@@ -468,13 +471,9 @@ class ParserTraits {
V8_INLINE Expression* RewriteYieldStar(Expression* generator,
Expression* expression, int pos);
private:
Parser* parser_;
};
class Parser : public ParserBase<ParserTraits> {
class Parser : public ParserBase<Parser> {
public:
explicit Parser(ParseInfo* info);
~Parser() {
......@@ -500,7 +499,9 @@ class Parser : public ParserBase<ParserTraits> {
void HandleSourceURLComments(Isolate* isolate, Handle<Script> script);
private:
friend class ParserTraits;
// TODO(nikolaos): This should not be necessary. It will be removed
// when the traits object stops delegating to the implementation object.
friend class ParserBaseTraits<Parser>;
// Runtime encoding of different completion modes.
enum CompletionKind {
......@@ -962,34 +963,32 @@ class Parser : public ParserBase<ParserTraits> {
#endif // DEBUG
};
bool ParserTraits::IsFutureStrictReserved(
bool ParserBaseTraits<Parser>::IsFutureStrictReserved(
const AstRawString* identifier) const {
return parser_->scanner()->IdentifierIsFutureStrictReserved(identifier);
return delegate()->scanner()->IdentifierIsFutureStrictReserved(identifier);
}
const AstRawString* ParserTraits::EmptyIdentifierString() const {
return parser_->ast_value_factory()->empty_string();
const AstRawString* ParserBaseTraits<Parser>::EmptyIdentifierString() const {
return delegate()->ast_value_factory()->empty_string();
}
void ParserTraits::SkipLazyFunctionBody(int* materialized_literal_count,
int* expected_property_count, bool* ok,
Scanner::BookmarkScope* bookmark) {
return parser_->SkipLazyFunctionBody(materialized_literal_count,
expected_property_count, ok, bookmark);
void ParserBaseTraits<Parser>::SkipLazyFunctionBody(
int* materialized_literal_count, int* expected_property_count, bool* ok,
Scanner::BookmarkScope* bookmark) {
return delegate()->SkipLazyFunctionBody(
materialized_literal_count, expected_property_count, ok, bookmark);
}
ZoneList<Statement*>* ParserTraits::ParseEagerFunctionBody(
ZoneList<Statement*>* ParserBaseTraits<Parser>::ParseEagerFunctionBody(
const AstRawString* name, int pos, const ParserFormalParameters& parameters,
FunctionKind kind, FunctionLiteral::FunctionType function_type, bool* ok) {
return parser_->ParseEagerFunctionBody(name, pos, parameters, kind,
function_type, ok);
return delegate()->ParseEagerFunctionBody(name, pos, parameters, kind,
function_type, ok);
}
void ParserTraits::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
parser_->CheckConflictingVarDeclarations(scope, ok);
void ParserBaseTraits<Parser>::CheckConflictingVarDeclarations(Scope* scope,
bool* ok) {
delegate()->CheckConflictingVarDeclarations(scope, ok);
}
......@@ -1021,80 +1020,71 @@ class CompileTimeValue: public AllStatic {
DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
};
ParserTraits::TemplateLiteralState ParserTraits::OpenTemplateLiteral(int pos) {
return parser_->OpenTemplateLiteral(pos);
ParserBaseTraits<Parser>::TemplateLiteralState
ParserBaseTraits<Parser>::OpenTemplateLiteral(int pos) {
return delegate()->OpenTemplateLiteral(pos);
}
void ParserTraits::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
parser_->AddTemplateSpan(state, tail);
void ParserBaseTraits<Parser>::AddTemplateSpan(TemplateLiteralState* state,
bool tail) {
delegate()->AddTemplateSpan(state, tail);
}
void ParserTraits::AddTemplateExpression(TemplateLiteralState* state,
Expression* expression) {
parser_->AddTemplateExpression(state, expression);
void ParserBaseTraits<Parser>::AddTemplateExpression(
TemplateLiteralState* state, Expression* expression) {
delegate()->AddTemplateExpression(state, expression);
}
Expression* ParserTraits::CloseTemplateLiteral(TemplateLiteralState* state,
int start, Expression* tag) {
return parser_->CloseTemplateLiteral(state, start, tag);
Expression* ParserBaseTraits<Parser>::CloseTemplateLiteral(
TemplateLiteralState* state, int start, Expression* tag) {
return delegate()->CloseTemplateLiteral(state, start, tag);
}
ZoneList<v8::internal::Expression*>* ParserTraits::PrepareSpreadArguments(
ZoneList<v8::internal::Expression*>* list) {
return parser_->PrepareSpreadArguments(list);
ZoneList<v8::internal::Expression*>* ParserBaseTraits<
Parser>::PrepareSpreadArguments(ZoneList<v8::internal::Expression*>* list) {
return delegate()->PrepareSpreadArguments(list);
}
Expression* ParserTraits::SpreadCall(Expression* function,
ZoneList<v8::internal::Expression*>* args,
int pos) {
return parser_->SpreadCall(function, args, pos);
Expression* ParserBaseTraits<Parser>::SpreadCall(
Expression* function, ZoneList<v8::internal::Expression*>* args, int pos) {
return delegate()->SpreadCall(function, args, pos);
}
Expression* ParserTraits::SpreadCallNew(
Expression* ParserBaseTraits<Parser>::SpreadCallNew(
Expression* function, ZoneList<v8::internal::Expression*>* args, int pos) {
return parser_->SpreadCallNew(function, args, pos);
return delegate()->SpreadCallNew(function, args, pos);
}
void ParserTraits::AddFormalParameter(ParserFormalParameters* parameters,
Expression* pattern,
Expression* initializer,
int initializer_end_position,
bool is_rest) {
void ParserBaseTraits<Parser>::AddFormalParameter(
ParserFormalParameters* parameters, Expression* pattern,
Expression* initializer, int initializer_end_position, bool is_rest) {
bool is_simple = pattern->IsVariableProxy() && initializer == nullptr;
const AstRawString* name = is_simple
? pattern->AsVariableProxy()->raw_name()
: parser_->ast_value_factory()->empty_string();
const AstRawString* name =
is_simple ? pattern->AsVariableProxy()->raw_name()
: delegate()->ast_value_factory()->empty_string();
parameters->params.Add(
ParserFormalParameters::Parameter(name, pattern, initializer,
initializer_end_position, is_rest),
parameters->scope->zone());
}
void ParserTraits::DeclareFormalParameter(
void ParserBaseTraits<Parser>::DeclareFormalParameter(
DeclarationScope* scope, const ParserFormalParameters::Parameter& parameter,
Type::ExpressionClassifier* classifier) {
bool is_duplicate = false;
bool is_simple = classifier->is_simple_parameter_list();
auto name = is_simple || parameter.is_rest
? parameter.name
: parser_->ast_value_factory()->empty_string();
: delegate()->ast_value_factory()->empty_string();
auto mode = is_simple || parameter.is_rest ? VAR : TEMPORARY;
if (!is_simple) scope->SetHasNonSimpleParameters();
bool is_optional = parameter.initializer != nullptr;
Variable* var =
scope->DeclareParameter(name, mode, is_optional, parameter.is_rest,
&is_duplicate, parser_->ast_value_factory());
&is_duplicate, delegate()->ast_value_factory());
if (is_duplicate) {
classifier->RecordDuplicateFormalParameterError(
parser_->scanner()->location());
delegate()->scanner()->location());
}
if (is_sloppy(scope->language_mode())) {
// TODO(sigurds) Mark every parameter as maybe assigned. This is a
......@@ -1104,35 +1094,36 @@ void ParserTraits::DeclareFormalParameter(
}
}
void ParserTraits::AddParameterInitializationBlock(
void ParserBaseTraits<Parser>::AddParameterInitializationBlock(
const ParserFormalParameters& parameters,
ZoneList<v8::internal::Statement*>* body, bool is_async, bool* ok) {
if (!parameters.is_simple) {
auto* init_block =
parser_->BuildParameterInitializationBlock(parameters, ok);
delegate()->BuildParameterInitializationBlock(parameters, ok);
if (!*ok) return;
if (is_async) {
init_block = parser_->BuildRejectPromiseOnException(init_block);
init_block = delegate()->BuildRejectPromiseOnException(init_block);
}
if (init_block != nullptr) {
body->Add(init_block, parser_->zone());
body->Add(init_block, delegate()->zone());
}
}
}
Expression* ParserTraits::ParseAsyncFunctionExpression(bool* ok) {
return parser_->ParseAsyncFunctionExpression(ok);
Expression* ParserBaseTraits<Parser>::ParseAsyncFunctionExpression(bool* ok) {
return delegate()->ParseAsyncFunctionExpression(ok);
}
DoExpression* ParserTraits::ParseDoExpression(bool* ok) {
return parser_->ParseDoExpression(ok);
DoExpression* ParserBaseTraits<Parser>::ParseDoExpression(bool* ok) {
return delegate()->ParseDoExpression(ok);
}
Expression* ParserTraits::RewriteYieldStar(Expression* generator,
Expression* iterable, int pos) {
return parser_->RewriteYieldStar(generator, iterable, pos);
Expression* ParserBaseTraits<Parser>::RewriteYieldStar(Expression* generator,
Expression* iterable,
int pos) {
return delegate()->RewriteYieldStar(generator, iterable, pos);
}
} // namespace internal
......
......@@ -41,24 +41,21 @@ namespace internal {
#define DUMMY ) // to make indentation work
#undef DUMMY
void PreParserTraits::ReportMessageAt(Scanner::Location source_location,
MessageTemplate::Template message,
const char* arg,
ParseErrorType error_type) {
pre_parser_->log_->LogMessage(source_location.beg_pos,
source_location.end_pos, message, arg,
error_type);
void ParserBaseTraits<PreParser>::ReportMessageAt(
Scanner::Location source_location, MessageTemplate::Template message,
const char* arg, ParseErrorType error_type) {
delegate()->log_->LogMessage(source_location.beg_pos, source_location.end_pos,
message, arg, error_type);
}
void PreParserTraits::ReportMessageAt(Scanner::Location source_location,
MessageTemplate::Template message,
const AstRawString* arg,
ParseErrorType error_type) {
void ParserBaseTraits<PreParser>::ReportMessageAt(
Scanner::Location source_location, MessageTemplate::Template message,
const AstRawString* arg, ParseErrorType error_type) {
UNREACHABLE();
}
PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) const {
PreParserIdentifier ParserBaseTraits<PreParser>::GetSymbol(
Scanner* scanner) const {
switch (scanner->current_token()) {
case Token::ENUM:
return PreParserIdentifier::Enum();
......@@ -89,8 +86,7 @@ PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) const {
}
}
PreParserExpression PreParserTraits::ExpressionFromString(
PreParserExpression ParserBaseTraits<PreParser>::ExpressionFromString(
int pos, Scanner* scanner, PreParserFactory* factory) const {
if (scanner->UnescapedLiteralMatches("use strict", 10)) {
return PreParserExpression::UseStrictStringLiteral();
......@@ -98,18 +94,16 @@ PreParserExpression PreParserTraits::ExpressionFromString(
return PreParserExpression::StringLiteral();
}
PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) {
return pre_parser_->ParseV8Intrinsic(ok);
PreParserExpression ParserBaseTraits<PreParser>::ParseV8Intrinsic(bool* ok) {
return delegate()->ParseV8Intrinsic(ok);
}
PreParserExpression PreParserTraits::ParseFunctionLiteral(
PreParserExpression ParserBaseTraits<PreParser>::ParseFunctionLiteral(
PreParserIdentifier name, Scanner::Location function_name_location,
FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_position, FunctionLiteral::FunctionType type,
LanguageMode language_mode, bool* ok) {
return pre_parser_->ParseFunctionLiteral(
return delegate()->ParseFunctionLiteral(
name, function_name_location, function_name_validity, kind,
function_token_position, type, language_mode, ok);
}
......@@ -154,12 +148,12 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
return kPreParseSuccess;
}
PreParserExpression PreParserTraits::ParseClassLiteral(
PreParserExpression ParserBaseTraits<PreParser>::ParseClassLiteral(
Type::ExpressionClassifier* classifier, PreParserIdentifier name,
Scanner::Location class_name_location, bool name_is_strict_reserved,
int pos, bool* ok) {
return pre_parser_->ParseClassLiteral(classifier, name, class_name_location,
name_is_strict_reserved, pos, ok);
return delegate()->ParseClassLiteral(classifier, name, class_name_location,
name_is_strict_reserved, pos, ok);
}
......@@ -1280,13 +1274,13 @@ PreParserExpression PreParser::ParseDoExpression(bool* ok) {
return PreParserExpression::Default();
}
void PreParserTraits::ParseAsyncArrowSingleExpressionBody(
void ParserBaseTraits<PreParser>::ParseAsyncArrowSingleExpressionBody(
PreParserStatementList body, bool accept_IN,
Type::ExpressionClassifier* classifier, int pos, bool* ok) {
Scope* scope = pre_parser_->scope();
Scope* scope = delegate()->scope();
scope->ForceContextAllocation();
PreParserExpression return_value = pre_parser_->ParseAssignmentExpression(
PreParserExpression return_value = delegate()->ParseAssignmentExpression(
accept_IN, classifier, CHECK_OK_CUSTOM(Void));
body->Add(PreParserStatement::ExpressionStatement(return_value), zone());
......
......@@ -585,13 +585,12 @@ struct PreParserFormalParameters : FormalParametersBase {
class PreParser;
class PreParserTraits {
template <>
class ParserBaseTraits<PreParser> {
public:
struct Type {
// TODO(marja): To be removed. The Traits object should contain all the data
// it needs.
typedef PreParser* Parser;
typedef ParserBaseTraits<PreParser> PreParserTraits;
struct Type {
// PreParser doesn't need to store generator variables.
typedef void GeneratorVariable;
......@@ -618,7 +617,12 @@ class PreParserTraits {
typedef PreParserFactory Factory;
};
explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
// TODO(nikolaos): The traits methods should not need to call methods
// of the implementation object.
PreParser* delegate() { return reinterpret_cast<PreParser*>(this); }
const PreParser* delegate() const {
return reinterpret_cast<const PreParser*>(this);
}
// Helper functions for recursive descent.
bool IsEval(PreParserIdentifier identifier) const {
......@@ -989,9 +993,6 @@ class PreParserTraits {
inline PreParserExpression RewriteYieldStar(PreParserExpression generator,
PreParserExpression expression,
int pos);
private:
PreParser* pre_parser_;
};
......@@ -1007,7 +1008,11 @@ class PreParserTraits {
// rather it is to speed up properly written and correct programs.
// That means that contextual checks (like a label being declared where
// it is used) are generally omitted.
class PreParser : public ParserBase<PreParserTraits> {
class PreParser : public ParserBase<PreParser> {
// TODO(nikolaos): This should not be necessary. It will be removed
// when the traits object stops delegating to the implementation object.
friend class ParserBaseTraits<PreParser>;
public:
typedef PreParserIdentifier Identifier;
typedef PreParserExpression Expression;
......@@ -1020,8 +1025,8 @@ class PreParser : public ParserBase<PreParserTraits> {
PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
ParserRecorder* log, uintptr_t stack_limit)
: ParserBase<PreParserTraits>(zone, scanner, stack_limit, NULL,
ast_value_factory, log, this),
: ParserBase<PreParser>(zone, scanner, stack_limit, NULL,
ast_value_factory, log),
use_counts_(nullptr) {}
// Pre-parse the program from the character stream; returns true on
......@@ -1075,8 +1080,6 @@ class PreParser : public ParserBase<PreParserTraits> {
int* use_counts);
private:
friend class PreParserTraits;
static const int kLazyParseTrialLimit = 200;
// These types form an algebra over syntactic categories that is just
......@@ -1153,27 +1156,24 @@ class PreParser : public ParserBase<PreParserTraits> {
int* use_counts_;
};
void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) {
void ParserBaseTraits<PreParser>::MaterializeUnspreadArgumentsLiterals(
int count) {
for (int i = 0; i < count; ++i) {
pre_parser_->function_state_->NextMaterializedLiteralIndex();
delegate()->function_state_->NextMaterializedLiteralIndex();
}
}
PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function,
PreParserExpressionList args,
int pos) {
return pre_parser_->factory()->NewCall(function, args, pos);
PreParserExpression ParserBaseTraits<PreParser>::SpreadCall(
PreParserExpression function, PreParserExpressionList args, int pos) {
return delegate()->factory()->NewCall(function, args, pos);
}
PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function,
PreParserExpressionList args,
int pos) {
return pre_parser_->factory()->NewCallNew(function, args, pos);
PreParserExpression ParserBaseTraits<PreParser>::SpreadCallNew(
PreParserExpression function, PreParserExpressionList args, int pos) {
return delegate()->factory()->NewCallNew(function, args, pos);
}
void PreParserTraits::ParseArrowFunctionFormalParameterList(
void ParserBaseTraits<PreParser>::ParseArrowFunctionFormalParameterList(
PreParserFormalParameters* parameters, PreParserExpression params,
const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
const Scope::Snapshot& scope_snapshot, bool* ok) {
......@@ -1181,42 +1181,41 @@ void PreParserTraits::ParseArrowFunctionFormalParameterList(
// lists that are too long.
}
PreParserExpression PreParserTraits::ParseAsyncFunctionExpression(bool* ok) {
return pre_parser_->ParseAsyncFunctionExpression(ok);
PreParserExpression ParserBaseTraits<PreParser>::ParseAsyncFunctionExpression(
bool* ok) {
return delegate()->ParseAsyncFunctionExpression(ok);
}
PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) {
return pre_parser_->ParseDoExpression(ok);
PreParserExpression ParserBaseTraits<PreParser>::ParseDoExpression(bool* ok) {
return delegate()->ParseDoExpression(ok);
}
void PreParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier,
bool* ok) {
pre_parser_->ValidateExpression(classifier, ok);
void ParserBaseTraits<PreParser>::RewriteNonPattern(
Type::ExpressionClassifier* classifier, bool* ok) {
delegate()->ValidateExpression(classifier, ok);
}
PreParserExpression PreParserTraits::RewriteAwaitExpression(
PreParserExpression ParserBaseTraits<PreParser>::RewriteAwaitExpression(
PreParserExpression value, int pos) {
return value;
}
ZoneList<PreParserExpression>* PreParserTraits::GetNonPatternList() const {
return pre_parser_->function_state_->non_patterns_to_rewrite();
ZoneList<PreParserExpression>* ParserBaseTraits<PreParser>::GetNonPatternList()
const {
return delegate()->function_state_->non_patterns_to_rewrite();
}
ZoneList<typename PreParserTraits::Type::ExpressionClassifier::Error>*
PreParserTraits::GetReportedErrorList() const {
return pre_parser_->function_state_->GetReportedErrorList();
ZoneList<
typename ParserBaseTraits<PreParser>::Type::ExpressionClassifier::Error>*
ParserBaseTraits<PreParser>::GetReportedErrorList() const {
return delegate()->function_state_->GetReportedErrorList();
}
Zone* PreParserTraits::zone() const {
return pre_parser_->function_state_->scope()->zone();
Zone* ParserBaseTraits<PreParser>::zone() const {
return delegate()->function_state_->scope()->zone();
}
PreParserExpression PreParserTraits::RewriteYieldStar(
PreParserExpression ParserBaseTraits<PreParser>::RewriteYieldStar(
PreParserExpression generator, PreParserExpression expression, int pos) {
return PreParserExpression::Default();
}
......@@ -1240,22 +1239,21 @@ PreParserStatementList PreParser::ParseEagerFunctionBody(
return PreParserStatementList();
}
PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
PreParserStatementList ParserBaseTraits<PreParser>::ParseEagerFunctionBody(
PreParserIdentifier function_name, int pos,
const PreParserFormalParameters& parameters, FunctionKind kind,
FunctionLiteral::FunctionType function_type, bool* ok) {
return pre_parser_->ParseEagerFunctionBody(function_name, pos, parameters,
kind, function_type, ok);
return delegate()->ParseEagerFunctionBody(function_name, pos, parameters,
kind, function_type, ok);
}
PreParserExpression PreParserTraits::CloseTemplateLiteral(
PreParserExpression ParserBaseTraits<PreParser>::CloseTemplateLiteral(
TemplateLiteralState* state, int start, PreParserExpression tag) {
if (IsTaggedTemplate(tag)) {
// Emulate generation of array literals for tag callsite
// 1st is array of cooked strings, second is array of raw strings
pre_parser_->function_state_->NextMaterializedLiteralIndex();
pre_parser_->function_state_->NextMaterializedLiteralIndex();
delegate()->function_state_->NextMaterializedLiteralIndex();
delegate()->function_state_->NextMaterializedLiteralIndex();
}
return EmptyExpression();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment