Move new expression parsing funcs to ParserBase.
authormarja@chromium.org <marja@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 21 Mar 2014 10:34:51 +0000 (10:34 +0000)
committermarja@chromium.org <marja@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 21 Mar 2014 10:34:51 +0000 (10:34 +0000)
Functions moved: ParseMemberWithNewPrefixesExpression, ParseMemberExpression,
ParseMemberExpressionContinuation.

Now all Parse*Expression functions are in ParserBase.

R=mstarzinger@chromium.org
BUG=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20153 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/parser.cc
src/parser.h
src/preparser.cc
src/preparser.h

index c0d3360..9724ec7 100644 (file)
@@ -439,6 +439,17 @@ bool ParserTraits::IsIdentifier(Expression* expression) {
 }
 
 
+void ParserTraits::PushPropertyName(FuncNameInferrer* fni,
+                                    Expression* expression) {
+  if (expression->IsPropertyName()) {
+    fni->PushLiteralName(expression->AsLiteral()->AsPropertyName());
+  } else {
+    fni->PushLiteralName(
+        parser_->isolate()->factory()->anonymous_function_string());
+  }
+}
+
+
 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
                                                            Expression* right) {
   ASSERT(left != NULL);
@@ -750,11 +761,6 @@ FunctionLiteral* ParserTraits::ParseFunctionLiteral(
 }
 
 
-Expression* ParserTraits::ParseMemberWithNewPrefixesExpression(bool* ok) {
-  return parser_->ParseMemberWithNewPrefixesExpression(ok);
-}
-
-
 Parser::Parser(CompilationInfo* info)
     : ParserBase<ParserTraits>(&scanner_,
                                info->isolate()->stack_guard()->real_climit(),
@@ -3053,127 +3059,6 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
 }
 
 
-Expression* Parser::ParseMemberWithNewPrefixesExpression(bool* ok) {
-  // NewExpression ::
-  //   ('new')+ MemberExpression
-
-  // The grammar for new expressions is pretty warped. We can have several 'new'
-  // keywords following each other, and then a MemberExpression. When we see '('
-  // after the MemberExpression, it's associated with the rightmost unassociated
-  // 'new' to create a NewExpression with arguments. However, a NewExpression
-  // can also occur without arguments.
-
-  // Examples of new expression:
-  // new foo.bar().baz means (new (foo.bar)()).baz
-  // new foo()() means (new foo())()
-  // new new foo()() means (new (new foo())())
-  // new new foo means new (new foo)
-  // new new foo() means new (new foo())
-  // new new foo().bar().baz means (new (new foo()).bar()).baz
-
-  if (peek() == Token::NEW) {
-    Consume(Token::NEW);
-    int new_pos = position();
-    Expression* result = ParseMemberWithNewPrefixesExpression(CHECK_OK);
-    if (peek() == Token::LPAREN) {
-      // NewExpression with arguments.
-      ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
-      result = factory()->NewCallNew(result, args, new_pos);
-      // The expression can still continue with . or [ after the arguments.
-      result = ParseMemberExpressionContinuation(result, CHECK_OK);
-      return result;
-    }
-    // NewExpression without arguments.
-    return factory()->NewCallNew(
-        result, new(zone()) ZoneList<Expression*>(0, zone()), new_pos);
-  }
-  // No 'new' keyword.
-  return ParseMemberExpression(ok);
-}
-
-
-Expression* Parser::ParseMemberExpression(bool* ok) {
-  // MemberExpression ::
-  //   (PrimaryExpression | FunctionLiteral)
-  //     ('[' Expression ']' | '.' Identifier | Arguments)*
-
-  // The '[' Expression ']' and '.' Identifier parts are parsed by
-  // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
-  // caller.
-
-  // Parse the initial primary or function expression.
-  Expression* result = NULL;
-  if (peek() == Token::FUNCTION) {
-    Consume(Token::FUNCTION);
-    int function_token_position = position();
-    bool is_generator = allow_generators() && Check(Token::MUL);
-    Handle<String> name;
-    bool is_strict_reserved_name = false;
-    Scanner::Location function_name_location = Scanner::Location::invalid();
-    FunctionLiteral::FunctionType function_type =
-        FunctionLiteral::ANONYMOUS_EXPRESSION;
-    if (peek_any_identifier()) {
-      name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
-                                                 CHECK_OK);
-      function_name_location = scanner()->location();
-      function_type = FunctionLiteral::NAMED_EXPRESSION;
-    }
-    result = ParseFunctionLiteral(name,
-                                  function_name_location,
-                                  is_strict_reserved_name,
-                                  is_generator,
-                                  function_token_position,
-                                  function_type,
-                                  CHECK_OK);
-  } else {
-    result = ParsePrimaryExpression(CHECK_OK);
-  }
-
-  result = ParseMemberExpressionContinuation(result, CHECK_OK);
-  return result;
-}
-
-
-Expression* Parser::ParseMemberExpressionContinuation(Expression* expression,
-                                                      bool* ok) {
-  // Parses this part of MemberExpression:
-  // ('[' Expression ']' | '.' Identifier)*
-  while (true) {
-    switch (peek()) {
-      case Token::LBRACK: {
-        Consume(Token::LBRACK);
-        int pos = position();
-        Expression* index = ParseExpression(true, CHECK_OK);
-        expression = factory()->NewProperty(expression, index, pos);
-        if (fni_ != NULL) {
-          if (index->IsPropertyName()) {
-            fni_->PushLiteralName(index->AsLiteral()->AsPropertyName());
-          } else {
-            fni_->PushLiteralName(
-                isolate()->factory()->anonymous_function_string());
-          }
-        }
-        Expect(Token::RBRACK, CHECK_OK);
-        break;
-      }
-      case Token::PERIOD: {
-        Consume(Token::PERIOD);
-        int pos = position();
-        Handle<String> name = ParseIdentifierName(CHECK_OK);
-        expression = factory()->NewProperty(
-            expression, factory()->NewLiteral(name, pos), pos);
-        if (fni_ != NULL) fni_->PushLiteralName(name);
-        break;
-      }
-      default:
-        return expression;
-    }
-  }
-  ASSERT(false);
-  return NULL;
-}
-
-
 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
   // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
   // contexts this is used as a statement which invokes the debugger as i a
