Commit ff1c294c authored by marja@chromium.org's avatar marja@chromium.org

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
parent 77441346
...@@ -2486,23 +2486,21 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { ...@@ -2486,23 +2486,21 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
if (peek() == Token::LBRACE) { Target target(&this->target_stack_, &catch_collector);
Target target(&this->target_stack_, &catch_collector); VariableMode mode = is_extended_mode() ? LET : VAR;
VariableMode mode = is_extended_mode() ? LET : VAR; catch_variable =
catch_variable = catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
BlockState block_state(this, catch_scope);
BlockState block_state(this, catch_scope); catch_block = ParseBlock(NULL, CHECK_OK);
catch_block = ParseBlock(NULL, CHECK_OK);
} else {
Expect(Token::LBRACE, CHECK_OK);
}
catch_scope->set_end_position(scanner().location().end_pos); catch_scope->set_end_position(scanner().location().end_pos);
tok = peek(); tok = peek();
} }
Block* finally_block = NULL; 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); Consume(Token::FINALLY);
finally_block = ParseBlock(NULL, CHECK_OK); finally_block = ParseBlock(NULL, CHECK_OK);
} }
......
...@@ -699,15 +699,17 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) { ...@@ -699,15 +699,17 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
// Finally :: // Finally ::
// 'finally' Block // 'finally' Block
// In preparsing, allow any number of catch/finally blocks, including zero
// of both.
Expect(Token::TRY, CHECK_OK); Expect(Token::TRY, CHECK_OK);
ParseBlock(CHECK_OK); ParseBlock(CHECK_OK);
bool catch_or_finally_seen = false; Token::Value tok = peek();
if (peek() == Token::CATCH) { 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); Consume(Token::CATCH);
Expect(Token::LPAREN, CHECK_OK); Expect(Token::LPAREN, CHECK_OK);
ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
...@@ -715,15 +717,11 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) { ...@@ -715,15 +717,11 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
{ Scope::InsideWith iw(scope_); { Scope::InsideWith iw(scope_);
ParseBlock(CHECK_OK); ParseBlock(CHECK_OK);
} }
catch_or_finally_seen = true; tok = peek();
} }
if (peek() == Token::FINALLY) { if (tok == Token::FINALLY) {
Consume(Token::FINALLY); Consume(Token::FINALLY);
ParseBlock(CHECK_OK); ParseBlock(CHECK_OK);
catch_or_finally_seen = true;
}
if (!catch_or_finally_seen) {
*ok = false;
} }
return Statement::Default(); return Statement::Default();
} }
......
...@@ -1977,3 +1977,39 @@ TEST(FunctionDeclaresItselfStrict) { ...@@ -1977,3 +1977,39 @@ TEST(FunctionDeclaresItselfStrict) {
RunParserSyncTest(context_data, strict_statement_data, kError); RunParserSyncTest(context_data, strict_statement_data, kError);
RunParserSyncTest(context_data, non_strict_statement_data, kSuccess); 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment