Chromium Code Reviews| Index: src/preparser.h |
| diff --git a/src/preparser.h b/src/preparser.h |
| index 33c737f8633e970cb3c63ea85a0efb3b5cc65be9..a34f573597fa1b7256964166116d6decc5d26315 100644 |
| --- a/src/preparser.h |
| +++ b/src/preparser.h |
| @@ -574,37 +574,94 @@ class ParserBase : public Traits { |
| bool* is_set, |
| bool* ok); |
| - ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); |
| - ExpressionT ParsePrimaryExpression(bool* ok); |
| + class ExpressionClassifier { |
|
rossberg
2015/04/22 09:30:47
Don't we also want is_valid_arrow_parameter_list,
Dmitry Lomov (no reviews)
2015/04/22 09:36:55
Sounds good, but I'd prefer to do that in a separa
|
| + public: |
| + ExpressionClassifier() |
| + : expression_error_(Scanner::Location::invalid()), |
| + binding_pattern_error_(Scanner::Location::invalid()), |
| + assignment_pattern_error_(Scanner::Location::invalid()) {} |
| + |
| + bool is_valid_expression() const { |
| + return expression_error_ == Scanner::Location::invalid(); |
| + } |
| + |
| + bool is_valid_binding_pattern() const { |
| + return binding_pattern_error_ == Scanner::Location::invalid(); |
| + } |
| + |
| + bool is_valid_assignmnent_pattern() const { |
| + return assignment_pattern_error_ == Scanner::Location::invalid(); |
| + } |
| + |
| + void RecordExpressionError(const Scanner::Location& loc) { |
| + if (!is_valid_expression()) return; |
| + expression_error_ = loc; |
| + } |
| + |
| + void RecordBindingPatternError(const Scanner::Location& loc) { |
| + if (!is_valid_binding_pattern()) return; |
| + binding_pattern_error_ = loc; |
| + } |
| + |
| + void RecordAssignmentPatternError(const Scanner::Location& loc) { |
| + if (!is_valid_assignmnent_pattern()) return; |
| + assignment_pattern_error_ = loc; |
| + } |
| + |
| + private: |
| + Scanner::Location expression_error_; |
| + Scanner::Location binding_pattern_error_; |
| + Scanner::Location assignment_pattern_error_; |
| + }; |
| + |
| + ExpressionT ParseRegExpLiteral(bool seen_equal, |
| + ExpressionClassifier* classifier, bool* ok); |
| + |
| + ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, |
| + bool* ok); |
| ExpressionT ParseExpression(bool accept_IN, bool* ok); |
| - ExpressionT ParseArrayLiteral(bool* ok); |
| + ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, |
| + bool* ok); |
| + ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); |
| ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
| bool* is_static, bool* is_computed_name, |
| - bool* ok); |
| - ExpressionT ParseObjectLiteral(bool* ok); |
| + ExpressionClassifier* classifier, bool* ok); |
| + ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
| ObjectLiteralPropertyT ParsePropertyDefinition( |
| ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
| - bool* ok); |
| + ExpressionClassifier* classifier, bool* ok); |
| typename Traits::Type::ExpressionList ParseArguments( |
| - Scanner::Location* first_spread_pos, bool* ok); |
| - ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
| - ExpressionT ParseYieldExpression(bool* ok); |
| - ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
| - ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
| - ExpressionT ParseUnaryExpression(bool* ok); |
| - ExpressionT ParsePostfixExpression(bool* ok); |
| - ExpressionT ParseLeftHandSideExpression(bool* ok); |
| - ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
| - ExpressionT ParseMemberExpression(bool* ok); |
| - ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
| - bool* ok); |
| + Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
| + bool* ok); |
| + ExpressionT ParseAssignmentExpression(bool accept_IN, |
| + ExpressionClassifier* classifier, |
| + bool* ok); |
| + ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); |
| + ExpressionT ParseConditionalExpression(bool accept_IN, |
| + ExpressionClassifier* classifier, |
| + bool* ok); |
| + ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
| + ExpressionClassifier* classifier, bool* ok); |
| + ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); |
| + ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, |
| + bool* ok); |
| + ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, |
| + bool* ok); |
| + ExpressionT ParseMemberWithNewPrefixesExpression( |
| + ExpressionClassifier* classifier, bool* ok); |
| + ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok); |
| + ExpressionT ParseMemberExpressionContinuation( |
| + ExpressionT expression, ExpressionClassifier* classifier, bool* ok); |
| ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
| + ExpressionClassifier* classifier, |
| bool* ok); |
| - ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
| + ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, |
| + ExpressionClassifier* classifier, bool* ok); |
| void AddTemplateExpression(ExpressionT); |
| - ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
| + ExpressionT ParseSuperExpression(bool is_new, |
| + ExpressionClassifier* classifier, bool* ok); |
| // Checks if the expression is a valid reference expression (e.g., on the |
| // left-hand side of assignments). Although ruled out by ECMA as early errors, |
| @@ -1930,7 +1987,7 @@ ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get, |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( |
| - bool seen_equal, bool* ok) { |
| + bool seen_equal, ExpressionClassifier* classifier, bool* ok) { |
| int pos = peek_position(); |
| if (!scanner()->ScanRegExpPattern(seen_equal)) { |
| Next(); |
| @@ -1967,9 +2024,17 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( |
| #define DUMMY ) // to make indentation work |
| #undef DUMMY |
| + |
| +#define CHECK_CLASSIFIER_OK classifier, ok); \ |
|
rossberg
2015/04/22 09:30:47
Don't think this macro is worth it. It saves a sin
Dmitry Lomov (no reviews)
2015/04/22 09:36:55
Yes, I think we should merge ok into a classifier
|
| + if (!*ok) return this->EmptyExpression(); \ |
| + ((void)0 |
| +#define DUMMY ) // to make indentation work |
| +#undef DUMMY |
| + |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT |
| -ParserBase<Traits>::ParsePrimaryExpression(bool* ok) { |
| +ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, |
| + bool* ok) { |
| // PrimaryExpression :: |
| // 'this' |
| // 'null' |
| @@ -2026,19 +2091,19 @@ ParserBase<Traits>::ParsePrimaryExpression(bool* ok) { |
| } |
| case Token::ASSIGN_DIV: |
| - result = this->ParseRegExpLiteral(true, CHECK_OK); |
| + result = this->ParseRegExpLiteral(true, CHECK_CLASSIFIER_OK); |
| break; |
| case Token::DIV: |
| - result = this->ParseRegExpLiteral(false, CHECK_OK); |
| + result = this->ParseRegExpLiteral(false, CHECK_CLASSIFIER_OK); |
| break; |
| case Token::LBRACK: |
| - result = this->ParseArrayLiteral(CHECK_OK); |
| + result = this->ParseArrayLiteral(CHECK_CLASSIFIER_OK); |
| break; |
| case Token::LBRACE: |
| - result = this->ParseObjectLiteral(CHECK_OK); |
| + result = this->ParseObjectLiteral(CHECK_CLASSIFIER_OK); |
| break; |
| case Token::LPAREN: |
| @@ -2048,12 +2113,12 @@ ParserBase<Traits>::ParsePrimaryExpression(bool* ok) { |
| // for which an empty parameter list "()" is valid input. |
| Consume(Token::RPAREN); |
| result = this->ParseArrowFunctionLiteral( |
| - beg_pos, this->EmptyArrowParamList(), CHECK_OK); |
| + beg_pos, this->EmptyArrowParamList(), CHECK_CLASSIFIER_OK); |
| } else { |
| // Heuristically try to detect immediately called functions before |
| // seeing the call parentheses. |
| parenthesized_function_ = (peek() == Token::FUNCTION); |
| - result = this->ParseExpression(true, CHECK_OK); |
| + result = this->ParseExpression(true, CHECK_CLASSIFIER_OK); |
| result->increase_parenthesization_level(); |
| Expect(Token::RPAREN, CHECK_OK); |
| } |
| @@ -2084,7 +2149,7 @@ ParserBase<Traits>::ParsePrimaryExpression(bool* ok) { |
| case Token::TEMPLATE_SPAN: |
| case Token::TEMPLATE_TAIL: |
| result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, |
| - CHECK_OK); |
| + CHECK_CLASSIFIER_OK); |
| break; |
| case Token::MOD: |
| @@ -2105,19 +2170,32 @@ ParserBase<Traits>::ParsePrimaryExpression(bool* ok) { |
| return result; |
| } |
| -// Precedence = 1 |
| + |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| bool accept_IN, bool* ok) { |
| + ExpressionClassifier classifier; |
| + ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
| + // TODO(dslomov): report error if not a valid expression. |
| + return result; |
| +} |
| + |
| + |
| +// Precedence = 1 |
| +template <class Traits> |
| +typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| + bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
| // Expression :: |
| // AssignmentExpression |
| // Expression ',' AssignmentExpression |
| - ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK); |
| + ExpressionT result = |
| + this->ParseAssignmentExpression(accept_IN, CHECK_CLASSIFIER_OK); |
| while (peek() == Token::COMMA) { |
| Expect(Token::COMMA, CHECK_OK); |
| int pos = position(); |
| - ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); |
| + ExpressionT right = |
| + this->ParseAssignmentExpression(accept_IN, CHECK_CLASSIFIER_OK); |
| result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
| } |
| return result; |
| @@ -2126,7 +2204,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( |
| - bool* ok) { |
| + ExpressionClassifier* classifier, bool* ok) { |
| // ArrayLiteral :: |
| // '[' Expression? (',' Expression?)* ']' |
| @@ -2144,7 +2222,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( |
| } |
| elem = this->GetLiteralTheHole(peek_position(), factory()); |
| } else { |
| - elem = this->ParseAssignmentExpression(true, CHECK_OK); |
| + elem = this->ParseAssignmentExpression(true, CHECK_CLASSIFIER_OK); |
| } |
| values->Add(elem, zone_); |
| if (peek() != Token::RBRACK) { |
| @@ -2163,7 +2241,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( |
| IdentifierT* name, bool* is_get, bool* is_set, bool* is_static, |
| - bool* is_computed_name, bool* ok) { |
| + bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) { |
| Token::Value token = peek(); |
| int pos = peek_position(); |
| @@ -2196,7 +2274,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( |
| if (allow_harmony_computed_property_names_) { |
| *is_computed_name = true; |
| Consume(Token::LBRACK); |
| - ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); |
| + ExpressionT expression = |
| + ParseAssignmentExpression(true, CHECK_CLASSIFIER_OK); |
| Expect(Token::RBRACK, CHECK_OK); |
| return expression; |
| } |
| @@ -2220,12 +2299,10 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( |
| template <class Traits> |
| typename ParserBase<Traits>::ObjectLiteralPropertyT |
| -ParserBase<Traits>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker, |
| - bool in_class, bool has_extends, |
| - bool is_static, |
| - bool* is_computed_name, |
| - bool* has_seen_constructor, |
| - bool* ok) { |
| +ParserBase<Traits>::ParsePropertyDefinition( |
| + ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| + bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
| + ExpressionClassifier* classifier, bool* ok) { |
| DCHECK(!in_class || is_static || has_seen_constructor != nullptr); |
| ExpressionT value = this->EmptyExpression(); |
| IdentifierT name = this->EmptyIdentifier(); |
| @@ -2238,7 +2315,7 @@ ParserBase<Traits>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker, |
| int next_beg_pos = scanner()->peek_location().beg_pos; |
| int next_end_pos = scanner()->peek_location().end_pos; |
| ExpressionT name_expression = ParsePropertyName( |
| - &name, &is_get, &is_set, &name_is_static, is_computed_name, |
| + &name, &is_get, &is_set, &name_is_static, is_computed_name, classifier, |
| CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| if (fni_ != nullptr && !*is_computed_name) { |
| @@ -2254,7 +2331,7 @@ ParserBase<Traits>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker, |
| } |
| Consume(Token::COLON); |
| value = this->ParseAssignmentExpression( |
| - true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| + true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| } else if (is_generator || |
| (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { |
| @@ -2290,7 +2367,7 @@ ParserBase<Traits>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker, |
| } else if (in_class && name_is_static && !is_static) { |
| // static MethodDefinition |
| return ParsePropertyDefinition(checker, true, has_extends, true, |
| - is_computed_name, nullptr, ok); |
| + is_computed_name, nullptr, classifier, ok); |
| } else if (is_get || is_set) { |
| // Accessor |
| name = this->EmptyIdentifier(); |
| @@ -2298,7 +2375,7 @@ ParserBase<Traits>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker, |
| name_token = peek(); |
| name_expression = ParsePropertyName( |
| - &name, &dont_care, &dont_care, &dont_care, is_computed_name, |
| + &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, |
| CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| if (!*is_computed_name) { |
| @@ -2353,7 +2430,7 @@ ParserBase<Traits>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker, |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( |
| - bool* ok) { |
| + ExpressionClassifier* classifier, bool* ok) { |
| // ObjectLiteral :: |
| // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
| @@ -2376,7 +2453,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( |
| bool is_computed_name = false; |
| ObjectLiteralPropertyT property = this->ParsePropertyDefinition( |
| &checker, in_class, has_extends, is_static, &is_computed_name, NULL, |
| - CHECK_OK); |
| + CHECK_CLASSIFIER_OK); |
| if (is_computed_name) { |
| has_computed_names = true; |
| @@ -2419,7 +2496,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( |
| template <class Traits> |
| typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( |
| - Scanner::Location* first_spread_arg_loc, bool* ok) { |
| + Scanner::Location* first_spread_arg_loc, ExpressionClassifier* classifier, |
| + bool* ok) { |
| // Arguments :: |
| // '(' (AssignmentExpression)*[','] ')' |
| @@ -2436,7 +2514,7 @@ typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( |
| if (is_spread) Consume(Token::ELLIPSIS); |
| ExpressionT argument = this->ParseAssignmentExpression( |
| - true, CHECK_OK_CUSTOM(NullExpressionList)); |
| + true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); |
| if (is_spread) { |
| if (!spread_arg.IsValid()) { |
| spread_arg.beg_pos = start_pos; |
| @@ -2486,7 +2564,9 @@ typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( |
| // Precedence = 2 |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT |
| -ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| +ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
| + ExpressionClassifier* classifier, |
| + bool* ok) { |
| // AssignmentExpression :: |
| // ConditionalExpression |
| // ArrowFunction |
| @@ -2496,18 +2576,18 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| Scanner::Location lhs_location = scanner()->peek_location(); |
| if (peek() == Token::YIELD && is_generator()) { |
| - return this->ParseYieldExpression(ok); |
| + return this->ParseYieldExpression(classifier, ok); |
| } |
| if (fni_ != NULL) fni_->Enter(); |
| ParserBase<Traits>::Checkpoint checkpoint(this); |
| ExpressionT expression = |
| - this->ParseConditionalExpression(accept_IN, CHECK_OK); |
| + this->ParseConditionalExpression(accept_IN, CHECK_CLASSIFIER_OK); |
| if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { |
| checkpoint.Restore(); |
| - expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos, |
| - expression, CHECK_OK); |
| + expression = this->ParseArrowFunctionLiteral( |
| + lhs_location.beg_pos, expression, CHECK_CLASSIFIER_OK); |
| return expression; |
| } |
| @@ -2523,7 +2603,8 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| Token::Value op = Next(); // Get assignment operator. |
| int pos = position(); |
| - ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); |
| + ExpressionT right = |
| + this->ParseAssignmentExpression(accept_IN, CHECK_CLASSIFIER_OK); |
| // TODO(1231235): We try to estimate the set of properties set by |
| // constructors. We define a new property whenever there is an |
| @@ -2556,7 +2637,8 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT |
| -ParserBase<Traits>::ParseYieldExpression(bool* ok) { |
| +ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, |
| + bool* ok) { |
| // YieldExpression :: |
| // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
| int pos = peek_position(); |
| @@ -2584,7 +2666,7 @@ ParserBase<Traits>::ParseYieldExpression(bool* ok) { |
| DCHECK_EQ(Yield::kDelegating, kind); |
| // Delegating yields require an RHS; fall through. |
| default: |
| - expression = ParseAssignmentExpression(false, CHECK_OK); |
| + expression = ParseAssignmentExpression(false, CHECK_CLASSIFIER_OK); |
| break; |
| } |
| } |
| @@ -2604,22 +2686,25 @@ ParserBase<Traits>::ParseYieldExpression(bool* ok) { |
| // Precedence = 3 |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT |
| -ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, bool* ok) { |
| +ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, |
| + ExpressionClassifier* classifier, |
| + bool* ok) { |
| // ConditionalExpression :: |
| // LogicalOrExpression |
| // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
| int pos = peek_position(); |
| // We start using the binary expression parser for prec >= 4 only! |
| - ExpressionT expression = this->ParseBinaryExpression(4, accept_IN, CHECK_OK); |
| + ExpressionT expression = |
| + this->ParseBinaryExpression(4, accept_IN, CHECK_CLASSIFIER_OK); |
| if (peek() != Token::CONDITIONAL) return expression; |
| Consume(Token::CONDITIONAL); |
| // In parsing the first assignment expression in conditional |
| // expressions we always accept the 'in' keyword; see ECMA-262, |
| // section 11.12, page 58. |
| - ExpressionT left = ParseAssignmentExpression(true, CHECK_OK); |
| + ExpressionT left = ParseAssignmentExpression(true, CHECK_CLASSIFIER_OK); |
| Expect(Token::COLON, CHECK_OK); |
| - ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| + ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_CLASSIFIER_OK); |
| return factory()->NewConditional(expression, left, right, pos); |
| } |
| @@ -2627,16 +2712,19 @@ ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, bool* ok) { |
| // Precedence >= 4 |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT |
| -ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { |
| +ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, |
| + ExpressionClassifier* classifier, |
| + bool* ok) { |
| DCHECK(prec >= 4); |
| - ExpressionT x = this->ParseUnaryExpression(CHECK_OK); |
| + ExpressionT x = this->ParseUnaryExpression(CHECK_CLASSIFIER_OK); |
| for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
| // prec1 >= 4 |
| while (Precedence(peek(), accept_IN) == prec1) { |
| Token::Value op = Next(); |
| Scanner::Location op_location = scanner()->location(); |
| int pos = position(); |
| - ExpressionT y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); |
| + ExpressionT y = |
| + ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_CLASSIFIER_OK); |
| if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, |
| factory())) { |
| @@ -2677,7 +2765,8 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT |
| -ParserBase<Traits>::ParseUnaryExpression(bool* ok) { |
| +ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier, |
| + bool* ok) { |
| // UnaryExpression :: |
| // PostfixExpression |
| // 'delete' UnaryExpression |
| @@ -2694,7 +2783,7 @@ ParserBase<Traits>::ParseUnaryExpression(bool* ok) { |
| if (Token::IsUnaryOp(op)) { |
| op = Next(); |
| int pos = position(); |
| - ExpressionT expression = ParseUnaryExpression(CHECK_OK); |
| + ExpressionT expression = ParseUnaryExpression(CHECK_CLASSIFIER_OK); |
| if (op == Token::DELETE && is_strict(language_mode())) { |
| if (is_strong(language_mode())) { |
| @@ -2714,7 +2803,7 @@ ParserBase<Traits>::ParseUnaryExpression(bool* ok) { |
| } else if (Token::IsCountOp(op)) { |
| op = Next(); |
| Scanner::Location lhs_location = scanner()->peek_location(); |
| - ExpressionT expression = this->ParseUnaryExpression(CHECK_OK); |
| + ExpressionT expression = this->ParseUnaryExpression(CHECK_CLASSIFIER_OK); |
| expression = this->CheckAndRewriteReferenceExpression( |
| expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK); |
| this->MarkExpressionAsAssigned(expression); |
| @@ -2725,19 +2814,21 @@ ParserBase<Traits>::ParseUnaryExpression(bool* ok) { |
| position()); |
| } else { |
| - return this->ParsePostfixExpression(ok); |
| + return this->ParsePostfixExpression(classifier, ok); |
| } |
| } |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT |
| -ParserBase<Traits>::ParsePostfixExpression(bool* ok) { |
| +ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, |
| + bool* ok) { |
| // PostfixExpression :: |
| // LeftHandSideExpression ('++' | '--')? |
| Scanner::Location lhs_location = scanner()->peek_location(); |
| - ExpressionT expression = this->ParseLeftHandSideExpression(CHECK_OK); |
| + ExpressionT expression = |
| + this->ParseLeftHandSideExpression(CHECK_CLASSIFIER_OK); |
| if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| Token::IsCountOp(peek())) { |
| expression = this->CheckAndRewriteReferenceExpression( |
| @@ -2757,18 +2848,20 @@ ParserBase<Traits>::ParsePostfixExpression(bool* ok) { |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT |
| -ParserBase<Traits>::ParseLeftHandSideExpression(bool* ok) { |
| +ParserBase<Traits>::ParseLeftHandSideExpression( |
| + ExpressionClassifier* classifier, bool* ok) { |
| // LeftHandSideExpression :: |
| // (NewExpression | MemberExpression) ... |
| - ExpressionT result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); |
| + ExpressionT result = |
| + this->ParseMemberWithNewPrefixesExpression(CHECK_CLASSIFIER_OK); |
| while (true) { |
| switch (peek()) { |
| case Token::LBRACK: { |
| Consume(Token::LBRACK); |
| int pos = position(); |
| - ExpressionT index = ParseExpression(true, CHECK_OK); |
| + ExpressionT index = ParseExpression(true, CHECK_CLASSIFIER_OK); |
| result = factory()->NewProperty(result, index, pos); |
| Expect(Token::RBRACK, CHECK_OK); |
| break; |
| @@ -2802,7 +2895,7 @@ ParserBase<Traits>::ParseLeftHandSideExpression(bool* ok) { |
| } |
| Scanner::Location spread_pos; |
| typename Traits::Type::ExpressionList args = |
| - ParseArguments(&spread_pos, CHECK_OK); |
| + ParseArguments(&spread_pos, CHECK_CLASSIFIER_OK); |
| // Keep track of eval() calls since they disable all local variable |
| // optimizations. |
| @@ -2842,7 +2935,8 @@ ParserBase<Traits>::ParseLeftHandSideExpression(bool* ok) { |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT |
| -ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) { |
| +ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( |
| + ExpressionClassifier* classifier, bool* ok) { |
| // NewExpression :: |
| // ('new')+ MemberExpression |
| @@ -2866,15 +2960,15 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) { |
| ExpressionT result = this->EmptyExpression(); |
| if (peek() == Token::SUPER) { |
| const bool is_new = true; |
| - result = ParseSuperExpression(is_new, CHECK_OK); |
| + result = ParseSuperExpression(is_new, CHECK_CLASSIFIER_OK); |
| } else { |
| - result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); |
| + result = this->ParseMemberWithNewPrefixesExpression(CHECK_CLASSIFIER_OK); |
| } |
| if (peek() == Token::LPAREN) { |
| // NewExpression with arguments. |
| Scanner::Location spread_pos; |
| typename Traits::Type::ExpressionList args = |
| - this->ParseArguments(&spread_pos, CHECK_OK); |
| + this->ParseArguments(&spread_pos, CHECK_CLASSIFIER_OK); |
| if (spread_pos.IsValid()) { |
| args = Traits::PrepareSpreadArguments(args); |
| @@ -2883,7 +2977,8 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) { |
| result = factory()->NewCallNew(result, args, new_pos); |
| } |
| // The expression can still continue with . or [ after the arguments. |
| - result = this->ParseMemberExpressionContinuation(result, CHECK_OK); |
| + result = |
| + this->ParseMemberExpressionContinuation(result, CHECK_CLASSIFIER_OK); |
| return result; |
| } |
| // NewExpression without arguments. |
| @@ -2891,13 +2986,14 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) { |
| new_pos); |
| } |
| // No 'new' or 'super' keyword. |
| - return this->ParseMemberExpression(ok); |
| + return this->ParseMemberExpression(classifier, ok); |
| } |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT |
| -ParserBase<Traits>::ParseMemberExpression(bool* ok) { |
| +ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, |
| + bool* ok) { |
| // MemberExpression :: |
| // (PrimaryExpression | FunctionLiteral | ClassLiteral) |
| // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* |
| @@ -2931,19 +3027,21 @@ ParserBase<Traits>::ParseMemberExpression(bool* ok) { |
| CHECK_OK); |
| } else if (peek() == Token::SUPER) { |
| const bool is_new = false; |
| - result = ParseSuperExpression(is_new, CHECK_OK); |
| + result = ParseSuperExpression(is_new, CHECK_CLASSIFIER_OK); |
| } else { |
| - result = ParsePrimaryExpression(CHECK_OK); |
| + result = ParsePrimaryExpression(CHECK_CLASSIFIER_OK); |
| } |
| - result = ParseMemberExpressionContinuation(result, CHECK_OK); |
| + result = ParseMemberExpressionContinuation(result, CHECK_CLASSIFIER_OK); |
| return result; |
| } |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT |
| -ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { |
| +ParserBase<Traits>::ParseSuperExpression(bool is_new, |
| + ExpressionClassifier* classifier, |
| + bool* ok) { |
| Expect(Token::SUPER, CHECK_OK); |
| FunctionState* function_state = function_state_; |
| @@ -2987,8 +3085,8 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { |
| template <class Traits> |
| typename ParserBase<Traits>::ExpressionT |
| -ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, |
| - bool* ok) { |
| +ParserBase<Traits>::ParseMemberExpressionContinuation( |
| + ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { |
| // Parses this part of MemberExpression: |
| // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
| while (true) { |
| @@ -2996,7 +3094,7 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, |
| case Token::LBRACK: { |
| Consume(Token::LBRACK); |
| int pos = position(); |
| - ExpressionT index = this->ParseExpression(true, CHECK_OK); |
| + ExpressionT index = this->ParseExpression(true, CHECK_CLASSIFIER_OK); |
| expression = factory()->NewProperty(expression, index, pos); |
| if (fni_ != NULL) { |
| this->PushPropertyName(fni_, index); |
| @@ -3028,7 +3126,7 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, |
| expression->AsFunctionLiteral()->set_parenthesized(); |
| } |
| } |
| - expression = ParseTemplateLiteral(expression, pos, CHECK_OK); |
| + expression = ParseTemplateLiteral(expression, pos, CHECK_CLASSIFIER_OK); |
| break; |
| } |
| default: |
| @@ -3044,6 +3142,7 @@ template <class Traits> |
| typename ParserBase<Traits>::ExpressionT |
| ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, |
| ExpressionT params_ast, |
| + ExpressionClassifier* classifier, |
| bool* ok) { |
| if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
| // ASI inserts `;` after arrow parameters if a line terminator is found. |
| @@ -3115,7 +3214,8 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, |
| // Single-expression body |
| int pos = position(); |
| parenthesized_function_ = false; |
| - ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); |
| + ExpressionT expression = |
| + ParseAssignmentExpression(true, CHECK_CLASSIFIER_OK); |
| body = this->NewStatementList(1, zone()); |
| body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
| materialized_literal_count = function_state.materialized_literal_count(); |
| @@ -3164,7 +3264,9 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, |
| template <typename Traits> |
| typename ParserBase<Traits>::ExpressionT |
| -ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, bool* ok) { |
| +ParserBase<Traits>::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. |
| @@ -3216,7 +3318,7 @@ ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, bool* ok) { |
| } |
| int expr_pos = peek_position(); |
| - ExpressionT expression = this->ParseExpression(true, CHECK_OK); |
| + ExpressionT expression = this->ParseExpression(true, CHECK_CLASSIFIER_OK); |
| Traits::AddTemplateExpression(&ts, expression); |
| if (peek() != Token::RBRACE) { |