index 4febdc8..f496267 100644 (file)
@@ -475,6 +475,7 @@ class ParserTraits {
   static void PushLiteralName(FuncNameInferrer* fni, Handle<String> id) {
     fni->PushLiteralName(id);
   }
+  void PushPropertyName(FuncNameInferrer* fni, Expression* expression);
 
   static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
       Scope* scope, Expression* value, bool* has_function) {
@@ -549,6 +550,7 @@ class ParserTraits {
   static Literal* EmptyLiteral() {
     return NULL;
   }
+  // Used in error return values.
   static ZoneList<Expression*>* NullExpressionList() {
     return NULL;
   }
@@ -589,7 +591,6 @@ class ParserTraits {
       int function_token_position,
       FunctionLiteral::FunctionType type,
       bool* ok);
-  Expression* ParseMemberWithNewPrefixesExpression(bool* ok);
 
  private:
   Parser* parser_;
@@ -725,10 +726,6 @@ class Parser : public ParserBase<ParserTraits> {
   // Support for hamony block scoped bindings.
   Block* ParseScopedBlock(ZoneStringList* labels, bool* ok);
 
-  Expression* ParseMemberWithNewPrefixesExpression(bool* ok);
-  Expression* ParseMemberExpression(bool* ok);
-  Expression* ParseMemberExpressionContinuation(Expression* expression,
-                                                bool* ok);
   // Initialize the components of a for-in / for-of statement.
   void InitializeForEachStatement(ForEachStatement* stmt,
                                   Expression* each,
index 9473701..459cb6a 100644 (file)
@@ -146,12 +146,6 @@ PreParserExpression PreParserTraits::ParseFunctionLiteral(
 }
 
 
-PreParserExpression PreParserTraits::ParseMemberWithNewPrefixesExpression(
-    bool* ok) {
-  return pre_parser_->ParseMemberWithNewPrefixesExpression(ok);
-}
-
-
 PreParser::PreParseResult PreParser::PreParseLazyFunction(
     StrictMode strict_mode, bool is_generator, ParserRecorder* log) {
   log_ = log;
@@ -843,110 +837,6 @@ PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
 #undef DUMMY
 
 
-PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
-    bool* ok) {
-  // NewExpression ::
-  //   ('new')+ MemberExpression
-
-  // See Parser::ParseNewExpression.
-
-  if (peek() == Token::NEW) {
-    Consume(Token::NEW);
-    ParseMemberWithNewPrefixesExpression(CHECK_OK);
-    Expression expression = Expression::Default();
-    if (peek() == Token::LPAREN) {
-      // NewExpression with arguments.
-      ParseArguments(CHECK_OK);
-      // The expression can still continue with . or [ after the arguments. Here
-      // we need to transmit the "is valid left hand side" property of the
-      // expression.
-      expression =
-          ParseMemberExpressionContinuation(Expression::Default(), CHECK_OK);
-    }
-    return expression;
-  }
-  // No 'new' keyword.
-  return ParseMemberExpression(ok);
-}
-
-
-PreParser::Expression PreParser::ParseMemberExpression(bool* ok) {
-  // MemberExpression ::
-  //   (PrimaryExpression | FunctionLiteral)
-  //     ('[' Expression ']' | '.' Identifier | Arguments)*
-
-  // The '[' Expression ']' and '.' Identifier parts are parsed by
-  // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
-  // caller.
-
-  // Parse the initial primary or function expression.
-  Expression result = Expression::Default();
-  if (peek() == Token::FUNCTION) {
-    Consume(Token::FUNCTION);
-    int function_token_position = position();
-    bool is_generator = allow_generators() && Check(Token::MUL);
-    Identifier name = Identifier::Default();
-    bool is_strict_reserved_name = false;
-    Scanner::Location function_name_location = Scanner::Location::invalid();
-    FunctionLiteral::FunctionType function_type =
-        FunctionLiteral::ANONYMOUS_EXPRESSION;
-    if (peek_any_identifier()) {
-      name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
-                                                 CHECK_OK);
-      function_name_location = scanner()->location();
-      function_type = FunctionLiteral::NAMED_EXPRESSION;
-    }
-    result = ParseFunctionLiteral(name,
-                                  function_name_location,
-                                  is_strict_reserved_name,
-                                  is_generator,
-                                  function_token_position,
-                                  function_type,
-                                  CHECK_OK);
-  } else {
-    result = ParsePrimaryExpression(CHECK_OK);
-  }
-  result = ParseMemberExpressionContinuation(result, CHECK_OK);
-  return result;
-}
-
-
-PreParser::Expression PreParser::ParseMemberExpressionContinuation(
-    PreParserExpression expression, bool* ok) {
-  // Parses this part of MemberExpression:
-  // ('[' Expression ']' | '.' Identifier)*
-  while (true) {
-    switch (peek()) {
-      case Token::LBRACK: {
-        Consume(Token::LBRACK);
-        ParseExpression(true, CHECK_OK);
-        Expect(Token::RBRACK, CHECK_OK);
-        if (expression.IsThis()) {
-          expression = Expression::ThisProperty();
-        } else {
-          expression = Expression::Property();
-        }
-        break;
-      }
-      case Token::PERIOD: {
-        Consume(Token::PERIOD);
-        ParseIdentifierName(CHECK_OK);
-        if (expression.IsThis()) {
-          expression = Expression::ThisProperty();
-        } else {
-          expression = Expression::Property();
-        }
-        break;
-      }
-      default:
-        return expression;
-    }
-  }
-  ASSERT(false);
-  return PreParserExpression::Default();
-}
-
-
 PreParser::Expression PreParser::ParseFunctionLiteral(
     Identifier function_name,
     Scanner::Location function_name_location,
index 7977fe2..ee8e46b 100644 (file)
@@ -420,6 +420,10 @@ class ParserBase : public Traits {
   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);
 
   // Used to detect duplicates in object literals. Each of the values
   // kGetterProperty, kSetterProperty and kValueProperty represents
@@ -504,6 +508,7 @@ class ParserBase : public Traits {
 
 class PreParserIdentifier {
  public:
+  PreParserIdentifier() : type_(kUnknownIdentifier) {}
   static PreParserIdentifier Default() {
     return PreParserIdentifier(kUnknownIdentifier);
   }
@@ -791,6 +796,11 @@ class PreParserFactory {
                               int pos) {
     return PreParserExpression::Default();
   }
+  PreParserExpression NewCallNew(PreParserExpression expression,
+                                 PreParserExpressionList arguments,
+                                 int pos) {
+    return PreParserExpression::Default();
+  }
 };
 
 
@@ -860,7 +870,12 @@ class PreParserTraits {
   // operations interleaved with the recursive descent.
   static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
     // PreParser should not use FuncNameInferrer.
-    ASSERT(false);
+    UNREACHABLE();
+  }
+  static void PushPropertyName(FuncNameInferrer* fni,
+                               PreParserExpression expression) {
+    // PreParser should not use FuncNameInferrer.
+    UNREACHABLE();
   }
 
   static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
@@ -979,7 +994,6 @@ class PreParserTraits {
       int function_token_position,
       FunctionLiteral::FunctionType type,
       bool* ok);
-  PreParserExpression ParseMemberWithNewPrefixesExpression(bool* ok);
 
  private:
   PreParser* pre_parser_;
@@ -1143,10 +1157,6 @@ class PreParser : public ParserBase<PreParserTraits> {
   Statement ParseTryStatement(bool* ok);
   Statement ParseDebuggerStatement(bool* ok);
   Expression ParseConditionalExpression(bool accept_IN, bool* ok);
-  Expression ParseMemberExpression(bool* ok);
-  Expression ParseMemberExpressionContinuation(PreParserExpression expression,
-                                               bool* ok);
-  Expression ParseMemberWithNewPrefixesExpression(bool* ok);
   Expression ParseObjectLiteral(bool* ok);
   Expression ParseV8Intrinsic(bool* ok);
 
@@ -1994,6 +2004,131 @@ ParserBase<Traits>::ParseLeftHandSideExpression(bool* ok) {
 }
 
 
+template <class Traits>
+typename ParserBase<Traits>::ExpressionT
+ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) {
+  // NewExpression ::
+  //   ('new')+ MemberExpression
+
+  // The grammar for new expressions is pretty warped. We can have several 'new'
+  // keywords following each other, and then a MemberExpression. When we see '('
+  // after the MemberExpression, it's associated with the rightmost unassociated
+  // 'new' to create a NewExpression with arguments. However, a NewExpression
+  // can also occur without arguments.
+
+  // Examples of new expression:
+  // new foo.bar().baz means (new (foo.bar)()).baz
+  // new foo()() means (new foo())()
+  // new new foo()() means (new (new foo())())
+  // new new foo means new (new foo)
+  // new new foo() means new (new foo())
+  // new new foo().bar().baz means (new (new foo()).bar()).baz
+
+  if (peek() == Token::NEW) {
+    Consume(Token::NEW);
+    int new_pos = position();
+    ExpressionT result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
+    if (peek() == Token::LPAREN) {
+      // NewExpression with arguments.
+      typename Traits::Type::ExpressionList args =
+          this->ParseArguments(CHECK_OK);
+      result = factory()->NewCallNew(result, args, new_pos);
+      // The expression can still continue with . or [ after the arguments.
+      result = this->ParseMemberExpressionContinuation(result, CHECK_OK);
+      return result;
+    }
+    // NewExpression without arguments.
+    return factory()->NewCallNew(result, this->NewExpressionList(0, zone_),
+                                 new_pos);
+  }
+  // No 'new' keyword.
+  return this->ParseMemberExpression(ok);
+}
+
+
+template <class Traits>
+typename ParserBase<Traits>::ExpressionT
+ParserBase<Traits>::ParseMemberExpression(bool* ok) {
+  // MemberExpression ::
+  //   (PrimaryExpression | FunctionLiteral)
+  //     ('[' Expression ']' | '.' Identifier | Arguments)*
+
+  // The '[' Expression ']' and '.' Identifier parts are parsed by
+  // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
+  // caller.
+
+  // Parse the initial primary or function expression.
+  ExpressionT result = this->EmptyExpression();
+  if (peek() == Token::FUNCTION) {
+    Consume(Token::FUNCTION);
+    int function_token_position = position();
+    bool is_generator = allow_generators() && Check(Token::MUL);
+    IdentifierT name;
+    bool is_strict_reserved_name = false;
+    Scanner::Location function_name_location = Scanner::Location::invalid();
+    FunctionLiteral::FunctionType function_type =
+        FunctionLiteral::ANONYMOUS_EXPRESSION;
+    if (peek_any_identifier()) {
+      name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
+                                                 CHECK_OK);
+      function_name_location = scanner()->location();
+      function_type = FunctionLiteral::NAMED_EXPRESSION;
+    }
+    result = this->ParseFunctionLiteral(name,
+                                        function_name_location,
+                                        is_strict_reserved_name,
+                                        is_generator,
+                                        function_token_position,
+                                        function_type,
+                                        CHECK_OK);
+  } else {
+    result = ParsePrimaryExpression(CHECK_OK);
+  }
+
+  result = ParseMemberExpressionContinuation(result, CHECK_OK);
+  return result;
+}
+
+
+template <class Traits>
+typename ParserBase<Traits>::ExpressionT
+ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
+                                                      bool* ok) {
+  // Parses this part of MemberExpression:
+  // ('[' Expression ']' | '.' Identifier)*
+  while (true) {
+    switch (peek()) {
+      case Token::LBRACK: {
+        Consume(Token::LBRACK);
+        int pos = position();
+        ExpressionT index = this->ParseExpression(true, CHECK_OK);
+        expression = factory()->NewProperty(expression, index, pos);
+        if (fni_ != NULL) {
+          this->PushPropertyName(fni_, index);
+        }
+        Expect(Token::RBRACK, CHECK_OK);
+        break;
+      }
+      case Token::PERIOD: {
+        Consume(Token::PERIOD);
+        int pos = position();
+        IdentifierT name = ParseIdentifierName(CHECK_OK);
+        expression = factory()->NewProperty(
+            expression, factory()->NewLiteral(name, pos), pos);
+        if (fni_ != NULL) {
+          this->PushLiteralName(fni_, name);
+        }
+        break;
+      }
+      default:
+        return expression;
+    }
+  }
+  ASSERT(false);
+  return this->EmptyExpression();
+}
+
+
 #undef CHECK_OK
 #undef CHECK_OK_CUSTOM