Revert "Move ParseUnaryExpression into ParserBase and add tests."
authormarja@chromium.org <marja@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 19 Mar 2014 13:58:15 +0000 (13:58 +0000)
committermarja@chromium.org <marja@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 19 Mar 2014 13:58:15 +0000 (13:58 +0000)
This reverts revision 20077.

Reason: build fail on some compilers.

BUG=
TBR=marja@chromium.org,rossberg@chromium.org

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

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

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

index 0d1ba00..01bd853 100644 (file)
@@ -433,12 +433,6 @@ bool ParserTraits::IsThisProperty(Expression* expression) {
 }
 
 
-bool ParserTraits::IsIdentifier(Expression* expression) {
-  VariableProxy* operand = expression->AsVariableProxy();
-  return operand != NULL && !operand->is_this();
-}
-
-
 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
                                                            Expression* right) {
   ASSERT(left != NULL);
@@ -531,52 +525,6 @@ bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
 }
 
 
-Expression* ParserTraits::BuildUnaryExpression(
-    Expression* expression, Token::Value op, int pos,
-    AstNodeFactory<AstConstructionVisitor>* factory) {
-  ASSERT(expression != NULL);
-  if (expression->AsLiteral() != NULL) {
-    Handle<Object> literal = expression->AsLiteral()->value();
-    if (op == Token::NOT) {
-      // Convert the literal to a boolean condition and negate it.
-      bool condition = literal->BooleanValue();
-      Handle<Object> result =
-          parser_->isolate()->factory()->ToBoolean(!condition);
-      return factory->NewLiteral(result, pos);
-    } else if (literal->IsNumber()) {
-      // Compute some expressions involving only number literals.
-      double value = literal->Number();
-      switch (op) {
-        case Token::ADD:
-          return expression;
-        case Token::SUB:
-          return factory->NewNumberLiteral(-value, pos);
-        case Token::BIT_NOT:
-          return factory->NewNumberLiteral(~DoubleToInt32(value), pos);
-        default:
-          break;
-      }
-    }
-  }
-  // Desugar '+foo' => 'foo*1'
-  if (op == Token::ADD) {
-    return factory->NewBinaryOperation(
-        Token::MUL, expression, factory->NewNumberLiteral(1, pos), pos);
-  }
-  // The same idea for '-foo' => 'foo*(-1)'.
-  if (op == Token::SUB) {
-    return factory->NewBinaryOperation(
-        Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos);
-  }
-  // ...and one more time for '~foo' => 'foo^(~0)'.
-  if (op == Token::BIT_NOT) {
-    return factory->NewBinaryOperation(
-        Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos);
-  }
-  return factory->NewUnaryOperation(op, expression, pos);
-}
-
-
 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
                                    const char* message,
                                    Vector<const char*> args,
@@ -740,8 +688,8 @@ FunctionLiteral* ParserTraits::ParseFunctionLiteral(
 }
 
 
-Expression* ParserTraits::ParsePostfixExpression(bool* ok) {
-  return parser_->ParsePostfixExpression(ok);
+Expression* ParserTraits::ParseUnaryExpression(bool* ok) {
+  return parser_->ParseUnaryExpression(ok);
 }
 
 
@@ -3042,6 +2990,111 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
 }
 
 
