Chromium Code Reviews| Index: src/parser.cc |
| diff --git a/src/parser.cc b/src/parser.cc |
| index b54172f72c21cc6ccf320ed04877227804a5d134..4b0ac64b7fd0b4792c7de4c2f87abc30c381b513 100644 |
| --- a/src/parser.cc |
| +++ b/src/parser.cc |
| @@ -3148,21 +3148,80 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { |
| Scope* catch_scope = NULL; |
| Variable* catch_variable = NULL; |
| Block* catch_block = NULL; |
| - const AstRawString* name = NULL; |
| if (tok == Token::CATCH) { |
| Consume(Token::CATCH); |
| Expect(Token::LPAREN, CHECK_OK); |
| catch_scope = NewScope(scope_, CATCH_SCOPE); |
| catch_scope->set_start_position(scanner()->location().beg_pos); |
| - name = ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); |
| - Expect(Token::RPAREN, CHECK_OK); |
| + ExpressionClassifier pattern_classifier; |
| + Expression* pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK); |
| + ValidateBindingPattern(&pattern_classifier, CHECK_OK); |
| + |
| + bool is_simple = false; |
|
rossberg
2015/11/03 12:00:50
Nit: why not `is_simple = pattern->IsVariableProxy
adamk
2015/11/03 20:35:20
Done.
|
| + const AstRawString* name = ast_value_factory()->dot_catch_string(); |
| + if (pattern->IsVariableProxy()) { |
| + is_simple = true; |
| + auto proxy = pattern->AsVariableProxy(); |
| + scope_->RemoveUnresolved(proxy); |
| + name = proxy->raw_name(); |
| + } |
| catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized, |
| Variable::NORMAL); |
| - BlockState block_state(&scope_, catch_scope); |
| - catch_block = ParseBlock(NULL, CHECK_OK); |
| + |
| + Expect(Token::RPAREN, CHECK_OK); |
| + |
| + { |
| + BlockState block_state(&scope_, catch_scope); |
| + |
| + // TODO(adamk): Make a version of ParseScopedBlock that takes a scope and |
| + // a block. |
| + catch_block = |
| + factory()->NewBlock(nullptr, 16, false, RelocInfo::kNoPosition); |
| + Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); |
| + |
| + block_scope->set_start_position(scanner()->location().beg_pos); |
| + { |
| + BlockState block_state(&scope_, block_scope); |
| + Target target(&this->target_stack_, catch_block); |
| + |
| + if (!is_simple) { |
| + DeclarationDescriptor descriptor; |
| + descriptor.declaration_kind = DeclarationDescriptor::NORMAL; |
| + descriptor.parser = this; |
| + descriptor.declaration_scope = |
| + scope_->DeclarationScope(); // is this right? |
|
rossberg
2015/11/03 12:00:50
Judging from how it's set in the other cases, this
adamk
2015/11/03 20:35:20
There's definitely some refactoring to be done her
|
| + descriptor.scope = scope_; |
| + descriptor.hoist_scope = nullptr; |
| + descriptor.mode = LET; |
| + descriptor.is_const = false; |
| + descriptor.needs_init = true; |
| + descriptor.declaration_pos = pattern->position(); |
| + descriptor.init_op = Token::INIT_LET; |
| + |
| + DeclarationParsingResult::Declaration decl( |
| + pattern, pattern->position(), |
| + factory()->NewVariableProxy(catch_variable)); |
| + |
| + PatternRewriter::DeclareAndInitializeVariables( |
| + catch_block, &descriptor, &decl, nullptr, CHECK_OK); |
| + } |
| + |
| + Expect(Token::LBRACE, CHECK_OK); |
| + while (peek() != Token::RBRACE) { |
| + Statement* stat = ParseStatementListItem(CHECK_OK); |
| + if (stat && !stat->IsEmpty()) { |
| + catch_block->statements()->Add(stat, zone()); |
| + } |
| + } |
| + Consume(Token::RBRACE); |
| + } |
| + block_scope->set_end_position(scanner()->location().end_pos); |
| + block_scope = block_scope->FinalizeBlockScope(); |
| + catch_block->set_scope(block_scope); |
| + } |
| catch_scope->set_end_position(scanner()->location().end_pos); |
| tok = peek(); |