diff options
author | Ali Ijaz Sheikh <ofrobots@google.com> | 2016-04-07 14:06:55 -0700 |
---|---|---|
committer | Ali Ijaz Sheikh <ofrobots@google.com> | 2016-04-14 10:03:39 -0700 |
commit | 52af5c4eebf4de8638aef0338bd826656312a02a (patch) | |
tree | 628dc9fb0b558c3a73a2160706fef368876fe548 /deps/v8/src/parsing/parser-base.h | |
parent | 6e3e8acc7cc7ebd3d67db5ade1247b8b558efe09 (diff) | |
download | android-node-v8-52af5c4eebf4de8638aef0338bd826656312a02a.tar.gz android-node-v8-52af5c4eebf4de8638aef0338bd826656312a02a.tar.bz2 android-node-v8-52af5c4eebf4de8638aef0338bd826656312a02a.zip |
deps: upgrade V8 to 5.0.71.32
* Pick up the branch head for V8 5.0 stable [1]
* Edit v8 gitignore to allow trace_event copy
* Update V8 DEP trace_event as per deps/v8/DEPS [2]
[1] https://chromium.googlesource.com/v8/v8.git/+/3c67831
[2] https://chromium.googlesource.com/chromium/src/base/trace_event/common/+/4b09207e447ae5bd34643b4c6321bee7b76d35f9
Ref: https://github.com/nodejs/node/pull/5945
PR-URL: https://github.com/nodejs/node/pull/6111
Reviewed-By: targos - Michaƫl Zasso <mic.besace@gmail.com>
Reviewed-By: bnoordhuis - Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: indutny - Fedor Indutny <fedor.indutny@gmail.com>
Diffstat (limited to 'deps/v8/src/parsing/parser-base.h')
-rw-r--r-- | deps/v8/src/parsing/parser-base.h | 552 |
1 files changed, 276 insertions, 276 deletions
diff --git a/deps/v8/src/parsing/parser-base.h b/deps/v8/src/parsing/parser-base.h index d9da445977..6be19b397c 100644 --- a/deps/v8/src/parsing/parser-base.h +++ b/deps/v8/src/parsing/parser-base.h @@ -88,6 +88,7 @@ class ParserBase : public Traits { typedef typename Traits::Type::Literal LiteralT; typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; typedef typename Traits::Type::StatementList StatementListT; + typedef typename Traits::Type::ExpressionClassifier ExpressionClassifier; ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, v8::Extension* extension, AstValueFactory* ast_value_factory, @@ -116,7 +117,8 @@ class ParserBase : public Traits { allow_strong_mode_(false), allow_legacy_const_(true), allow_harmony_do_expressions_(false), - allow_harmony_function_name_(false) {} + allow_harmony_function_name_(false), + allow_harmony_function_sent_(false) {} #define ALLOW_ACCESSORS(name) \ bool allow_##name() const { return allow_##name##_; } \ @@ -134,6 +136,7 @@ class ParserBase : public Traits { ALLOW_ACCESSORS(legacy_const); ALLOW_ACCESSORS(harmony_do_expressions); ALLOW_ACCESSORS(harmony_function_name); + ALLOW_ACCESSORS(harmony_function_sent); #undef ALLOW_ACCESSORS uintptr_t stack_limit() const { return stack_limit_; } @@ -242,11 +245,37 @@ class ParserBase : public Traits { return destructuring_assignments_to_rewrite_; } + List<ExpressionT>& expressions_in_tail_position() { + return expressions_in_tail_position_; + } + void AddExpressionInTailPosition(ExpressionT expression) { + if (collect_expressions_in_tail_position_) { + expressions_in_tail_position_.Add(expression); + } + } + + bool collect_expressions_in_tail_position() const { + return collect_expressions_in_tail_position_; + } + void set_collect_expressions_in_tail_position(bool collect) { + collect_expressions_in_tail_position_ = collect; + } + + ZoneList<ExpressionT>* non_patterns_to_rewrite() { + return &non_patterns_to_rewrite_; + } + + private: void AddDestructuringAssignment(DestructuringAssignment pair) { destructuring_assignments_to_rewrite_.Add(pair); } - private: + V8_INLINE Scope* scope() { return *scope_stack_; } + + void AddNonPatternForRewriting(ExpressionT expr) { + non_patterns_to_rewrite_.Add(expr, (*scope_stack_)->zone()); + } + // Used to assign an index to each literal that needs materialization in // the function. Includes regexp literals, and boilerplate for object and // array literals. @@ -276,12 +305,14 @@ class ParserBase : public Traits { Scope* outer_scope_; List<DestructuringAssignment> destructuring_assignments_to_rewrite_; - - void RewriteDestructuringAssignments(); + List<ExpressionT> expressions_in_tail_position_; + bool collect_expressions_in_tail_position_; + ZoneList<ExpressionT> non_patterns_to_rewrite_; typename Traits::Type::Factory* factory_; friend class ParserTraits; + friend class PreParserTraits; friend class Checkpoint; }; @@ -436,6 +467,9 @@ class ParserBase : public Traits { scanner()->is_next_contextual_keyword(keyword); } + void ExpectMetaProperty(Vector<const char> property_name, + const char* full_name, int pos, bool* ok); + void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { Expect(Token::IDENTIFIER, ok); if (!*ok) return; @@ -461,6 +495,10 @@ class ParserBase : public Traits { return false; } + bool PeekInOrOf() { + return peek() == Token::IN || PeekContextualKeyword(CStrVector("of")); + } + // Checks whether an octal literal was last seen between beg_pos and end_pos. // If so, reports an error. Only called for strict mode and template strings. void CheckOctalLiteral(int beg_pos, int end_pos, @@ -563,8 +601,8 @@ class ParserBase : public Traits { Scanner::Location location, Token::Value token, MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); - - void ReportClassifierError(const ExpressionClassifier::Error& error) { + void ReportClassifierError( + const typename ExpressionClassifier::Error& error) { Traits::ReportMessageAt(error.location, error.message, error.arg, error.type); } @@ -642,7 +680,7 @@ class ParserBase : public Traits { // neither a valid binding pattern nor a valid parenthesized formal // parameter list, show the "arrow formal parameters" error if the formals // started with a parenthesis, and the binding pattern error otherwise. - const ExpressionClassifier::Error& error = + const typename ExpressionClassifier::Error& error = parenthesized_formals ? classifier->arrow_formal_parameters_error() : classifier->binding_pattern_error(); ReportClassifierError(error); @@ -715,10 +753,6 @@ class ParserBase : public Traits { } IdentifierT ParseIdentifierName(bool* ok); - // Parses an identifier and determines whether or not it is 'get' or 'set'. - IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, bool* is_set, - bool* ok); - ExpressionT ParseRegExpLiteral(bool seen_equal, ExpressionClassifier* classifier, bool* ok); @@ -728,12 +762,9 @@ class ParserBase : public Traits { ExpressionT ParseExpression(bool accept_IN, bool* ok); ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, bool* ok); - ExpressionT ParseExpression(bool accept_IN, int flags, - 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* is_identifier, bool* is_escaped_keyword, + bool* is_computed_name, ExpressionClassifier* classifier, bool* ok); ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); ObjectLiteralPropertyT ParsePropertyDefinition( @@ -744,21 +775,9 @@ class ParserBase : public Traits { Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, bool* ok); - enum AssignmentExpressionFlags { - kIsNormalAssignment = 0, - kIsPossiblePatternElement = 1 << 0, - kIsPossibleArrowFormals = 1 << 1 - }; - - ExpressionT ParseAssignmentExpression(bool accept_IN, int flags, - ExpressionClassifier* classifier, - bool* ok); ExpressionT ParseAssignmentExpression(bool accept_IN, ExpressionClassifier* classifier, - bool* ok) { - return ParseAssignmentExpression(accept_IN, kIsNormalAssignment, classifier, - ok); - } + bool* ok); ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); ExpressionT ParseConditionalExpression(bool accept_IN, ExpressionClassifier* classifier, @@ -794,9 +813,9 @@ class ParserBase : public Traits { ExpressionClassifier* classifier, bool* ok); void ParseFormalParameterList(FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok); - void CheckArityRestrictions( - int param_count, FunctionLiteral::ArityRestriction arity_restriction, - bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok); + void CheckArityRestrictions(int param_count, FunctionKind function_type, + bool has_rest, int formals_start_pos, + int formals_end_pos, bool* ok); bool IsNextLetKeyword(); @@ -829,6 +848,10 @@ class ParserBase : public Traits { return true; } + bool IsValidPattern(ExpressionT expression) { + return expression->IsObjectLiteral() || expression->IsArrayLiteral(); + } + // Keep track of eval() calls since they disable all local variable // optimizations. This checks if expression is an eval call, and if yes, // forwards the information to scope. @@ -932,9 +955,9 @@ class ParserBase : public Traits { bool allow_legacy_const_; bool allow_harmony_do_expressions_; bool allow_harmony_function_name_; + bool allow_harmony_function_sent_; }; - template <class Traits> ParserBase<Traits>::FunctionState::FunctionState( FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, @@ -950,6 +973,8 @@ ParserBase<Traits>::FunctionState::FunctionState( outer_function_state_(*function_state_stack), scope_stack_(scope_stack), outer_scope_(*scope_stack), + collect_expressions_in_tail_position_(true), + non_patterns_to_rewrite_(0, scope->zone()), factory_(factory) { *scope_stack_ = scope; *function_state_stack = this; @@ -967,7 +992,6 @@ template <class Traits> void ParserBase<Traits>::GetUnexpectedTokenMessage( Token::Value token, MessageTemplate::Template* message, const char** arg, MessageTemplate::Template default_) { - // Four of the tokens are treated specially switch (token) { case Token::EOS: *message = MessageTemplate::kUnexpectedEOS; @@ -1037,7 +1061,7 @@ void ParserBase<Traits>::ReportUnexpectedTokenAt( template <class Traits> typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { - ExpressionClassifier classifier; + ExpressionClassifier classifier(this); auto result = ParseAndClassifyIdentifier(&classifier, ok); if (!*ok) return Traits::EmptyIdentifier(); @@ -1091,10 +1115,8 @@ ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, scanner()->location(), MessageTemplate::kStrongUndefined); if (is_strong(language_mode())) { // TODO(dslomov): allow 'undefined' in nested patterns. - classifier->RecordBindingPatternError( - scanner()->location(), MessageTemplate::kStrongUndefined); - classifier->RecordAssignmentPatternError( - scanner()->location(), MessageTemplate::kStrongUndefined); + classifier->RecordPatternError(scanner()->location(), + MessageTemplate::kStrongUndefined); } } @@ -1116,7 +1138,9 @@ ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, *ok = false; return Traits::EmptyIdentifier(); } - if (next == Token::LET) { + if (next == Token::LET || + (next == Token::ESCAPED_STRICT_RESERVED_WORD && + scanner()->is_literal_contextual_keyword(CStrVector("let")))) { classifier->RecordLetPatternError(scanner()->location(), MessageTemplate::kLetInLexicalBinding); } @@ -1172,18 +1196,6 @@ ParserBase<Traits>::ParseIdentifierName(bool* ok) { template <class Traits> -typename ParserBase<Traits>::IdentifierT -ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get, - bool* is_set, - bool* ok) { - IdentifierT result = ParseIdentifierName(ok); - if (!*ok) return Traits::EmptyIdentifier(); - scanner()->IsGetOrSet(is_get, is_set); - return result; -} - - -template <class Traits> typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( bool seen_equal, ExpressionClassifier* classifier, bool* ok) { int pos = peek_position(); @@ -1269,8 +1281,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); case Token::SMI: case Token::NUMBER: - classifier->RecordBindingPatternError( - scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber); + BindingPatternUnexpectedToken(classifier); return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); case Token::IDENTIFIER: @@ -1286,8 +1297,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, } case Token::STRING: { - classifier->RecordBindingPatternError( - scanner()->peek_location(), MessageTemplate::kUnexpectedTokenString); + BindingPatternUnexpectedToken(classifier); Consume(Token::STRING); return this->ExpressionFromString(beg_pos, scanner(), factory()); } @@ -1323,7 +1333,9 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, if (!classifier->is_valid_binding_pattern()) { ArrowFormalParametersUnexpectedToken(classifier); } - BindingPatternUnexpectedToken(classifier); + classifier->RecordPatternError(scanner()->peek_location(), + MessageTemplate::kUnexpectedToken, + Token::String(Token::LPAREN)); Consume(Token::LPAREN); if (Check(Token::RPAREN)) { // ()=>x. The continuation that looks for the => is in @@ -1331,20 +1343,23 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, classifier->RecordExpressionError(scanner()->location(), MessageTemplate::kUnexpectedToken, Token::String(Token::RPAREN)); - classifier->RecordBindingPatternError(scanner()->location(), - MessageTemplate::kUnexpectedToken, - Token::String(Token::RPAREN)); return factory()->NewEmptyParentheses(beg_pos); } else if (Check(Token::ELLIPSIS)) { // (...x)=>x. The continuation that looks for the => is in // ParseAssignmentExpression. int ellipsis_pos = position(); + int expr_pos = peek_position(); classifier->RecordExpressionError(scanner()->location(), MessageTemplate::kUnexpectedToken, Token::String(Token::ELLIPSIS)); classifier->RecordNonSimpleParameter(); ExpressionT expr = this->ParseAssignmentExpression(true, classifier, CHECK_OK); + if (!this->IsIdentifier(expr) && !IsValidPattern(expr)) { + classifier->RecordArrowFormalParametersError( + Scanner::Location(ellipsis_pos, scanner()->location().end_pos), + MessageTemplate::kInvalidRestParameter); + } if (peek() == Token::COMMA) { ReportMessageAt(scanner()->peek_location(), MessageTemplate::kParamAfterRest); @@ -1352,17 +1367,13 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, return this->EmptyExpression(); } Expect(Token::RPAREN, CHECK_OK); - return factory()->NewSpread(expr, ellipsis_pos); + return factory()->NewSpread(expr, ellipsis_pos, expr_pos); } // Heuristically try to detect immediately called functions before // seeing the call parentheses. parenthesized_function_ = (peek() == Token::FUNCTION); - ExpressionT expr = this->ParseExpression(true, kIsPossibleArrowFormals, - classifier, CHECK_OK); + ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK); Expect(Token::RPAREN, CHECK_OK); - if (peek() != Token::ARROW) { - expr->set_is_parenthesized(); - } return expr; } @@ -1390,9 +1401,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, case Token::TEMPLATE_SPAN: case Token::TEMPLATE_TAIL: - classifier->RecordBindingPatternError( - scanner()->peek_location(), - MessageTemplate::kUnexpectedTemplateString); + BindingPatternUnexpectedToken(classifier); return this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, classifier, ok); @@ -1423,9 +1432,9 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, template <class Traits> typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( bool accept_IN, bool* ok) { - ExpressionClassifier classifier; + ExpressionClassifier classifier(this); ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); - result = Traits::RewriteNonPattern(result, &classifier, CHECK_OK); + Traits::RewriteNonPattern(&classifier, CHECK_OK); return result; } @@ -1433,21 +1442,14 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( template <class Traits> typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( bool accept_IN, ExpressionClassifier* classifier, bool* ok) { - return ParseExpression(accept_IN, kIsNormalAssignment, classifier, ok); -} - - -template <class Traits> -typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( - bool accept_IN, int flags, ExpressionClassifier* classifier, bool* ok) { // Expression :: // AssignmentExpression // Expression ',' AssignmentExpression - ExpressionClassifier binding_classifier; - ExpressionT result = this->ParseAssignmentExpression( - accept_IN, flags, &binding_classifier, CHECK_OK); - classifier->Accumulate(binding_classifier, + ExpressionClassifier binding_classifier(this); + ExpressionT result = + this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); + classifier->Accumulate(&binding_classifier, ExpressionClassifier::AllProductions); bool is_simple_parameter_list = this->IsIdentifier(result); bool seen_rest = false; @@ -1469,14 +1471,21 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( Consume(Token::ELLIPSIS); seen_rest = is_rest = true; } - int pos = position(); + int pos = position(), expr_pos = peek_position(); ExpressionT right = this->ParseAssignmentExpression( - accept_IN, flags, &binding_classifier, CHECK_OK); - if (is_rest) right = factory()->NewSpread(right, pos); + accept_IN, &binding_classifier, CHECK_OK); + classifier->Accumulate(&binding_classifier, + ExpressionClassifier::AllProductions); + if (is_rest) { + if (!this->IsIdentifier(right) && !IsValidPattern(right)) { + classifier->RecordArrowFormalParametersError( + Scanner::Location(pos, scanner()->location().end_pos), + MessageTemplate::kInvalidRestParameter); + } + right = factory()->NewSpread(right, pos, expr_pos); + } is_simple_parameter_list = is_simple_parameter_list && this->IsIdentifier(right); - classifier->Accumulate(binding_classifier, - ExpressionClassifier::AllProductions); result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); } if (!is_simple_parameter_list || seen_rest) { @@ -1511,9 +1520,10 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( } else if (peek() == Token::ELLIPSIS) { int start_pos = peek_position(); Consume(Token::ELLIPSIS); + int expr_pos = peek_position(); ExpressionT argument = this->ParseAssignmentExpression(true, classifier, CHECK_OK); - elem = factory()->NewSpread(argument, start_pos); + elem = factory()->NewSpread(argument, start_pos, expr_pos); if (first_spread_index < 0) { first_spread_index = values->length(); @@ -1534,8 +1544,10 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( MessageTemplate::kElementAfterRest); } } else { - elem = this->ParseAssignmentExpression(true, kIsPossiblePatternElement, - classifier, CHECK_OK); + int beg_pos = peek_position(); + elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); + CheckDestructuringElement(elem, classifier, beg_pos, + scanner()->location().end_pos); } values->Add(elem, zone_); if (peek() != Token::RBRACK) { @@ -1547,15 +1559,20 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( // Update the scope information before the pre-parsing bailout. int literal_index = function_state_->NextMaterializedLiteralIndex(); - return factory()->NewArrayLiteral(values, first_spread_index, literal_index, - is_strong(language_mode()), pos); + ExpressionT result = + factory()->NewArrayLiteral(values, first_spread_index, literal_index, + is_strong(language_mode()), pos); + if (first_spread_index >= 0) { + result = factory()->NewRewritableExpression(result); + Traits::QueueNonPatternForRewriting(result); + } + return result; } 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* is_identifier, bool* is_escaped_keyword, + IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) { Token::Value token = peek(); int pos = peek_position(); @@ -1588,29 +1605,19 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( case Token::LBRACK: { *is_computed_name = true; Consume(Token::LBRACK); - ExpressionClassifier computed_name_classifier; + ExpressionClassifier computed_name_classifier(this); ExpressionT expression = ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); - expression = Traits::RewriteNonPattern( - expression, &computed_name_classifier, CHECK_OK); - classifier->Accumulate(computed_name_classifier, + Traits::RewriteNonPattern(&computed_name_classifier, CHECK_OK); + classifier->Accumulate(&computed_name_classifier, ExpressionClassifier::ExpressionProductions); Expect(Token::RBRACK, CHECK_OK); return expression; } - case Token::ESCAPED_KEYWORD: - *is_escaped_keyword = true; - *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); - break; - - case Token::STATIC: - *is_static = true; - - // Fall through. default: - *is_identifier = true; - *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); + *name = ParseIdentifierName(CHECK_OK); + scanner()->IsGetOrSet(is_get, is_set); break; } @@ -1631,27 +1638,19 @@ ParserBase<Traits>::ParsePropertyDefinition( ExpressionT value = this->EmptyExpression(); bool is_get = false; bool is_set = false; - bool name_is_static = false; bool is_generator = Check(Token::MUL); Token::Value name_token = peek(); int next_beg_pos = scanner()->peek_location().beg_pos; int next_end_pos = scanner()->peek_location().end_pos; - bool is_identifier = false; - bool is_escaped_keyword = false; - ExpressionT name_expression = ParsePropertyName( - name, &is_get, &is_set, &name_is_static, is_computed_name, &is_identifier, - &is_escaped_keyword, classifier, - CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); + ExpressionT name_expression = + ParsePropertyName(name, &is_get, &is_set, is_computed_name, classifier, + CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); if (fni_ != nullptr && !*is_computed_name) { this->PushLiteralName(fni_, *name); } - bool escaped_static = - is_escaped_keyword && - scanner()->is_literal_contextual_keyword(CStrVector("static")); - if (!in_class && !is_generator) { DCHECK(!is_static); @@ -1663,15 +1662,18 @@ ParserBase<Traits>::ParsePropertyDefinition( CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); } Consume(Token::COLON); + int beg_pos = peek_position(); value = this->ParseAssignmentExpression( - true, kIsPossiblePatternElement, classifier, - CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); + true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); + CheckDestructuringElement(value, classifier, beg_pos, + scanner()->location().end_pos); return factory()->NewObjectLiteralProperty(name_expression, value, false, *is_computed_name); } - if ((is_identifier || is_escaped_keyword) && + if (Token::IsIdentifier(name_token, language_mode(), + this->is_generator()) && (peek() == Token::COMMA || peek() == Token::RBRACE || peek() == Token::ASSIGN)) { // PropertyDefinition @@ -1680,14 +1682,6 @@ ParserBase<Traits>::ParsePropertyDefinition( // // CoverInitializedName // IdentifierReference Initializer? - if (!Token::IsIdentifier(name_token, language_mode(), - this->is_generator())) { - if (!escaped_static) { - ReportUnexpectedTokenAt(scanner()->location(), name_token); - *ok = false; - return this->EmptyObjectLiteralProperty(); - } - } if (classifier->duplicate_finder() != nullptr && scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { classifier->RecordDuplicateFormalParameterError(scanner()->location()); @@ -1703,18 +1697,22 @@ ParserBase<Traits>::ParsePropertyDefinition( if (peek() == Token::ASSIGN) { Consume(Token::ASSIGN); - ExpressionClassifier rhs_classifier; + ExpressionClassifier rhs_classifier(this); ExpressionT rhs = this->ParseAssignmentExpression( true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); - rhs = Traits::RewriteNonPattern( - rhs, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); - classifier->Accumulate(rhs_classifier, + Traits::RewriteNonPattern(&rhs_classifier, + CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); + classifier->Accumulate(&rhs_classifier, ExpressionClassifier::ExpressionProductions); value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, RelocInfo::kNoPosition); classifier->RecordCoverInitializedNameError( Scanner::Location(next_beg_pos, scanner()->location().end_pos), MessageTemplate::kInvalidCoverInitializedName); + + if (allow_harmony_function_name()) { + Traits::SetFunctionNameFromIdentifierRef(rhs, lhs); + } } else { value = lhs; } @@ -1725,12 +1723,6 @@ ParserBase<Traits>::ParsePropertyDefinition( } } - if (in_class && escaped_static && !is_static) { - ReportUnexpectedTokenAt(scanner()->location(), name_token); - *ok = false; - return this->EmptyObjectLiteralProperty(); - } - // Method definitions are never valid in patterns. classifier->RecordPatternError( Scanner::Location(next_beg_pos, scanner()->location().end_pos), @@ -1755,28 +1747,24 @@ ParserBase<Traits>::ParsePropertyDefinition( : FunctionKind::kBaseConstructor; } - if (!in_class) kind = WithObjectLiteralBit(kind); - value = this->ParseFunctionLiteral( *name, scanner()->location(), kSkipFunctionNameCheck, kind, - RelocInfo::kNoPosition, FunctionLiteral::kAnonymousExpression, - FunctionLiteral::kNormalArity, language_mode(), - CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); + RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod, + language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); return factory()->NewObjectLiteralProperty(name_expression, value, ObjectLiteralProperty::COMPUTED, is_static, *is_computed_name); } - if (in_class && name_is_static && !is_static) { + if (in_class && name_token == Token::STATIC && !is_static) { // ClassElement (static) // 'static' MethodDefinition *name = this->EmptyIdentifier(); ObjectLiteralPropertyT property = ParsePropertyDefinition( checker, true, has_extends, true, is_computed_name, nullptr, classifier, name, ok); - property = Traits::RewriteNonPatternObjectLiteralProperty(property, - classifier, ok); + Traits::RewriteNonPattern(classifier, ok); return property; } @@ -1789,8 +1777,8 @@ ParserBase<Traits>::ParsePropertyDefinition( name_token = peek(); name_expression = ParsePropertyName( - name, &dont_care, &dont_care, &dont_care, is_computed_name, &dont_care, - &dont_care, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); + name, &dont_care, &dont_care, is_computed_name, classifier, + CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); if (!*is_computed_name) { checker->CheckProperty(name_token, kAccessorProperty, is_static, @@ -1798,12 +1786,10 @@ ParserBase<Traits>::ParsePropertyDefinition( CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); } - FunctionKind kind = FunctionKind::kAccessorFunction; - if (!in_class) kind = WithObjectLiteralBit(kind); typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( - *name, scanner()->location(), kSkipFunctionNameCheck, kind, - RelocInfo::kNoPosition, FunctionLiteral::kAnonymousExpression, - is_get ? FunctionLiteral::kGetterArity : FunctionLiteral::kSetterArity, + *name, scanner()->location(), kSkipFunctionNameCheck, + is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction, + RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod, language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); // Make sure the name expression is a string since we need a Name for @@ -1913,17 +1899,17 @@ typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( while (!done) { int start_pos = peek_position(); bool is_spread = Check(Token::ELLIPSIS); + int expr_pos = peek_position(); ExpressionT argument = this->ParseAssignmentExpression( true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); - argument = Traits::RewriteNonPattern(argument, classifier, - CHECK_OK_CUSTOM(NullExpressionList)); + Traits::RewriteNonPattern(classifier, CHECK_OK_CUSTOM(NullExpressionList)); if (is_spread) { if (!spread_arg.IsValid()) { spread_arg.beg_pos = start_pos; spread_arg.end_pos = peek_position(); } - argument = factory()->NewSpread(argument, start_pos); + argument = factory()->NewSpread(argument, start_pos, expr_pos); } result->Add(argument, zone_); @@ -1967,7 +1953,7 @@ typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( // Precedence = 2 template <class Traits> typename ParserBase<Traits>::ExpressionT -ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, +ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, ExpressionClassifier* classifier, bool* ok) { // AssignmentExpression :: @@ -1975,8 +1961,6 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, // ArrowFunction // YieldExpression // LeftHandSideExpression AssignmentOperator AssignmentExpression - bool maybe_pattern_element = flags & kIsPossiblePatternElement; - bool maybe_arrow_formals = flags & kIsPossibleArrowFormals; bool is_destructuring_assignment = false; int lhs_beg_pos = peek_position(); @@ -1986,7 +1970,8 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, FuncNameInferrer::State fni_state(fni_); ParserBase<Traits>::Checkpoint checkpoint(this); - ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder()); + ExpressionClassifier arrow_formals_classifier(this, + classifier->duplicate_finder()); bool parenthesized_formals = peek() == Token::LPAREN; if (!parenthesized_formals) { ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); @@ -1994,7 +1979,9 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, ExpressionT expression = this->ParseConditionalExpression( accept_IN, &arrow_formals_classifier, CHECK_OK); if (peek() == Token::ARROW) { - BindingPatternUnexpectedToken(classifier); + classifier->RecordPatternError(scanner()->peek_location(), + MessageTemplate::kUnexpectedToken, + Token::String(Token::ARROW)); ValidateArrowFormalParameters(&arrow_formals_classifier, expression, parenthesized_formals, CHECK_OK); Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); @@ -2022,11 +2009,6 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, } expression = this->ParseArrowFunctionLiteral( accept_IN, parameters, arrow_formals_classifier, CHECK_OK); - if (maybe_pattern_element) { - classifier->RecordPatternError( - Scanner::Location(lhs_beg_pos, scanner()->location().end_pos), - MessageTemplate::kInvalidDestructuringTarget); - } if (fni_ != nullptr) fni_->Infer(); @@ -2039,44 +2021,42 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, // "expression" was not itself an arrow function parameter list, but it might // form part of one. Propagate speculative formal parameter error locations. + // Do not merge pending non-pattern expressions yet! classifier->Accumulate( - arrow_formals_classifier, + &arrow_formals_classifier, ExpressionClassifier::StandardProductions | - ExpressionClassifier::FormalParametersProductions | - ExpressionClassifier::CoverInitializedNameProduction); - - bool maybe_pattern = - (expression->IsObjectLiteral() || expression->IsArrayLiteral()) && - !expression->is_parenthesized(); + ExpressionClassifier::FormalParametersProductions | + ExpressionClassifier::CoverInitializedNameProduction, + false); if (!Token::IsAssignmentOp(peek())) { // Parsed conditional expression only (no assignment). - if (maybe_pattern_element) { - CheckDestructuringElement(expression, classifier, lhs_beg_pos, - scanner()->location().end_pos); - } + // Now pending non-pattern expressions must be merged. + classifier->MergeNonPatterns(&arrow_formals_classifier); return expression; } + // Now pending non-pattern expressions must be discarded. + arrow_formals_classifier.Discard(); + if (!(allow_harmony_destructuring_bind() || allow_harmony_default_parameters())) { BindingPatternUnexpectedToken(classifier); } - if (allow_harmony_destructuring_assignment() && maybe_pattern && + if (allow_harmony_destructuring_assignment() && IsValidPattern(expression) && peek() == Token::ASSIGN) { classifier->ForgiveCoverInitializedNameError(); ValidateAssignmentPattern(classifier, CHECK_OK); is_destructuring_assignment = true; - } else if (maybe_arrow_formals) { + } else if (allow_harmony_default_parameters() && + !allow_harmony_destructuring_assignment()) { + // TODO(adamk): This branch should be removed once the destructuring + // assignment and default parameter flags are removed. expression = this->ClassifyAndRewriteReferenceExpression( classifier, expression, lhs_beg_pos, scanner()->location().end_pos, MessageTemplate::kInvalidLhsInAssignment); } else { - if (maybe_pattern_element) { - CheckDestructuringElement(expression, classifier, lhs_beg_pos, - scanner()->location().end_pos); - } expression = this->CheckAndRewriteReferenceExpression( expression, lhs_beg_pos, scanner()->location().end_pos, MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); @@ -2086,20 +2066,20 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, Token::Value op = Next(); // Get assignment operator. if (op != Token::ASSIGN) { - classifier->RecordBindingPatternError(scanner()->location(), - MessageTemplate::kUnexpectedToken, - Token::String(op)); + classifier->RecordPatternError(scanner()->location(), + MessageTemplate::kUnexpectedToken, + Token::String(op)); } int pos = position(); - ExpressionClassifier rhs_classifier; + ExpressionClassifier rhs_classifier(this); ExpressionT right = this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); - right = Traits::RewriteNonPattern(right, &rhs_classifier, CHECK_OK); + Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK); classifier->Accumulate( - rhs_classifier, ExpressionClassifier::ExpressionProductions | - ExpressionClassifier::CoverInitializedNameProduction); + &rhs_classifier, ExpressionClassifier::ExpressionProductions | + ExpressionClassifier::CoverInitializedNameProduction); // TODO(1231235): We try to estimate the set of properties set by // constructors. We define a new property whenever there is an @@ -2110,12 +2090,6 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, function_state_->AddProperty(); } - if (op != Token::ASSIGN && maybe_pattern_element) { - classifier->RecordAssignmentPatternError( - Scanner::Location(lhs_beg_pos, scanner()->location().end_pos), - MessageTemplate::kInvalidDestructuringTarget); - } - this->CheckAssigningFunctionLiteralToProperty(expression, right); if (fni_ != NULL) { @@ -2137,7 +2111,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, ExpressionT result = factory()->NewAssignment(op, expression, right, pos); if (is_destructuring_assignment) { - result = factory()->NewRewritableAssignmentExpression(result); + result = factory()->NewRewritableExpression(result); Traits::QueueDestructuringAssignmentForRewriting(result); } @@ -2179,16 +2153,12 @@ ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, // Delegating yields require an RHS; fall through. default: expression = ParseAssignmentExpression(false, classifier, CHECK_OK); - expression = - Traits::RewriteNonPattern(expression, classifier, CHECK_OK); + Traits::RewriteNonPattern(classifier, CHECK_OK); break; } } if (kind == Yield::kDelegating) { - // var iterator = subject[Symbol.iterator](); - // Hackily disambiguate o from o.next and o [Symbol.iterator](). - // TODO(verwaest): Come up with a better solution. - expression = this->GetIterator(expression, factory(), pos + 1); + return Traits::RewriteYieldStar(generator_object, expression, pos); } // Hackily disambiguate o from o.next and o [Symbol.iterator](). // TODO(verwaest): Come up with a better solution. @@ -2213,7 +2183,7 @@ ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, ExpressionT expression = this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); if (peek() != Token::CONDITIONAL) return expression; - expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK); + Traits::RewriteNonPattern(classifier, CHECK_OK); ArrowFormalParametersUnexpectedToken(classifier); BindingPatternUnexpectedToken(classifier); Consume(Token::CONDITIONAL); @@ -2221,11 +2191,11 @@ ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, // expressions we always accept the 'in' keyword; see ECMA-262, // section 11.12, page 58. ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); - left = Traits::RewriteNonPattern(left, classifier, CHECK_OK); + Traits::RewriteNonPattern(classifier, CHECK_OK); Expect(Token::COLON, CHECK_OK); ExpressionT right = ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); - right = Traits::RewriteNonPattern(right, classifier, CHECK_OK); + Traits::RewriteNonPattern(classifier, CHECK_OK); return factory()->NewConditional(expression, left, right, pos); } @@ -2241,7 +2211,7 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { // prec1 >= 4 while (Precedence(peek(), accept_IN) == prec1) { - x = Traits::RewriteNonPattern(x, classifier, CHECK_OK); + Traits::RewriteNonPattern(classifier, CHECK_OK); BindingPatternUnexpectedToken(classifier); ArrowFormalParametersUnexpectedToken(classifier); Token::Value op = Next(); @@ -2249,7 +2219,7 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, int pos = position(); ExpressionT y = ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK); - y = Traits::RewriteNonPattern(y, classifier, CHECK_OK); + Traits::RewriteNonPattern(classifier, CHECK_OK); if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, factory())) { @@ -2271,13 +2241,15 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, ReportMessageAt(op_location, MessageTemplate::kStrongEqual); *ok = false; return this->EmptyExpression(); + } else if (FLAG_harmony_instanceof && cmp == Token::INSTANCEOF) { + x = Traits::RewriteInstanceof(x, y, pos); + } else { + x = factory()->NewCompareOperation(cmp, x, y, pos); + if (cmp != op) { + // The comparison was negated - add a NOT. + x = factory()->NewUnaryOperation(Token::NOT, x, pos); + } } - x = factory()->NewCompareOperation(cmp, x, y, pos); - if (cmp != op) { - // The comparison was negated - add a NOT. - x = factory()->NewUnaryOperation(Token::NOT, x, pos); - } - } else { // We have a "normal" binary operation. x = factory()->NewBinaryOperation(op, x, y, pos); @@ -2312,7 +2284,7 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier, op = Next(); int pos = position(); ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); - expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK); + Traits::RewriteNonPattern(classifier, CHECK_OK); if (op == Token::DELETE && is_strict(language_mode())) { if (is_strong(language_mode())) { @@ -2339,7 +2311,7 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier, expression, beg_pos, scanner()->location().end_pos, MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); this->MarkExpressionAsAssigned(expression); - expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK); + Traits::RewriteNonPattern(classifier, CHECK_OK); return factory()->NewCountOperation(op, true /* prefix */, @@ -2371,7 +2343,7 @@ ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, expression, lhs_beg_pos, scanner()->location().end_pos, MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); expression = this->MarkExpressionAsAssigned(expression); - expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK); + Traits::RewriteNonPattern(classifier, CHECK_OK); Token::Value next = Next(); expression = @@ -2397,19 +2369,20 @@ ParserBase<Traits>::ParseLeftHandSideExpression( while (true) { switch (peek()) { case Token::LBRACK: { + Traits::RewriteNonPattern(classifier, CHECK_OK); BindingPatternUnexpectedToken(classifier); ArrowFormalParametersUnexpectedToken(classifier); Consume(Token::LBRACK); int pos = position(); ExpressionT index = ParseExpression(true, classifier, CHECK_OK); - index = Traits::RewriteNonPattern(index, classifier, CHECK_OK); + Traits::RewriteNonPattern(classifier, CHECK_OK); result = factory()->NewProperty(result, index, pos); Expect(Token::RBRACK, CHECK_OK); break; } case Token::LPAREN: { - result = Traits::RewriteNonPattern(result, classifier, CHECK_OK); + Traits::RewriteNonPattern(classifier, CHECK_OK); BindingPatternUnexpectedToken(classifier); ArrowFormalParametersUnexpectedToken(classifier); @@ -2473,6 +2446,7 @@ ParserBase<Traits>::ParseLeftHandSideExpression( } case Token::PERIOD: { + Traits::RewriteNonPattern(classifier, CHECK_OK); BindingPatternUnexpectedToken(classifier); ArrowFormalParametersUnexpectedToken(classifier); Consume(Token::PERIOD); @@ -2486,6 +2460,7 @@ ParserBase<Traits>::ParseLeftHandSideExpression( case Token::TEMPLATE_SPAN: case Token::TEMPLATE_TAIL: { + Traits::RewriteNonPattern(classifier, CHECK_OK); BindingPatternUnexpectedToken(classifier); ArrowFormalParametersUnexpectedToken(classifier); result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); @@ -2537,7 +2512,7 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( } else { result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); } - result = Traits::RewriteNonPattern(result, classifier, CHECK_OK); + Traits::RewriteNonPattern(classifier, CHECK_OK); if (peek() == Token::LPAREN) { // NewExpression with arguments. Scanner::Location spread_pos; @@ -2584,6 +2559,23 @@ ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, Consume(Token::FUNCTION); int function_token_position = position(); + + if (allow_harmony_function_sent() && peek() == Token::PERIOD) { + // function.sent + int pos = position(); + ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK); + + if (!is_generator()) { + // TODO(neis): allow escaping into closures? + ReportMessageAt(scanner()->location(), + MessageTemplate::kUnexpectedFunctionSent); + *ok = false; + return this->EmptyExpression(); + } + + return this->FunctionSentExpression(scope_, factory(), pos); + } + bool is_generator = Check(Token::MUL); IdentifierT name = this->EmptyIdentifier(); bool is_strict_reserved_name = false; @@ -2602,8 +2594,7 @@ ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, : kFunctionNameValidityUnknown, is_generator ? FunctionKind::kGeneratorFunction : FunctionKind::kNormalFunction, - function_token_position, function_type, FunctionLiteral::kNormalArity, - language_mode(), CHECK_OK); + function_token_position, function_type, language_mode(), CHECK_OK); } else if (peek() == Token::SUPER) { const bool is_new = false; result = ParseSuperExpression(is_new, classifier, CHECK_OK); @@ -2637,7 +2628,7 @@ ParserBase<Traits>::ParseStrongInitializationExpression( Consume(Token::LBRACK); int pos = position(); ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); - index = Traits::RewriteNonPattern(index, classifier, CHECK_OK); + Traits::RewriteNonPattern(classifier, CHECK_OK); left = factory()->NewProperty(this_expr, index, pos); if (fni_ != NULL) { this->PushPropertyName(fni_, index); @@ -2673,7 +2664,7 @@ ParserBase<Traits>::ParseStrongInitializationExpression( ExpressionT right = this->ParseAssignmentExpression(true, classifier, CHECK_OK); - right = Traits::RewriteNonPattern(right, classifier, CHECK_OK); + Traits::RewriteNonPattern(classifier, CHECK_OK); this->CheckAssigningFunctionLiteralToProperty(left, right); function_state_->AddProperty(); if (fni_ != NULL) { @@ -2796,13 +2787,26 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new, return this->EmptyExpression(); } +template <class Traits> +void ParserBase<Traits>::ExpectMetaProperty(Vector<const char> property_name, + const char* full_name, int pos, + bool* ok) { + Consume(Token::PERIOD); + ExpectContextualKeyword(property_name, ok); + if (!*ok) return; + if (scanner()->literal_contains_escapes()) { + Traits::ReportMessageAt( + Scanner::Location(pos, scanner()->location().end_pos), + MessageTemplate::kInvalidEscapedMetaProperty, full_name); + *ok = false; + } +} template <class Traits> typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseNewTargetExpression(bool* ok) { int pos = position(); - Consume(Token::PERIOD); - ExpectContextualKeyword(CStrVector("target"), CHECK_OK); + ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK); if (!scope_->ReceiverScope()->is_function_scope()) { ReportMessageAt(scanner()->location(), @@ -2824,13 +2828,14 @@ ParserBase<Traits>::ParseMemberExpressionContinuation( while (true) { switch (peek()) { case Token::LBRACK: { + Traits::RewriteNonPattern(classifier, CHECK_OK); BindingPatternUnexpectedToken(classifier); ArrowFormalParametersUnexpectedToken(classifier); Consume(Token::LBRACK); int pos = position(); ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); - index = Traits::RewriteNonPattern(index, classifier, CHECK_OK); + Traits::RewriteNonPattern(classifier, CHECK_OK); expression = factory()->NewProperty(expression, index, pos); if (fni_ != NULL) { this->PushPropertyName(fni_, index); @@ -2839,6 +2844,7 @@ ParserBase<Traits>::ParseMemberExpressionContinuation( break; } case Token::PERIOD: { + Traits::RewriteNonPattern(classifier, CHECK_OK); BindingPatternUnexpectedToken(classifier); ArrowFormalParametersUnexpectedToken(classifier); @@ -2854,6 +2860,7 @@ ParserBase<Traits>::ParseMemberExpressionContinuation( } case Token::TEMPLATE_SPAN: case Token::TEMPLATE_TAIL: { + Traits::RewriteNonPattern(classifier, CHECK_OK); BindingPatternUnexpectedToken(classifier); ArrowFormalParametersUnexpectedToken(classifier); int pos; @@ -2908,14 +2915,19 @@ void ParserBase<Traits>::ParseFormalParameter( ExpressionT initializer = Traits::EmptyExpression(); if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) { - ExpressionClassifier init_classifier; + ExpressionClassifier init_classifier(this); initializer = ParseAssignmentExpression(true, &init_classifier, ok); if (!*ok) return; - initializer = Traits::RewriteNonPattern(initializer, &init_classifier, ok); + Traits::RewriteNonPattern(&init_classifier, ok); ValidateFormalParameterInitializer(&init_classifier, ok); if (!*ok) return; parameters->is_simple = false; + init_classifier.Discard(); classifier->RecordNonSimpleParameter(); + + if (allow_harmony_function_name()) { + Traits::SetFunctionNameFromIdentifierRef(initializer, pattern); + } } Traits::AddFormalParameter(parameters, pattern, initializer, @@ -2972,33 +2984,29 @@ void ParserBase<Traits>::ParseFormalParameterList( } } - template <class Traits> -void ParserBase<Traits>::CheckArityRestrictions( - int param_count, FunctionLiteral::ArityRestriction arity_restriction, - bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok) { - switch (arity_restriction) { - case FunctionLiteral::kGetterArity: - if (param_count != 0) { - ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), - MessageTemplate::kBadGetterArity); - *ok = false; - } - break; - case FunctionLiteral::kSetterArity: - if (param_count != 1) { - ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), - MessageTemplate::kBadSetterArity); - *ok = false; - } - if (has_rest) { - ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), - MessageTemplate::kBadSetterRestParameter); - *ok = false; - } - break; - default: - break; +void ParserBase<Traits>::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), + MessageTemplate::kBadGetterArity); + *ok = false; + } + } else if (IsSetterFunction(function_kind)) { + if (param_count != 1) { + ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), + MessageTemplate::kBadSetterArity); + *ok = false; + } + if (has_rest) { + ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), + MessageTemplate::kBadSetterRestParameter); + *ok = false; + } } } @@ -3082,10 +3090,10 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( // Single-expression body int pos = position(); parenthesized_function_ = false; - ExpressionClassifier classifier; + ExpressionClassifier classifier(this); ExpressionT expression = ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); - expression = Traits::RewriteNonPattern(expression, &classifier, CHECK_OK); + Traits::RewriteNonPattern(&classifier, CHECK_OK); body = this->NewStatementList(1, zone()); this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); body->Add(factory()->NewReturnStatement(expression, pos), zone()); @@ -3191,7 +3199,7 @@ ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, int expr_pos = peek_position(); ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); - expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK); + Traits::RewriteNonPattern(classifier, CHECK_OK); Traits::AddTemplateExpression(&ts, expression); if (peek() != Token::RBRACE) { @@ -3245,7 +3253,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::CheckAndRewriteReferenceExpression( ExpressionT expression, int beg_pos, int end_pos, MessageTemplate::Template message, ParseErrorType type, bool* ok) { - ExpressionClassifier classifier; + ExpressionClassifier classifier(this); ExpressionT result = ClassifyAndRewriteReferenceExpression( &classifier, expression, beg_pos, end_pos, message, type); ValidateExpression(&classifier, ok); @@ -3299,21 +3307,11 @@ template <typename Traits> void ParserBase<Traits>::CheckDestructuringElement( ExpressionT expression, ExpressionClassifier* classifier, int begin, int end) { - static const MessageTemplate::Template message = - MessageTemplate::kInvalidDestructuringTarget; - const Scanner::Location location(begin, end); - if (expression->IsArrayLiteral() || expression->IsObjectLiteral() || - expression->IsAssignment()) { - if (expression->is_parenthesized()) { - classifier->RecordPatternError(location, message); - } - return; - } - - if (expression->IsProperty()) { - classifier->RecordBindingPatternError(location, message); - } else if (!this->IsAssignableIdentifier(expression)) { - classifier->RecordPatternError(location, message); + if (!IsValidPattern(expression) && !expression->IsAssignment() && + !IsValidReferenceExpression(expression)) { + classifier->RecordAssignmentPatternError( + Scanner::Location(begin, end), + MessageTemplate::kInvalidDestructuringTarget); } } @@ -3375,6 +3373,8 @@ void ParserBase<Traits>::ClassLiteralChecker::CheckProperty( return; } } + + } // namespace internal } // namespace v8 |