+Expression* Parser::ParseUnaryExpression(bool* ok) {
+  // UnaryExpression ::
+  //   PostfixExpression
+  //   'delete' UnaryExpression
+  //   'void' UnaryExpression
+  //   'typeof' UnaryExpression
+  //   '++' UnaryExpression
+  //   '--' UnaryExpression
+  //   '+' UnaryExpression
+  //   '-' UnaryExpression
+  //   '~' UnaryExpression
+  //   '!' UnaryExpression
+
+  Token::Value op = peek();
+  if (Token::IsUnaryOp(op)) {
+    op = Next();
+    int pos = position();
+    Expression* expression = ParseUnaryExpression(CHECK_OK);
+
+    if (expression != NULL && (expression->AsLiteral() != NULL)) {
+      Handle<Object> literal = expression->AsLiteral()->value();
+      if (op == Token::NOT) {
+        // Convert the literal to a boolean condition and negate it.
+        bool condition = literal->BooleanValue();
+        Handle<Object> result = isolate()->factory()->ToBoolean(!condition);
+        return factory()->NewLiteral(result, pos);
+      } else if (literal->IsNumber()) {
+        // Compute some expressions involving only number literals.
+        double value = literal->Number();
+        switch (op) {
+          case Token::ADD:
+            return expression;
+          case Token::SUB:
+            return factory()->NewNumberLiteral(-value, pos);
+          case Token::BIT_NOT:
+            return factory()->NewNumberLiteral(~DoubleToInt32(value), pos);
+          default:
+            break;
+        }
+      }
+    }
+
+    // "delete identifier" is a syntax error in strict mode.
+    if (op == Token::DELETE && strict_mode() == STRICT) {
+      VariableProxy* operand = expression->AsVariableProxy();
+      if (operand != NULL && !operand->is_this()) {
+        ReportMessage("strict_delete", Vector<const char*>::empty());
+        *ok = false;
+        return NULL;
+      }
+    }
+
+    // Desugar '+foo' into 'foo*1', this enables the collection of type feedback
+    // without any special stub and the multiplication is removed later in
+    // Crankshaft's canonicalization pass.
+    if (op == Token::ADD) {
+      return factory()->NewBinaryOperation(Token::MUL,
+                                           expression,
+                                           factory()->NewNumberLiteral(1, pos),
+                                           pos);
+    }
+    // The same idea for '-foo' => 'foo*(-1)'.
+    if (op == Token::SUB) {
+      return factory()->NewBinaryOperation(Token::MUL,
+                                           expression,
+                                           factory()->NewNumberLiteral(-1, pos),
+                                           pos);
+    }
+    // ...and one more time for '~foo' => 'foo^(~0)'.
+    if (op == Token::BIT_NOT) {
+      return factory()->NewBinaryOperation(Token::BIT_XOR,
+                                           expression,
+                                           factory()->NewNumberLiteral(~0, pos),
+                                           pos);
+    }
+
+    return factory()->NewUnaryOperation(op, expression, pos);
+
+  } else if (Token::IsCountOp(op)) {
+    op = Next();
+    Scanner::Location lhs_location = scanner()->peek_location();
+    Expression* expression = ParseUnaryExpression(CHECK_OK);
+    if (expression == NULL || !expression->IsValidLeftHandSide()) {
+      ReportMessageAt(lhs_location, "invalid_lhs_in_prefix_op", true);
+      *ok = false;
+      return NULL;
+    }
+
+    if (strict_mode() == STRICT) {
+      // Prefix expression operand in strict mode may not be eval or arguments.
+      CheckStrictModeLValue(expression, CHECK_OK);
+    }
+    MarkExpressionAsLValue(expression);
+
+    return factory()->NewCountOperation(op,
+                                        true /* prefix */,
+                                        expression,
+                                        position());
+
+  } else {
+    return ParsePostfixExpression(ok);
+  }
+}
+
+
 Expression* Parser::ParsePostfixExpression(bool* ok) {
   // PostfixExpression ::
   //   LeftHandSideExpression ('++' | '--')?
index 3d2f032..072658e 100644 (file)
@@ -460,8 +460,6 @@ class ParserTraits {
   // Returns true if the expression is of type "this.foo".
   static bool IsThisProperty(Expression* expression);
 
-  static bool IsIdentifier(Expression* expression);
-
   static bool IsBoilerplateProperty(ObjectLiteral::Property* property) {
     return ObjectLiteral::IsBoilerplateProperty(property);
   }
@@ -511,21 +509,6 @@ class ParserTraits {
       Expression** x, Expression* y, Token::Value op, int pos,
       AstNodeFactory<AstConstructionVisitor>* factory);
 
-  // Rewrites the following types of unary expressions:
-  // not <literal> -> true / false
-  // + <numeric literal> -> <numeric literal>
-  // - <numeric literal> -> <numeric literal with value negated>
-  // ! <literal> -> true / false
-  // The following rewriting rules enable the collection of type feedback
-  // without any special stub and the multiplication is removed later in
-  // Crankshaft's canonicalization pass.
-  // + foo -> foo * 1
-  // - foo -> foo * (-1)
-  // ~ foo -> foo ^(~0)
-  Expression* BuildUnaryExpression(
-      Expression* expression, Token::Value op, int pos,
-      AstNodeFactory<AstConstructionVisitor>* factory);
-
   // Reporting errors.
   void ReportMessageAt(Scanner::Location source_location,
                        const char* message,
@@ -589,7 +572,7 @@ class ParserTraits {
       int function_token_position,
       FunctionLiteral::FunctionType type,
       bool* ok);
-  Expression* ParsePostfixExpression(bool* ok);
+  Expression* ParseUnaryExpression(bool* ok);
 
  private:
   Parser* parser_;
index 398f327..8a621b4 100644 (file)
@@ -146,8 +146,8 @@ PreParserExpression PreParserTraits::ParseFunctionLiteral(
 }
 
 
-PreParserExpression PreParserTraits::ParsePostfixExpression(bool* ok) {
-  return pre_parser_->ParsePostfixExpression(ok);
+PreParserExpression PreParserTraits::ParseUnaryExpression(bool* ok) {
+  return pre_parser_->ParseUnaryExpression(ok);
 }
 
 
@@ -842,6 +842,37 @@ PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
 #undef DUMMY
 
 
+PreParser::Expression PreParser::ParseUnaryExpression(bool* ok) {
+  // UnaryExpression ::
+  //   PostfixExpression
+  //   'delete' UnaryExpression
+  //   'void' UnaryExpression
+  //   'typeof' UnaryExpression
+  //   '++' UnaryExpression
+  //   '--' UnaryExpression
+  //   '+' UnaryExpression
+  //   '-' UnaryExpression
+  //   '~' UnaryExpression
+  //   '!' UnaryExpression
+
+  Token::Value op = peek();
+  if (Token::IsUnaryOp(op)) {
+    op = Next();
+    ParseUnaryExpression(ok);
+    return Expression::Default();
+  } else if (Token::IsCountOp(op)) {
+    op = Next();
+    Expression expression = ParseUnaryExpression(CHECK_OK);
+    if (strict_mode() == STRICT) {
+      CheckStrictModeLValue(expression, CHECK_OK);
+    }
+    return Expression::Default();
+  } else {
+    return ParsePostfixExpression(ok);
+  }
+}
+
+
 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
   // PostfixExpression ::
   //   LeftHandSideExpression ('++' | '--')?
index 7048c16..a060c03 100644 (file)
@@ -394,7 +394,6 @@ class ParserBase : public Traits {
   ExpressionT ParseYieldExpression(bool* ok);
   ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
   ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
-  ExpressionT ParseUnaryExpression(bool* ok);
 
   // Used to detect duplicates in object literals. Each of the values
   // kGetterProperty, kSetterProperty and kValueProperty represents
@@ -743,13 +742,6 @@ class PreParserFactory {
                                      int pos) {
     return PreParserExpression::Default();
   }
-
-  PreParserExpression NewCountOperation(Token::Value op,
-                                        bool is_prefix,
-                                        PreParserExpression expression,
-                                        int pos) {
-    return PreParserExpression::Default();
-  }
 };
 
 
@@ -802,10 +794,6 @@ class PreParserTraits {
     return expression.IsThisProperty();
   }
 
-  static bool IsIdentifier(PreParserExpression expression) {
-    return expression.IsIdentifier();
-  }
-
   static bool IsBoilerplateProperty(PreParserExpression property) {
     // PreParser doesn't count boilerplate properties.
     return false;
@@ -853,12 +841,6 @@ class PreParserTraits {
     return false;
   }
 
-  PreParserExpression BuildUnaryExpression(PreParserExpression expression,
-                                           Token::Value op, int pos,
-                                           PreParserFactory* factory) {
-    return PreParserExpression::Default();
-  }
-
   // Reporting errors.
   void ReportMessageAt(Scanner::Location location,
                        const char* message,
@@ -940,7 +922,7 @@ class PreParserTraits {
       int function_token_position,
       FunctionLiteral::FunctionType type,
       bool* ok);
-  PreParserExpression ParsePostfixExpression(bool* ok);
+  PreParserExpression ParseUnaryExpression(bool* ok);
 
  private:
   PreParser* pre_parser_;
@@ -1104,6 +1086,7 @@ class PreParser : public ParserBase<PreParserTraits> {
   Statement ParseTryStatement(bool* ok);
   Statement ParseDebuggerStatement(bool* ok);
   Expression ParseConditionalExpression(bool accept_IN, bool* ok);
+  Expression ParseUnaryExpression(bool* ok);
   Expression ParsePostfixExpression(bool* ok);
   Expression ParseLeftHandSideExpression(bool* ok);
   Expression ParseMemberExpression(bool* ok);
@@ -1795,64 +1778,6 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
 }
 
 
-template <class Traits>
-typename ParserBase<Traits>::ExpressionT
-ParserBase<Traits>::ParseUnaryExpression(bool* ok) {
-  // UnaryExpression ::
-  //   PostfixExpression
-  //   'delete' UnaryExpression
-  //   'void' UnaryExpression
-  //   'typeof' UnaryExpression
-  //   '++' UnaryExpression
-  //   '--' UnaryExpression
-  //   '+' UnaryExpression
-  //   '-' UnaryExpression
-  //   '~' UnaryExpression
-  //   '!' UnaryExpression
-
-  Token::Value op = peek();
-  if (Token::IsUnaryOp(op)) {
-    op = Next();
-    int pos = position();
-    ExpressionT expression = ParseUnaryExpression(CHECK_OK);
-
-    // "delete identifier" is a syntax error in strict mode.
-    if (op == Token::DELETE && strict_mode() == STRICT &&
-        this->IsIdentifier(expression)) {
-      ReportMessage("strict_delete", Vector<const char*>::empty());
-      *ok = false;
-      return this->EmptyExpression();
-    }
-
-    // Allow Traits do rewrite the expression.
-    return BuildUnaryExpression(expression, op, pos, factory());
-  } else if (Token::IsCountOp(op)) {
-    op = Next();
-    Scanner::Location lhs_location = scanner()->peek_location();
-    ExpressionT expression = ParseUnaryExpression(CHECK_OK);
-    if (!this->IsValidLeftHandSide(expression)) {
-      ReportMessageAt(lhs_location, "invalid_lhs_in_prefix_op", true);
-      *ok = false;
-      return this->EmptyExpression();
-    }
-
-    if (strict_mode() == STRICT) {
-      // Prefix expression operand in strict mode may not be eval or arguments.
-      CheckStrictModeLValue(expression, CHECK_OK);
-    }
-    MarkExpressionAsLValue(expression);
-
-    return factory()->NewCountOperation(op,
-                                        true /* prefix */,
-                                        expression,
-                                        position());
-
-  } else {
-    return this->ParsePostfixExpression(ok);
-  }
-}
-
-
 #undef CHECK_OK
 #undef CHECK_OK_CUSTOM
 
index c88b2dc..5a2ee13 100644 (file)
@@ -2472,57 +2472,3 @@ TEST(TooManyArguments) {
   static const ParserFlag empty_flags[] = {kAllowLazy};
   RunParserSyncTest(context_data, statement_data, kError, empty_flags, 1);
 }
-
-
-TEST(StrictDelete) {
-  // "delete <Identifier>" is not allowed in strict mode.
-  const char* strict_context_data[][2] = {
-    {"\"use strict\"; ", ""},
-    { NULL, NULL }
-  };
-
-  const char* sloppy_context_data[][2] = {
-    {"", ""},
-    { NULL, NULL }
-  };
-
-  // These are errors in the strict mode.
-  const char* sloppy_statement_data[] = {
-    "delete foo;",
-    "delete foo + 1;",
-    "delete (foo);",
-    "delete eval;",
-    "delete interface;",
-    NULL
-  };
-
-  // These are always OK
-  const char* good_statement_data[] = {
-    "delete this;",
-    "delete 1;",
-    "delete 1 + 2;",
-    "delete foo();",
-    "delete foo.bar;",
-    "delete foo[bar];",
-    "delete foo--;",
-    "delete --foo;",
-    "delete new foo();",
-    "delete new foo(bar);",
-    NULL
-  };
-
-  // These are always errors
-  const char* bad_statement_data[] = {
-    "delete if;",
-    NULL
-  };
-
-  RunParserSyncTest(strict_context_data, sloppy_statement_data, kError);
-  RunParserSyncTest(sloppy_context_data, sloppy_statement_data, kSuccess);
-
-  RunParserSyncTest(strict_context_data, good_statement_data, kSuccess);
-  RunParserSyncTest(sloppy_context_data, good_statement_data, kSuccess);
-
-  RunParserSyncTest(strict_context_data, bad_statement_data, kError);
-  RunParserSyncTest(sloppy_context_data, bad_statement_data, kError);
-}