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) {
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);
}
......
......@@ -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();
}
......
......@@ -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);
}
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