Reviewers: adamk,

Message:
Hi Adam, this is as far as I got so far. Please feel free to grab. I just got it
to compile, but currently breaks some existing stuff. I didn't yet get to
finding out why.

Description:
[es6] Implement destructuring for `catch`

WIP

BUG=v8:811
LOG=N

Please review this at https://codereview.chromium.org/1315483004/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+73, -15 lines):
  M src/ast-value-factory.h
  M src/parser.cc
  M src/preparser.cc


Index: src/ast-value-factory.h
diff --git a/src/ast-value-factory.h b/src/ast-value-factory.h
index 359cac8133d962b3c9695dca3360c904aae83a5e..57b3e313bf6987c9b35045d1b3ff33f653fcbbc3 100644
--- a/src/ast-value-factory.h
+++ b/src/ast-value-factory.h
@@ -249,6 +249,7 @@ class AstValue : public ZoneObject {
F(default, "default") \ F(done, "done") \ F(dot, ".") \ + F(dot_catch, ".catch") \ F(dot_for, ".for") \ F(dot_generator, ".generator") \ F(dot_generator_object, ".generator_object") \
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index 9334a33195a1e21f474055863bc28dd47fa2cb93..691f9fb83f43e3905f24e7676d406711cc334201 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -3041,21 +3041,63 @@ 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);
+
+    ExpressionClassifier pattern_classifier;
+    Token::Value next = peek();
+    Expression* pattern =
+        ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
+    ValidateBindingPattern(&pattern_classifier, CHECK_OK);
+
+    if (!allow_harmony_destructuring() && !pattern->IsVariableProxy()) {
+      ReportUnexpectedToken(next);
+      *ok = false;
+      return NULL;
+    }

     Expect(Token::RPAREN, CHECK_OK);

- catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized,
-                                               Variable::NORMAL);
-    BlockState block_state(&scope_, catch_scope);
-    catch_block = ParseBlock(NULL, CHECK_OK);
+    if (pattern->IsVariableProxy()) {
+      const AstRawString* name = pattern->AsVariableProxy()->raw_name();
+ catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized,
+                                                 Variable::NORMAL);
+      BlockState block_state(&scope_, catch_scope);
+      catch_block = ParseBlock(NULL, CHECK_OK);
+    } else {
+      Variable* temp = scope_->NewTemporary(
+          ast_value_factory()->dot_catch_string());
+      Scope* destruct_scope = NewScope(catch_scope, BLOCK_SCOPE);
+      Block* destruct_block =
+          factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition);
+
+      DeclarationDescriptor descriptor;
+      descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
+      descriptor.parser = this;
+      descriptor.declaration_scope = destruct_scope->DeclarationScope();
+      descriptor.scope = destruct_scope;
+      descriptor.hoist_scope = nullptr;
+      descriptor.mode = LET;
+      descriptor.is_const = false;
+      descriptor.needs_init = true;
+      descriptor.declaration_pos = RelocInfo::kNoPosition;
+      descriptor.initialization_pos = RelocInfo::kNoPosition;
+      descriptor.init_op = Token::INIT_LET;
+      Expression* initial_value = factory()->NewVariableProxy(temp);
+
+      BlockState block_state(&scope_, destruct_scope);
+      DeclarationParsingResult::Declaration decl(
+          pattern, pattern->position(), initial_value);
+      PatternRewriter::DeclareAndInitializeVariables(
+          destruct_block, &descriptor, &decl, nullptr, CHECK_OK);
+
+      catch_block->AddStatement(destruct_block, zone());
+      catch_block = ParseBlock(NULL, CHECK_OK);
+    }

     catch_scope->set_end_position(scanner()->location().end_pos);
     tok = peek();
Index: src/preparser.cc
diff --git a/src/preparser.cc b/src/preparser.cc
index b1541f616afe133554881e99aec4f71a9f5e45e0..a104678f9fb0f43a9ea6a75d9bf8c0d127536973 100644
--- a/src/preparser.cc
+++ b/src/preparser.cc
@@ -496,15 +496,11 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
   // VariableDeclarations ::
   //   ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
   //
- // The ES6 Draft Rev3 specifies the following grammar for const declarations
-  //
   // ConstDeclaration ::
   //   const ConstBinding (',' ConstBinding)* ';'
-  // ConstBinding ::
-  //   Identifier '=' AssignmentExpression
   //
-  // TODO(ES6):
   // ConstBinding ::
+  //   Identifier '=' AssignmentExpression
   //   BindingPattern '=' AssignmentExpression
   bool require_initializer = false;
   bool is_strict_const = false;
@@ -980,6 +976,7 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
   //
   // Catch ::
   //   'catch' '(' Identifier ')' Block
+  //   'catch' '(' BindingPattern ')' Block
   //
   // Finally ::
   //   'finally' Block
@@ -997,11 +994,29 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
   if (tok == Token::CATCH) {
     Consume(Token::CATCH);
     Expect(Token::LPAREN, CHECK_OK);
-    ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
+
+    ExpressionClassifier pattern_classifier;
+    Token::Value next = peek();
+    PreParserExpression pattern =
+        ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
+    ValidateBindingPattern(&pattern_classifier, CHECK_OK);
+
+    if (!allow_harmony_destructuring() && !pattern.IsIdentifier()) {
+      ReportUnexpectedToken(next);
+      *ok = false;
+      return Statement::Default();
+    }
+
     Expect(Token::RPAREN, CHECK_OK);
-    {
-      Scope* with_scope = NewScope(scope_, WITH_SCOPE);
-      BlockState block_state(&scope_, with_scope);
+
+    if (pattern.IsIdentifier()) {
+      Scope* catch_scope = NewScope(scope_, CATCH_SCOPE);
+      BlockState block_state(&scope_, catch_scope);
+      ParseBlock(CHECK_OK);
+    } else {
+      Scope* catch_scope = NewScope(scope_, CATCH_SCOPE);
+      Scope* destruct_scope = NewScope(catch_scope, BLOCK_SCOPE);
+      BlockState block_state(&scope_, destruct_scope);
       ParseBlock(CHECK_OK);
     }
     tok = peek();


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to