[es6] Refactor FormalParameter
authorrossberg <rossberg@chromium.org>
Tue, 4 Aug 2015 14:24:13 +0000 (07:24 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 4 Aug 2015 14:24:58 +0000 (14:24 +0000)
Store arity in FormalParameters; store name (instead of var) and is_rest flag in individual parameters. Ensure that the arity is always maintained consistently.

This is preparation for more parameter destructuring adjustments. In particular, a follow-up CL will separate parameter recording from declaring the variables.

R=adamk@chromium.org, littledan@chromium.org
BUG=v8:811
LOG=N

Review URL: https://codereview.chromium.org/1259013003

Cr-Commit-Position: refs/heads/master@{#30002}

src/parser.cc
src/parser.h
src/preparser.cc
src/preparser.h
test/cctest/test-parsing.cc

index e8f3a64..311d192 100644 (file)
@@ -917,7 +917,7 @@ Parser::Parser(ParseInfo* info)
   set_allow_harmony_unicode(FLAG_harmony_unicode);
   set_allow_harmony_computed_property_names(
       FLAG_harmony_computed_property_names);
-  set_allow_harmony_rest_params(FLAG_harmony_rest_parameters);
+  set_allow_harmony_rest_parameters(FLAG_harmony_rest_parameters);
   set_allow_harmony_spreadcalls(FLAG_harmony_spreadcalls);
   set_allow_harmony_destructuring(FLAG_harmony_destructuring);
   set_allow_harmony_spread_arrays(FLAG_harmony_spread_arrays);
@@ -3854,7 +3854,7 @@ void ParserTraits::ParseArrowFunctionFormalParameters(
     ParserFormalParameters* parameters, Expression* expr,
     const Scanner::Location& params_loc,
     Scanner::Location* duplicate_loc, bool* ok) {
-  if (parameters->scope->num_parameters() >= Code::kMaxArguments) {
+  if (parameters->arity >= Code::kMaxArguments) {
     ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
     *ok = false;
     return;
@@ -3908,6 +3908,7 @@ void ParserTraits::ParseArrowFunctionFormalParameters(
     parser_->scope_->RemoveUnresolved(expr->AsVariableProxy());
   }
 
+  ++parameters->arity;
   ExpressionClassifier classifier;
   DeclareFormalParameter(parameters, expr, is_rest, &classifier);
   if (!duplicate_loc->IsValid()) {
@@ -3996,7 +3997,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
                      : NewScope(scope_, FUNCTION_SCOPE, kind);
   scope->SetLanguageMode(language_mode);
   ZoneList<Statement*>* body = NULL;
-  int arity = 0;
+  int arity = -1;
   int materialized_literal_count = -1;
   int expected_property_count = -1;
   DuplicateFinder duplicate_finder(scanner()->unicode_cache());
@@ -4030,7 +4031,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
     int start_position = scanner()->location().beg_pos;
     scope_->set_start_position(start_position);
     ParserFormalParameters formals(scope);
-    arity = ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
+    ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
+    arity = formals.arity;
+    DCHECK(arity == formals.params.length());
     Expect(Token::RPAREN, CHECK_OK);
     int formals_end_position = scanner()->location().end_pos;
 
@@ -4294,7 +4297,8 @@ Block* Parser::BuildParameterInitializationBlock(
   DCHECK(scope_->is_function_scope());
   Block* init_block =
       factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
-  for (auto parameter : parameters.params) {
+  for (int i = 0; i < parameters.params.length(); ++i) {
+    auto parameter = parameters.params[i];
     if (parameter.pattern == nullptr) continue;
     DeclarationDescriptor descriptor;
     descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
@@ -4309,7 +4313,7 @@ Block* Parser::BuildParameterInitializationBlock(
     descriptor.init_op = Token::INIT_LET;
     DeclarationParsingResult::Declaration decl(
         parameter.pattern, parameter.pattern->position(),
-        factory()->NewVariableProxy(parameter.var));
+        factory()->NewVariableProxy(parameters.scope->parameter(i)));
     PatternRewriter::DeclareAndInitializeVariables(init_block, &descriptor,
                                                    &decl, nullptr, CHECK_OK);
   }
@@ -4477,7 +4481,7 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
     SET_ALLOW(harmony_sloppy_let);
     SET_ALLOW(harmony_unicode);
     SET_ALLOW(harmony_computed_property_names);
-    SET_ALLOW(harmony_rest_params);
+    SET_ALLOW(harmony_rest_parameters);
     SET_ALLOW(harmony_spreadcalls);
     SET_ALLOW(harmony_destructuring);
     SET_ALLOW(harmony_spread_arrays);
index 733665c..2086ee9 100644 (file)
@@ -541,10 +541,11 @@ class SingletonLogger;
 
 struct ParserFormalParameters : public PreParserFormalParameters {
   struct Parameter {
-    Parameter(Variable* var, Expression* pattern)
-        : var(var), pattern(pattern) {}
-    Variable* var;
+    Parameter(const AstRawString* name, Expression* pattern, bool is_rest)
+        : name(name), pattern(pattern), is_rest(is_rest) {}
+    const AstRawString* name;
     Expression* pattern;
+    bool is_rest;
   };
 
   explicit ParserFormalParameters(Scope* scope)
@@ -552,8 +553,10 @@ struct ParserFormalParameters : public PreParserFormalParameters {
 
   ZoneList<Parameter> params;
 
-  void AddParameter(Variable* var, Expression* pattern) {
-    params.Add(Parameter(var, pattern), scope->zone());
+  void AddParameter(
+      const AstRawString* name, Expression* pattern, bool is_rest) {
+    params.Add(Parameter(name, pattern, is_rest), scope->zone());
+    DCHECK_EQ(arity, params.length());
   }
 };
 
@@ -579,7 +582,7 @@ class ParserTraits {
     typedef ObjectLiteral::Property* ObjectLiteralProperty;
     typedef ZoneList<v8::internal::Expression*>* ExpressionList;
     typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
-    typedef const v8::internal::AstRawString* FormalParameter;
+    typedef ParserFormalParameters::Parameter FormalParameter;
     typedef ParserFormalParameters FormalParameters;
     typedef ZoneList<v8::internal::Statement*>* StatementList;
 
@@ -1320,7 +1323,7 @@ void ParserTraits::DeclareFormalParameter(
   VariableMode mode = is_simple ? VAR : TEMPORARY;
   Variable* var =
       parameters->scope->DeclareParameter(name, mode, is_rest, &is_duplicate);
-  parameters->AddParameter(var, is_simple ? nullptr : pattern);
+  parameters->AddParameter(name, is_simple ? nullptr : pattern, is_rest);
   if (is_duplicate) {
     classifier->RecordDuplicateFormalParameterError(
         parser_->scanner()->location());
index d60fa56..ec0ea2d 100644 (file)
@@ -1053,11 +1053,11 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
   int start_position = scanner()->location().beg_pos;
   function_scope->set_start_position(start_position);
   PreParserFormalParameters formals(nullptr);
-  int arity = ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
+  ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
   Expect(Token::RPAREN, CHECK_OK);
   int formals_end_position = scanner()->location().end_pos;
 
-  CheckArityRestrictions(arity, arity_restriction,
+  CheckArityRestrictions(formals.arity, arity_restriction,
                          formals.has_rest, start_position,
                          formals_end_position, CHECK_OK);
 
index a3ae91c..3bd0953 100644 (file)
@@ -103,7 +103,7 @@ class ParserBase : public Traits {
         allow_harmony_sloppy_(false),
         allow_harmony_sloppy_let_(false),
         allow_harmony_computed_property_names_(false),
-        allow_harmony_rest_params_(false),
+        allow_harmony_rest_parameters_(false),
         allow_harmony_spreadcalls_(false),
         allow_harmony_destructuring_(false),
         allow_harmony_spread_arrays_(false),
@@ -121,7 +121,7 @@ class ParserBase : public Traits {
   ALLOW_ACCESSORS(harmony_sloppy);
   ALLOW_ACCESSORS(harmony_sloppy_let);
   ALLOW_ACCESSORS(harmony_computed_property_names);
-  ALLOW_ACCESSORS(harmony_rest_params);
+  ALLOW_ACCESSORS(harmony_rest_parameters);
   ALLOW_ACCESSORS(harmony_spreadcalls);
   ALLOW_ACCESSORS(harmony_destructuring);
   ALLOW_ACCESSORS(harmony_spread_arrays);
@@ -702,8 +702,8 @@ class ParserBase : public Traits {
   void ParseFormalParameter(bool is_rest,
                             FormalParametersT* parameters,
                             ExpressionClassifier* classifier, bool* ok);
-  int ParseFormalParameterList(FormalParametersT* parameters,
-                               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);
@@ -801,7 +801,7 @@ class ParserBase : public Traits {
   bool allow_harmony_sloppy_;
   bool allow_harmony_sloppy_let_;
   bool allow_harmony_computed_property_names_;
-  bool allow_harmony_rest_params_;
+  bool allow_harmony_rest_parameters_;
   bool allow_harmony_spreadcalls_;
   bool allow_harmony_destructuring_;
   bool allow_harmony_spread_arrays_;
@@ -1315,10 +1315,12 @@ class PreParserFactory {
 struct PreParserFormalParameters {
   explicit PreParserFormalParameters(Scope* scope)
       : scope(scope),
+        arity(0),
         has_rest(false),
         is_simple(true),
         materialized_literals_count(0) {}
   Scope* scope;
+  int arity;
   bool has_rest;
   bool is_simple;
   int materialized_literals_count;
@@ -2274,7 +2276,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
         result = this->ParseArrowFunctionLiteral(parameters, args_classifier,
                                                  CHECK_OK);
       } else if (allow_harmony_arrow_functions() &&
-                 allow_harmony_rest_params() && Check(Token::ELLIPSIS)) {
+                 allow_harmony_rest_parameters() && Check(Token::ELLIPSIS)) {
         // (...x) => y
         Scope* scope =
             this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
@@ -2386,7 +2388,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
     }
     Consume(Token::COMMA);
     bool is_rest = false;
-    if (allow_harmony_rest_params() && peek() == Token::ELLIPSIS) {
+    if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) {
       // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
       // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
       // valid expression or binding pattern.
@@ -3645,12 +3647,13 @@ void ParserBase<Traits>::ParseFormalParameter(
     *ok = false;
     return;
   }
+  ++parameters->arity;
   Traits::DeclareFormalParameter(parameters, pattern, is_rest, classifier);
 }
 
 
 template <class Traits>
-int ParserBase<Traits>::ParseFormalParameterList(
+void ParserBase<Traits>::ParseFormalParameterList(
     FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
   // FormalParameters[Yield,GeneratorParameter] :
   //   [empty]
@@ -3666,29 +3669,26 @@ int ParserBase<Traits>::ParseFormalParameterList(
   //   FormalsList[?Yield, ?GeneratorParameter] ,
   //     FormalParameter[?Yield,?GeneratorParameter]
 
-  int arity = 0;
+  DCHECK_EQ(0, parameters->arity);
 
   if (peek() != Token::RPAREN) {
     do {
-      if (++arity > Code::kMaxArguments) {
+      if (parameters->arity > Code::kMaxArguments) {
         ReportMessage(MessageTemplate::kTooManyParameters);
         *ok = false;
-        return -1;
+        return;
       }
-      bool is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS);
+      bool is_rest = allow_harmony_rest_parameters() && Check(Token::ELLIPSIS);
       ParseFormalParameter(is_rest, parameters, classifier, ok);
-      if (!*ok) return -1;
+      if (!*ok) return;
     } while (!parameters->has_rest && Check(Token::COMMA));
 
     if (parameters->has_rest && peek() == Token::COMMA) {
       ReportMessageAt(scanner()->peek_location(),
                       MessageTemplate::kParamAfterRest);
       *ok = false;
-      return -1;
     }
   }
-
-  return arity;
 }
 
 
index 5c78f43..66f7f75 100644 (file)
@@ -1457,7 +1457,7 @@ void SetParserFlags(i::ParserBase<Traits>* parser,
   parser->set_allow_harmony_modules(flags.Contains(kAllowHarmonyModules));
   parser->set_allow_harmony_arrow_functions(
       flags.Contains(kAllowHarmonyArrowFunctions));
-  parser->set_allow_harmony_rest_params(
+  parser->set_allow_harmony_rest_parameters(
       flags.Contains(kAllowHarmonyRestParameters));
   parser->set_allow_harmony_spreadcalls(
       flags.Contains(kAllowHarmonySpreadCalls));