Unify (Pre)Parser::ParseTryStatement.
authormarja@chromium.org <marja@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 10 Feb 2014 08:45:13 +0000 (08:45 +0000)
committermarja@chromium.org <marja@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 10 Feb 2014 08:45:13 +0000 (08:45 +0000)
Notes:
- This makes Parser and PreParser produce the same errors with the added test
cases (this was not the case before).
- ParseBlock already does Expect(Token::LBRACE), so no need to check it twice.

BUG=v8:3126
LOG=N
R=mstarzinger@chromium.org

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

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

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

index 54a83e8..5e7680e 100644 (file)
@@ -2486,23 +2486,21 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
 
     Expect(Token::RPAREN, CHECK_OK);
 
-    if (peek() == Token::LBRACE) {
-      Target target(&this->target_stack_, &catch_collector);
-      VariableMode mode = is_extended_mode() ? LET : VAR;
-      catch_variable =
-          catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
-
-      BlockState block_state(this, catch_scope);
-      catch_block = ParseBlock(NULL, CHECK_OK);
-    } else {
-      Expect(Token::LBRACE, CHECK_OK);
-    }
+    Target target(&this->target_stack_, &catch_collector);
+    VariableMode mode = is_extended_mode() ? LET : VAR;
+    catch_variable =
+        catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
+
+    BlockState block_state(this, catch_scope);
+    catch_block = ParseBlock(NULL, CHECK_OK);
+
     catch_scope->set_end_position(scanner().location().end_pos);
     tok = peek();
   }
 
   Block* finally_block = NULL;
-  if (tok == Token::FINALLY || catch_block == NULL) {
+  ASSERT(tok == Token::FINALLY || catch_block != NULL);
+  if (tok == Token::FINALLY) {
     Consume(Token::FINALLY);
     finally_block = ParseBlock(NULL, CHECK_OK);
   }
index 49d6cd2..fa6f217 100644 (file)
@@ -699,15 +699,17 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
   // Finally ::
   //   'finally' Block
 
-  // In preparsing, allow any number of catch/finally blocks, including zero
-  // of both.
-
   Expect(Token::TRY, CHECK_OK);
 
   ParseBlock(CHECK_OK);
 
-  bool catch_or_finally_seen = false;
-  if (peek() == Token::CATCH) {
+  Token::Value tok = peek();
+  if (tok != Token::CATCH && tok != Token::FINALLY) {
+    ReportMessageAt(scanner()->location(), "no_catch_or_finally", NULL);
+    *ok = false;
+    return Statement::Default();
+  }
+  if (tok == Token::CATCH) {
     Consume(Token::CATCH);
     Expect(Token::LPAREN, CHECK_OK);
     ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
@@ -715,15 +717,11 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
     { Scope::InsideWith iw(scope_);
       ParseBlock(CHECK_OK);
     }
-    catch_or_finally_seen = true;
+    tok = peek();
   }
-  if (peek() == Token::FINALLY) {
+  if (tok == Token::FINALLY) {
     Consume(Token::FINALLY);
     ParseBlock(CHECK_OK);
-    catch_or_finally_seen = true;
-  }
-  if (!catch_or_finally_seen) {
-    *ok = false;
   }
   return Statement::Default();
 }
index 85b2f3c..22d5056 100644 (file)
@@ -1977,3 +1977,39 @@ TEST(FunctionDeclaresItselfStrict) {
   RunParserSyncTest(context_data, strict_statement_data, kError);
   RunParserSyncTest(context_data, non_strict_statement_data, kSuccess);
 }
+
+
+TEST(ErrorsTryWithoutCatchOrFinally) {
+  const char* context_data[][2] = {
+    {"", ""},
+    { NULL, NULL }
+  };
+
+  const char* statement_data[] = {
+    "try { }",
+    "try { } foo();",
+    "try { } catch (e) foo();",
+    "try { } catch { }",
+    "try { } finally foo();",
+    NULL
+  };
+
+  RunParserSyncTest(context_data, statement_data, kError);
+}
+
+
+TEST(NoErrorsTryCatchFinally) {
+  const char* context_data[][2] = {
+    {"", ""},
+    { NULL, NULL }
+  };
+
+  const char* statement_data[] = {
+    "try { } catch (e) { }",
+    "try { } catch (e) { } finally { }",
+    "try { } finally { }",
+    NULL
+  };
+
+  RunParserSyncTest(context_data, statement_data, kSuccess);
+}