| Index: src/preparser.h
|
| diff --git a/src/preparser.h b/src/preparser.h
|
| index 0d71d939c01c7a3cd9a3d89278c9f390c5487d92..36320513adb872f5ef4f51d450551af9ab1499d8 100644
|
| --- a/src/preparser.h
|
| +++ b/src/preparser.h
|
| @@ -600,40 +600,98 @@ class ParserBase : public Traits {
|
| bool* is_set,
|
| bool* ok);
|
|
|
| - ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok);
|
|
|
| - ExpressionT ParsePrimaryExpression(bool* ok);
|
| + class ExpressionClassifier {
|
| + 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(
|
| Scope* function_scope, const FormalParameterErrorLocations& error_locs,
|
| - bool has_rest, bool* ok);
|
| - ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
|
| + bool has_rest, ExpressionClassifier* classifier, bool* ok);
|
| + ExpressionT ParseTemplateLiteral(ExpressionT tag, int start,
|
| + ExpressionClassifier* classifier, bool* ok);
|
| void AddTemplateExpression(ExpressionT);
|
| - ExpressionT ParseSuperExpression(bool is_new, bool* ok);
|
| - ExpressionT ParseStrongInitializationExpression(bool* ok);
|
| - ExpressionT ParseStrongSuperCallExpression(bool* ok);
|
| + ExpressionT ParseSuperExpression(bool is_new,
|
| + ExpressionClassifier* classifier, bool* ok);
|
| + ExpressionT ParseStrongInitializationExpression(
|
| + ExpressionClassifier* classifier, bool* ok);
|
| + ExpressionT ParseStrongSuperCallExpression(ExpressionClassifier* classifier,
|
| + bool* ok);
|
|
|
| void ParseFormalParameter(FormalParameterScopeT* scope,
|
| FormalParameterErrorLocations* locs, bool is_rest,
|
| @@ -1989,7 +2047,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();
|
| @@ -2026,9 +2084,11 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
|
| #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'
|
| @@ -2094,19 +2154,19 @@ ParserBase<Traits>::ParsePrimaryExpression(bool* ok) {
|
| }
|
|
|
| case Token::ASSIGN_DIV:
|
| - result = this->ParseRegExpLiteral(true, CHECK_OK);
|
| + result = this->ParseRegExpLiteral(true, classifier, CHECK_OK);
|
| break;
|
|
|
| case Token::DIV:
|
| - result = this->ParseRegExpLiteral(false, CHECK_OK);
|
| + result = this->ParseRegExpLiteral(false, classifier, CHECK_OK);
|
| break;
|
|
|
| case Token::LBRACK:
|
| - result = this->ParseArrayLiteral(CHECK_OK);
|
| + result = this->ParseArrayLiteral(classifier, CHECK_OK);
|
| break;
|
|
|
| case Token::LBRACE:
|
| - result = this->ParseObjectLiteral(CHECK_OK);
|
| + result = this->ParseObjectLiteral(classifier, CHECK_OK);
|
| break;
|
|
|
| case Token::LPAREN:
|
| @@ -2118,12 +2178,12 @@ ParserBase<Traits>::ParsePrimaryExpression(bool* ok) {
|
| FormalParameterErrorLocations error_locs;
|
| bool has_rest = false;
|
| result = this->ParseArrowFunctionLiteral(scope, error_locs, has_rest,
|
| - CHECK_OK);
|
| + classifier, CHECK_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, classifier, CHECK_OK);
|
| result->increase_parenthesization_level();
|
| Expect(Token::RPAREN, CHECK_OK);
|
| }
|
| @@ -2154,7 +2214,7 @@ ParserBase<Traits>::ParsePrimaryExpression(bool* ok) {
|
| case Token::TEMPLATE_SPAN:
|
| case Token::TEMPLATE_TAIL:
|
| result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
|
| - CHECK_OK);
|
| + classifier, CHECK_OK);
|
| break;
|
|
|
| case Token::MOD:
|
| @@ -2175,19 +2235,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, classifier, CHECK_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, classifier, CHECK_OK);
|
| result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
|
| }
|
| return result;
|
| @@ -2196,7 +2269,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?)* ']'
|
|
|
| @@ -2214,7 +2287,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, classifier, CHECK_OK);
|
| }
|
| values->Add(elem, zone_);
|
| if (peek() != Token::RBRACK) {
|
| @@ -2233,7 +2306,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();
|
|
|
| @@ -2266,7 +2339,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, classifier, CHECK_OK);
|
| Expect(Token::RBRACK, CHECK_OK);
|
| return expression;
|
| }
|
| @@ -2290,12 +2364,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();
|
| @@ -2308,7 +2380,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) {
|
| @@ -2324,7 +2396,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)) {
|
| @@ -2360,7 +2432,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();
|
| @@ -2368,7 +2440,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) {
|
| @@ -2423,7 +2495,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)* ','? )? '}'
|
|
|
| @@ -2446,7 +2518,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);
|
| + classifier, CHECK_OK);
|
|
|
| if (is_computed_name) {
|
| has_computed_names = true;
|
| @@ -2489,7 +2561,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)*[','] ')'
|
|
|
| @@ -2506,7 +2579,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;
|
| @@ -2556,7 +2629,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
|
| @@ -2566,13 +2641,13 @@ 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, classifier, CHECK_OK);
|
|
|
| if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
|
| checkpoint.Restore();
|
| @@ -2583,8 +2658,8 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
|
| scope->set_start_position(lhs_location.beg_pos);
|
| this->ParseArrowFunctionFormalParameters(scope, expression, loc,
|
| &error_locs, &has_rest, CHECK_OK);
|
| - expression =
|
| - this->ParseArrowFunctionLiteral(scope, error_locs, has_rest, CHECK_OK);
|
| + expression = this->ParseArrowFunctionLiteral(scope, error_locs, has_rest,
|
| + classifier, CHECK_OK);
|
| return expression;
|
| }
|
|
|
| @@ -2600,7 +2675,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, classifier, CHECK_OK);
|
|
|
| // TODO(1231235): We try to estimate the set of properties set by
|
| // constructors. We define a new property whenever there is an
|
| @@ -2633,7 +2709,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();
|
| @@ -2661,7 +2738,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, classifier, CHECK_OK);
|
| break;
|
| }
|
| }
|
| @@ -2681,22 +2758,26 @@ 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, classifier, CHECK_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, classifier, CHECK_OK);
|
| Expect(Token::COLON, CHECK_OK);
|
| - ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK);
|
| + ExpressionT right =
|
| + ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
|
| return factory()->NewConditional(expression, left, right, pos);
|
| }
|
|
|
| @@ -2704,16 +2785,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(classifier, CHECK_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, classifier, CHECK_OK);
|
|
|
| if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
|
| factory())) {
|
| @@ -2754,7 +2838,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
|
| @@ -2771,7 +2856,7 @@ ParserBase<Traits>::ParseUnaryExpression(bool* ok) {
|
| if (Token::IsUnaryOp(op)) {
|
| op = Next();
|
| int pos = position();
|
| - ExpressionT expression = ParseUnaryExpression(CHECK_OK);
|
| + ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
|
|
|
| if (op == Token::DELETE && is_strict(language_mode())) {
|
| if (is_strong(language_mode())) {
|
| @@ -2791,7 +2876,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(classifier, CHECK_OK);
|
| expression = this->CheckAndRewriteReferenceExpression(
|
| expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK);
|
| this->MarkExpressionAsAssigned(expression);
|
| @@ -2802,19 +2887,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(classifier, CHECK_OK);
|
| if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
|
| Token::IsCountOp(peek())) {
|
| expression = this->CheckAndRewriteReferenceExpression(
|
| @@ -2834,18 +2921,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(classifier, CHECK_OK);
|
|
|
| while (true) {
|
| switch (peek()) {
|
| case Token::LBRACK: {
|
| Consume(Token::LBRACK);
|
| int pos = position();
|
| - ExpressionT index = ParseExpression(true, CHECK_OK);
|
| + ExpressionT index = ParseExpression(true, classifier, CHECK_OK);
|
| result = factory()->NewProperty(result, index, pos);
|
| Expect(Token::RBRACK, CHECK_OK);
|
| break;
|
| @@ -2879,7 +2968,7 @@ ParserBase<Traits>::ParseLeftHandSideExpression(bool* ok) {
|
| }
|
| Scanner::Location spread_pos;
|
| typename Traits::Type::ExpressionList args =
|
| - ParseArguments(&spread_pos, CHECK_OK);
|
| + ParseArguments(&spread_pos, classifier, CHECK_OK);
|
|
|
| // Keep track of eval() calls since they disable all local variable
|
| // optimizations.
|
| @@ -2919,7 +3008,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
|
|
|
| @@ -2943,15 +3033,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, classifier, CHECK_OK);
|
| } else {
|
| - result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
|
| + result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_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, classifier, CHECK_OK);
|
|
|
| if (spread_pos.IsValid()) {
|
| args = Traits::PrepareSpreadArguments(args);
|
| @@ -2960,7 +3050,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, classifier, CHECK_OK);
|
| return result;
|
| }
|
| // NewExpression without arguments.
|
| @@ -2968,13 +3059,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)*
|
| @@ -3008,19 +3100,20 @@ 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, classifier, CHECK_OK);
|
| } else {
|
| - result = ParsePrimaryExpression(CHECK_OK);
|
| + result = ParsePrimaryExpression(classifier, CHECK_OK);
|
| }
|
|
|
| - result = ParseMemberExpressionContinuation(result, CHECK_OK);
|
| + result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
|
| return result;
|
| }
|
|
|
|
|
| template <class Traits>
|
| typename ParserBase<Traits>::ExpressionT
|
| -ParserBase<Traits>::ParseStrongInitializationExpression(bool* ok) {
|
| +ParserBase<Traits>::ParseStrongInitializationExpression(
|
| + ExpressionClassifier* classifier, bool* ok) {
|
| // InitializationExpression :: (strong mode)
|
| // 'this' '.' IdentifierName '=' AssignmentExpression
|
| // 'this' '[' Expression ']' '=' AssignmentExpression
|
| @@ -3038,7 +3131,7 @@ ParserBase<Traits>::ParseStrongInitializationExpression(bool* ok) {
|
| case Token::LBRACK: {
|
| Consume(Token::LBRACK);
|
| int pos = position();
|
| - ExpressionT index = this->ParseExpression(true, CHECK_OK);
|
| + ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
|
| left = factory()->NewProperty(this_expr, index, pos);
|
| if (fni_ != NULL) {
|
| this->PushPropertyName(fni_, index);
|
| @@ -3072,7 +3165,8 @@ ParserBase<Traits>::ParseStrongInitializationExpression(bool* ok) {
|
| Consume(Token::ASSIGN);
|
| left = this->MarkExpressionAsAssigned(left);
|
|
|
| - ExpressionT right = this->ParseAssignmentExpression(true, CHECK_OK);
|
| + ExpressionT right =
|
| + this->ParseAssignmentExpression(true, classifier, CHECK_OK);
|
| this->CheckAssigningFunctionLiteralToProperty(left, right);
|
| function_state_->AddProperty();
|
| if (fni_ != NULL) {
|
| @@ -3100,7 +3194,8 @@ ParserBase<Traits>::ParseStrongInitializationExpression(bool* ok) {
|
|
|
| template <class Traits>
|
| typename ParserBase<Traits>::ExpressionT
|
| -ParserBase<Traits>::ParseStrongSuperCallExpression(bool* ok) {
|
| +ParserBase<Traits>::ParseStrongSuperCallExpression(
|
| + ExpressionClassifier* classifier, bool* ok) {
|
| // SuperCallExpression :: (strong mode)
|
| // 'super' '(' ExpressionList ')'
|
|
|
| @@ -3117,7 +3212,7 @@ ParserBase<Traits>::ParseStrongSuperCallExpression(bool* ok) {
|
|
|
| Scanner::Location spread_pos;
|
| typename Traits::Type::ExpressionList args =
|
| - ParseArguments(&spread_pos, CHECK_OK);
|
| + ParseArguments(&spread_pos, classifier, CHECK_OK);
|
|
|
| // TODO(rossberg): This doesn't work with arrow functions yet.
|
| if (!IsSubclassConstructor(function_state_->kind())) {
|
| @@ -3151,7 +3246,9 @@ ParserBase<Traits>::ParseStrongSuperCallExpression(bool* ok) {
|
|
|
| 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);
|
|
|
| // TODO(wingo): Does this actually work with lazily compiled arrows?
|
| @@ -3190,8 +3287,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) {
|
| @@ -3199,7 +3296,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, classifier, CHECK_OK);
|
| expression = factory()->NewProperty(expression, index, pos);
|
| if (fni_ != NULL) {
|
| this->PushPropertyName(fni_, index);
|
| @@ -3231,7 +3328,8 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
|
| expression->AsFunctionLiteral()->set_parenthesized();
|
| }
|
| }
|
| - expression = ParseTemplateLiteral(expression, pos, CHECK_OK);
|
| + expression =
|
| + ParseTemplateLiteral(expression, pos, classifier, CHECK_OK);
|
| break;
|
| }
|
| default:
|
| @@ -3343,7 +3441,7 @@ template <class Traits>
|
| typename ParserBase<Traits>::ExpressionT
|
| ParserBase<Traits>::ParseArrowFunctionLiteral(
|
| Scope* scope, const FormalParameterErrorLocations& error_locs,
|
| - bool has_rest, bool* ok) {
|
| + bool has_rest, ExpressionClassifier* classifier, bool* ok) {
|
| if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
|
| // ASI inserts `;` after arrow parameters if a line terminator is found.
|
| // `=> ...` is never a valid expression, so report as syntax error.
|
| @@ -3389,7 +3487,8 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
|
| // Single-expression body
|
| int pos = position();
|
| parenthesized_function_ = false;
|
| - ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK);
|
| + ExpressionT expression =
|
| + ParseAssignmentExpression(true, classifier, CHECK_OK);
|
| body = this->NewStatementList(1, zone());
|
| body->Add(factory()->NewReturnStatement(expression, pos), zone());
|
| materialized_literal_count = function_state.materialized_literal_count();
|
| @@ -3435,7 +3534,9 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
|
|
|
| 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.
|
| @@ -3487,7 +3588,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, classifier, CHECK_OK);
|
| Traits::AddTemplateExpression(&ts, expression);
|
|
|
| if (peek() != Token::RBRACE) {
|
|
|