| Index: src/preparser.h
|
| diff --git a/src/preparser.h b/src/preparser.h
|
| index bb4ac8c951065280233726559b0a1e4eb70a697d..0440d831eea5105552c2c268534faead9ff44f0e 100644
|
| --- a/src/preparser.h
|
| +++ b/src/preparser.h
|
| @@ -17,26 +17,6 @@
|
| namespace v8 {
|
| namespace internal {
|
|
|
| -
|
| -// When parsing the formal parameters of a function, we usually don't yet know
|
| -// if the function will be strict, so we cannot yet produce errors for
|
| -// parameter names or duplicates. Instead, we remember the locations of these
|
| -// errors if they occur and produce the errors later.
|
| -class FormalParameterErrorLocations BASE_EMBEDDED {
|
| - public:
|
| - FormalParameterErrorLocations()
|
| - : eval_or_arguments(Scanner::Location::invalid()),
|
| - undefined(Scanner::Location::invalid()),
|
| - duplicate(Scanner::Location::invalid()),
|
| - reserved(Scanner::Location::invalid()) {}
|
| -
|
| - Scanner::Location eval_or_arguments;
|
| - Scanner::Location undefined;
|
| - Scanner::Location duplicate;
|
| - Scanner::Location reserved;
|
| -};
|
| -
|
| -
|
| // Common base class shared between parser and pre-parser. Traits encapsulate
|
| // the differences between Parser and PreParser:
|
|
|
| @@ -71,8 +51,6 @@ class FormalParameterErrorLocations BASE_EMBEDDED {
|
| // typedef Literal;
|
| // typedef ExpressionList;
|
| // typedef PropertyList;
|
| -// typedef FormalParameter;
|
| -// typedef FormalParameterList;
|
| // // For constructing objects returned by the traversing functions.
|
| // typedef Factory;
|
| // };
|
| @@ -85,8 +63,6 @@ class ParserBase : public Traits {
|
| // Shorten type names defined by Traits.
|
| typedef typename Traits::Type::Expression ExpressionT;
|
| typedef typename Traits::Type::Identifier IdentifierT;
|
| - typedef typename Traits::Type::FormalParameter FormalParameterT;
|
| - typedef typename Traits::Type::FormalParameterList FormalParameterListT;
|
| typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
|
| typedef typename Traits::Type::Literal LiteralT;
|
| typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
|
| @@ -519,28 +495,31 @@ class ParserBase : public Traits {
|
| // after parsing the function, since the function can declare itself strict.
|
| void CheckFunctionParameterNames(LanguageMode language_mode,
|
| bool strict_params,
|
| - const FormalParameterErrorLocations& locs,
|
| + const Scanner::Location& eval_args_loc,
|
| + const Scanner::Location& undefined_loc,
|
| + const Scanner::Location& dupe_loc,
|
| + const Scanner::Location& reserved_loc,
|
| bool* ok) {
|
| if (is_sloppy(language_mode) && !strict_params) return;
|
| - if (is_strict(language_mode) && locs.eval_or_arguments.IsValid()) {
|
| - Traits::ReportMessageAt(locs.eval_or_arguments, "strict_eval_arguments");
|
| + if (is_strict(language_mode) && eval_args_loc.IsValid()) {
|
| + Traits::ReportMessageAt(eval_args_loc, "strict_eval_arguments");
|
| *ok = false;
|
| return;
|
| }
|
| - if (is_strict(language_mode) && locs.reserved.IsValid()) {
|
| - Traits::ReportMessageAt(locs.reserved, "unexpected_strict_reserved");
|
| + if (is_strong(language_mode) && undefined_loc.IsValid()) {
|
| + Traits::ReportMessageAt(undefined_loc, "strong_undefined");
|
| *ok = false;
|
| return;
|
| }
|
| - if (is_strong(language_mode) && locs.undefined.IsValid()) {
|
| - Traits::ReportMessageAt(locs.undefined, "strong_undefined");
|
| + // TODO(arv): When we add support for destructuring in setters we also need
|
| + // to check for duplicate names.
|
| + if (dupe_loc.IsValid()) {
|
| + Traits::ReportMessageAt(dupe_loc, "strict_param_dupe");
|
| *ok = false;
|
| return;
|
| }
|
| - // TODO(arv): When we add support for destructuring in setters we also need
|
| - // to check for duplicate names.
|
| - if (locs.duplicate.IsValid()) {
|
| - Traits::ReportMessageAt(locs.duplicate, "strict_param_dupe");
|
| + if (reserved_loc.IsValid()) {
|
| + Traits::ReportMessageAt(reserved_loc, "unexpected_strict_reserved");
|
| *ok = false;
|
| return;
|
| }
|
| @@ -621,22 +600,12 @@ class ParserBase : public Traits {
|
| ExpressionT ParseMemberExpression(bool* ok);
|
| ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
|
| bool* ok);
|
| - ExpressionT ParseArrowFunctionLiteral(
|
| - int start_pos, FormalParameterListT params,
|
| - const FormalParameterErrorLocations& error_locs, bool has_rest, bool* ok);
|
| + ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast,
|
| + bool* ok);
|
| ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
|
| void AddTemplateExpression(ExpressionT);
|
| ExpressionT ParseSuperExpression(bool is_new, bool* ok);
|
|
|
| - FormalParameterT ParseFormalParameter(DuplicateFinder* duplicate_finder,
|
| - FormalParameterErrorLocations* locs,
|
| - bool* ok);
|
| - FormalParameterListT ParseFormalParameterList(
|
| - FormalParameterErrorLocations* locs, bool* is_rest, bool* ok);
|
| - void CheckArityRestrictions(
|
| - int param_count, FunctionLiteral::ArityRestriction arity_restriction,
|
| - int formals_start_pos, int formals_end_pos, 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,
|
| // we allow calls for web compatibility and rewrite them to a runtime throw.
|
| @@ -846,6 +815,12 @@ class PreParserExpression {
|
| IsValidArrowParamListField::encode(valid_arrow_param_list));
|
| }
|
|
|
| + static PreParserExpression EmptyArrowParamList() {
|
| + // Any expression for which IsValidArrowParamList() returns true
|
| + // will work here.
|
| + return FromIdentifier(PreParserIdentifier::Default());
|
| + }
|
| +
|
| static PreParserExpression StringLiteral() {
|
| return PreParserExpression(TypeField::encode(kStringLiteralExpression));
|
| }
|
| @@ -936,27 +911,20 @@ class PreParserExpression {
|
| return IsIdentifier() || IsProperty();
|
| }
|
|
|
| - bool IsValidArrowParamList(FormalParameterErrorLocations* locs,
|
| - const Scanner::Location& params_loc) const {
|
| + bool IsValidArrowParamList(Scanner::Location* undefined_loc) const {
|
| ValidArrowParam valid = ValidateArrowParams();
|
| if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) {
|
| return false;
|
| }
|
| - switch (valid) {
|
| - case kInvalidArrowParam:
|
| - return false;
|
| - case kInvalidStrongArrowParam:
|
| - locs->undefined = params_loc;
|
| - return true;
|
| - case kInvalidStrictReservedArrowParam:
|
| - locs->reserved = params_loc;
|
| - return true;
|
| - case kInvalidStrictEvalArgumentsArrowParam:
|
| - locs->eval_or_arguments = params_loc;
|
| - return true;
|
| - default:
|
| - DCHECK_EQ(valid, kValidArrowParam);
|
| - return true;
|
| + if (valid == kValidArrowParam) {
|
| + return true;
|
| + } else if (valid == kInvalidStrongArrowParam) {
|
| + // Return true for now regardless of strong mode for compatibility with
|
| + // parser.
|
| + *undefined_loc = Scanner::Location();
|
| + return true;
|
| + } else {
|
| + return false;
|
| }
|
| }
|
|
|
| @@ -1023,12 +991,8 @@ class PreParserExpression {
|
| kNoTemplateTagExpression
|
| };
|
|
|
| - // These validity constraints are ordered such that a value of N implies lack
|
| - // of errors M < N.
|
| enum ValidArrowParam {
|
| kInvalidArrowParam,
|
| - kInvalidStrictEvalArgumentsArrowParam,
|
| - kInvalidStrictReservedArrowParam,
|
| kInvalidStrongArrowParam,
|
| kValidArrowParam
|
| };
|
| @@ -1044,16 +1008,13 @@ class PreParserExpression {
|
| return kInvalidArrowParam;
|
| }
|
| PreParserIdentifier ident = AsIdentifier();
|
| - // In strict mode, eval and arguments are not valid formal parameter names.
|
| - if (ident.IsEval() || ident.IsArguments()) {
|
| - return kInvalidStrictEvalArgumentsArrowParam;
|
| - }
|
| - // In strict mode, future reserved words are not valid either, and as they
|
| - // produce different errors we allot them their own error code.
|
| - if (ident.IsFutureStrictReserved()) {
|
| - return kInvalidStrictReservedArrowParam;
|
| + // A valid identifier can be an arrow function parameter
|
| + // except for eval, arguments, yield, and reserved keywords.
|
| + if (ident.IsEval() || ident.IsArguments() ||
|
| + ident.IsFutureStrictReserved()) {
|
| + return kInvalidArrowParam;
|
| }
|
| - // In strong mode, 'undefined' isn't a valid formal parameter name either.
|
| + // In strong mode, 'undefined' is similarly restricted.
|
| if (ident.IsUndefined()) {
|
| return kInvalidStrongArrowParam;
|
| }
|
| @@ -1070,7 +1031,7 @@ class PreParserExpression {
|
| ExpressionTypeField;
|
| typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField;
|
| typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField;
|
| - typedef BitField<ValidArrowParam, ParenthesizationField::kNext, 3>
|
| + typedef BitField<ValidArrowParam, ParenthesizationField::kNext, 2>
|
| IsValidArrowParamListField;
|
| typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10>
|
| IdentifierTypeField;
|
| @@ -1079,25 +1040,20 @@ class PreParserExpression {
|
| };
|
|
|
|
|
| -// The pre-parser doesn't need to build lists of expressions, identifiers, or
|
| -// the like.
|
| -template <typename T>
|
| -class PreParserList {
|
| +// PreParserExpressionList doesn't actually store the expressions because
|
| +// PreParser doesn't need to.
|
| +class PreParserExpressionList {
|
| public:
|
| // These functions make list->Add(some_expression) work (and do nothing).
|
| - PreParserList() : length_(0) {}
|
| - PreParserList* operator->() { return this; }
|
| - void Add(T, void*) { ++length_; }
|
| + PreParserExpressionList() : length_(0) {}
|
| + PreParserExpressionList* operator->() { return this; }
|
| + void Add(PreParserExpression, void*) { ++length_; }
|
| int length() const { return length_; }
|
| private:
|
| int length_;
|
| };
|
|
|
|
|
| -typedef PreParserList<PreParserExpression> PreParserExpressionList;
|
| -typedef PreParserList<PreParserIdentifier> PreParserFormalParameterList;
|
| -
|
| -
|
| class PreParserStatement {
|
| public:
|
| static PreParserStatement Default() {
|
| @@ -1162,7 +1118,16 @@ class PreParserStatement {
|
| };
|
|
|
|
|
| -typedef PreParserList<PreParserStatement> PreParserStatementList;
|
| +
|
| +// PreParserStatementList doesn't actually store the statements because
|
| +// the PreParser does not need them.
|
| +class PreParserStatementList {
|
| + public:
|
| + // These functions make list->Add(some_expression) work as no-ops.
|
| + PreParserStatementList() {}
|
| + PreParserStatementList* operator->() { return this; }
|
| + void Add(PreParserStatement, void*) {}
|
| +};
|
|
|
|
|
| class PreParserFactory {
|
| @@ -1327,8 +1292,6 @@ class PreParserTraits {
|
| typedef PreParserExpression Literal;
|
| typedef PreParserExpressionList ExpressionList;
|
| typedef PreParserExpressionList PropertyList;
|
| - typedef PreParserIdentifier FormalParameter;
|
| - typedef PreParserFormalParameterList FormalParameterList;
|
| typedef PreParserStatementList StatementList;
|
|
|
| // For constructing objects returned by the traversing functions.
|
| @@ -1472,6 +1435,9 @@ class PreParserTraits {
|
| static PreParserExpression EmptyExpression() {
|
| return PreParserExpression::Default();
|
| }
|
| + static PreParserExpression EmptyArrowParamList() {
|
| + return PreParserExpression::EmptyArrowParamList();
|
| + }
|
| static PreParserExpression EmptyLiteral() {
|
| return PreParserExpression::Default();
|
| }
|
| @@ -1484,12 +1450,6 @@ class PreParserTraits {
|
| static PreParserExpressionList NullExpressionList() {
|
| return PreParserExpressionList();
|
| }
|
| - static PreParserIdentifier EmptyFormalParameter() {
|
| - return PreParserIdentifier::Default();
|
| - }
|
| - static PreParserFormalParameterList NullFormalParameterList() {
|
| - return PreParserFormalParameterList();
|
| - }
|
|
|
| // Odd-ball literal creators.
|
| static PreParserExpression GetLiteralTheHole(int position,
|
| @@ -1554,11 +1514,6 @@ class PreParserTraits {
|
| return PreParserExpressionList();
|
| }
|
|
|
| - static PreParserFormalParameterList NewFormalParameterList(int size,
|
| - Zone* zone) {
|
| - return PreParserFormalParameterList();
|
| - }
|
| -
|
| V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name,
|
| int* materialized_literal_count,
|
| int* expected_property_count, bool* ok) {
|
| @@ -1570,9 +1525,16 @@ class PreParserTraits {
|
| Variable* fvar, Token::Value fvar_init_op,
|
| FunctionKind kind, bool* ok);
|
|
|
| - V8_INLINE PreParserFormalParameterList ParseArrowFunctionFormalParameterList(
|
| - PreParserExpression expression, const Scanner::Location& params_loc,
|
| - FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok);
|
| + // Utility functions
|
| + int DeclareArrowParametersFromExpression(PreParserExpression expression,
|
| + Scope* scope,
|
| + Scanner::Location* undefined_loc,
|
| + Scanner::Location* dupe_loc,
|
| + bool* ok) {
|
| + // TODO(aperez): Detect duplicated identifiers in paramlists.
|
| + *ok = expression.IsValidArrowParamList(undefined_loc);
|
| + return 0;
|
| + }
|
|
|
| struct TemplateLiteralState {};
|
|
|
| @@ -1598,11 +1560,6 @@ class PreParserTraits {
|
| return !tag.IsNoTemplateTag();
|
| }
|
|
|
| - int DeclareFormalParameters(PreParserFormalParameterList params, Scope* scope,
|
| - bool has_rest) {
|
| - return params->length();
|
| - }
|
| -
|
| void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
|
|
|
| // Temporary glue; these functions will move to ParserBase.
|
| @@ -1791,22 +1748,6 @@ PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function,
|
| }
|
|
|
|
|
| -PreParserFormalParameterList
|
| -PreParserTraits::ParseArrowFunctionFormalParameterList(
|
| - PreParserExpression params, const Scanner::Location& params_loc,
|
| - FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok) {
|
| - // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter
|
| - // lists that are too long.
|
| - if (!params.IsValidArrowParamList(error_locs, params_loc)) {
|
| - *ok = false;
|
| - ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list");
|
| - return this->NullFormalParameterList();
|
| - }
|
| -
|
| - return PreParserFormalParameterList();
|
| -}
|
| -
|
| -
|
| PreParserStatementList PreParser::ParseEagerFunctionBody(
|
| PreParserIdentifier function_name, int pos, Variable* fvar,
|
| Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
|
| @@ -2102,13 +2043,12 @@ ParserBase<Traits>::ParsePrimaryExpression(bool* ok) {
|
|
|
| case Token::LPAREN:
|
| Consume(Token::LPAREN);
|
| - if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) {
|
| - // As a primary expression, the only thing that can follow "()" is "=>".
|
| - FormalParameterListT params = this->NewFormalParameterList(0, zone());
|
| - FormalParameterErrorLocations error_locs;
|
| - bool has_rest = false;
|
| - result = this->ParseArrowFunctionLiteral(beg_pos, params, error_locs,
|
| - has_rest, CHECK_OK);
|
| + if (allow_harmony_arrow_functions() && peek() == Token::RPAREN) {
|
| + // Arrow functions are the only expression type constructions
|
| + // for which an empty parameter list "()" is valid input.
|
| + Consume(Token::RPAREN);
|
| + result = this->ParseArrowFunctionLiteral(
|
| + beg_pos, this->EmptyArrowParamList(), CHECK_OK);
|
| } else {
|
| // Heuristically try to detect immediately called functions before
|
| // seeing the call parentheses.
|
| @@ -2566,13 +2506,8 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
|
|
|
| if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
|
| checkpoint.Restore();
|
| - FormalParameterErrorLocations error_locs;
|
| - Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos);
|
| - bool has_rest = false;
|
| - FormalParameterListT params = this->ParseArrowFunctionFormalParameterList(
|
| - expression, loc, &error_locs, &has_rest, CHECK_OK);
|
| - expression = this->ParseArrowFunctionLiteral(
|
| - lhs_location.beg_pos, params, error_locs, has_rest, CHECK_OK);
|
| + expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos,
|
| + expression, CHECK_OK);
|
| return expression;
|
| }
|
|
|
| @@ -3106,112 +3041,10 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
|
|
|
|
|
| template <class Traits>
|
| -typename ParserBase<Traits>::FormalParameterT
|
| -ParserBase<Traits>::ParseFormalParameter(DuplicateFinder* duplicate_finder,
|
| - FormalParameterErrorLocations* locs,
|
| - bool* ok) {
|
| - // FormalParameter[Yield,GeneratorParameter] :
|
| - // BindingElement[?Yield, ?GeneratorParameter]
|
| - bool is_strict_reserved;
|
| - IdentifierT name =
|
| - ParseIdentifierOrStrictReservedWord(&is_strict_reserved, ok);
|
| - if (!*ok) return this->EmptyFormalParameter();
|
| -
|
| - // Store locations for possible future error reports.
|
| - if (!locs->eval_or_arguments.IsValid() && this->IsEvalOrArguments(name)) {
|
| - locs->eval_or_arguments = scanner()->location();
|
| - }
|
| - if (!locs->undefined.IsValid() && this->IsUndefined(name)) {
|
| - locs->undefined = scanner()->location();
|
| - }
|
| - if (!locs->reserved.IsValid() && is_strict_reserved) {
|
| - locs->reserved = scanner()->location();
|
| - }
|
| - if (!locs->duplicate.IsValid() && duplicate_finder != nullptr) {
|
| - int prev_value = scanner()->FindSymbol(duplicate_finder, 1);
|
| - if (prev_value != 0) locs->duplicate = scanner()->location();
|
| - }
|
| -
|
| - return name;
|
| -}
|
| -
|
| -
|
| -template <class Traits>
|
| -typename ParserBase<Traits>::FormalParameterListT
|
| -ParserBase<Traits>::ParseFormalParameterList(
|
| - FormalParameterErrorLocations* locs, bool* is_rest, bool* ok) {
|
| - // FormalParameters[Yield,GeneratorParameter] :
|
| - // [empty]
|
| - // FormalParameterList[?Yield, ?GeneratorParameter]
|
| - //
|
| - // FormalParameterList[Yield,GeneratorParameter] :
|
| - // FunctionRestParameter[?Yield]
|
| - // FormalsList[?Yield, ?GeneratorParameter]
|
| - // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield]
|
| - //
|
| - // FormalsList[Yield,GeneratorParameter] :
|
| - // FormalParameter[?Yield, ?GeneratorParameter]
|
| - // FormalsList[?Yield, ?GeneratorParameter] ,
|
| - // FormalParameter[?Yield,?GeneratorParameter]
|
| -
|
| - FormalParameterListT result = this->NewFormalParameterList(4, zone_);
|
| - DuplicateFinder duplicate_finder(scanner()->unicode_cache());
|
| -
|
| - if (peek() != Token::RPAREN) {
|
| - do {
|
| - *is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS);
|
| - FormalParameterT param =
|
| - ParseFormalParameter(&duplicate_finder, locs, ok);
|
| - if (!*ok) return this->NullFormalParameterList();
|
| - result->Add(param, zone());
|
| - if (result->length() > Code::kMaxArguments) {
|
| - ReportMessage("too_many_parameters");
|
| - *ok = false;
|
| - return this->NullFormalParameterList();
|
| - }
|
| - } while (!*is_rest && Check(Token::COMMA));
|
| - }
|
| -
|
| - if (is_rest && peek() == Token::COMMA) {
|
| - ReportMessageAt(scanner()->peek_location(), "param_after_rest");
|
| - *ok = false;
|
| - return this->NullFormalParameterList();
|
| - }
|
| -
|
| - return result;
|
| -}
|
| -
|
| -
|
| -template <class Traits>
|
| -void ParserBase<Traits>::CheckArityRestrictions(
|
| - int param_count, FunctionLiteral::ArityRestriction arity_restriction,
|
| - int formals_start_pos, int formals_end_pos, bool* ok) {
|
| - switch (arity_restriction) {
|
| - case FunctionLiteral::GETTER_ARITY:
|
| - if (param_count != 0) {
|
| - ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
|
| - "bad_getter_arity");
|
| - *ok = false;
|
| - }
|
| - break;
|
| - case FunctionLiteral::SETTER_ARITY:
|
| - if (param_count != 1) {
|
| - ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
|
| - "bad_setter_arity");
|
| - *ok = false;
|
| - }
|
| - break;
|
| - default:
|
| - break;
|
| - }
|
| -}
|
| -
|
| -
|
| -template <class Traits>
|
| typename ParserBase<Traits>::ExpressionT
|
| -ParserBase<Traits>::ParseArrowFunctionLiteral(
|
| - int start_pos, FormalParameterListT params,
|
| - const FormalParameterErrorLocations& error_locs, bool has_rest, bool* ok) {
|
| +ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos,
|
| + ExpressionT params_ast,
|
| + 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.
|
| @@ -3233,7 +3066,29 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
|
| typename Traits::Type::Factory function_factory(ast_value_factory());
|
| FunctionState function_state(&function_state_, &scope_, scope,
|
| kArrowFunction, &function_factory);
|
| - num_parameters = this->DeclareFormalParameters(params, scope_, has_rest);
|
| + Scanner::Location undefined_loc = Scanner::Location::invalid();
|
| + Scanner::Location dupe_loc = Scanner::Location::invalid();
|
| + // TODO(arv): Pass in eval_args_loc and reserved_loc here.
|
| + num_parameters = Traits::DeclareArrowParametersFromExpression(
|
| + params_ast, scope_, &undefined_loc, &dupe_loc, ok);
|
| + if (!*ok) {
|
| + ReportMessageAt(
|
| + Scanner::Location(start_pos, scanner()->location().beg_pos),
|
| + "malformed_arrow_function_parameter_list");
|
| + return this->EmptyExpression();
|
| + }
|
| +
|
| + if (undefined_loc.IsValid()) {
|
| + // Workaround for preparser not keeping track of positions.
|
| + undefined_loc = Scanner::Location(start_pos,
|
| + scanner()->location().end_pos);
|
| + }
|
| + if (num_parameters > Code::kMaxArguments) {
|
| + ReportMessageAt(Scanner::Location(params_ast->position(), position()),
|
| + "too_many_parameters");
|
| + *ok = false;
|
| + return this->EmptyExpression();
|
| + }
|
|
|
| Expect(Token::ARROW, CHECK_OK);
|
|
|
| @@ -3272,13 +3127,15 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
|
| scope->set_start_position(start_pos);
|
| scope->set_end_position(scanner()->location().end_pos);
|
|
|
| - // Arrow function formal parameters are parsed as StrictFormalParameterList,
|
| - // which is not the same as "parameters of a strict function"; it only means
|
| - // that duplicates are not allowed. Of course, the arrow function may
|
| - // itself be strict as well.
|
| + // Arrow function *parameter lists* are always checked as in strict mode.
|
| + // TODO(arv): eval_args_loc and reserved_loc needs to be set by
|
| + // DeclareArrowParametersFromExpression.
|
| + Scanner::Location eval_args_loc = Scanner::Location::invalid();
|
| + Scanner::Location reserved_loc = Scanner::Location::invalid();
|
| const bool use_strict_params = true;
|
| this->CheckFunctionParameterNames(language_mode(), use_strict_params,
|
| - error_locs, CHECK_OK);
|
| + eval_args_loc, undefined_loc, dupe_loc,
|
| + reserved_loc, CHECK_OK);
|
|
|
| // Validate strict mode.
|
| if (is_strict(language_mode())) {
|
|
|