From ff1c294cf90845302fb4647596c835dae1095a76 Mon Sep 17 00:00:00 2001 From: "marja@chromium.org" Date: Mon, 10 Feb 2014 08:45:13 +0000 Subject: [PATCH] Unify (Pre)Parser::ParseTryStatement. 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 | 22 ++++++++++------------ src/preparser.cc | 20 +++++++++----------- test/cctest/test-parsing.cc | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 23 deletions(-) diff --git a/src/parser.cc b/src/parser.cc index 54a83e8..5e7680e 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -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); } diff --git a/src/preparser.cc b/src/preparser.cc index 49d6cd2..fa6f217 100644 --- a/src/preparser.cc +++ b/src/preparser.cc @@ -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(); } diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc index 85b2f3c..22d5056 100644 --- a/test/cctest/test-parsing.cc +++ b/test/cctest/test-parsing.cc @@ -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); +} -- 2.7.4