Upgrade V8 to version 4.9.385.28

https://chromium.googlesource.com/v8/v8/+/4.9.385.28

FPIIM-449

Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/parsing/pattern-rewriter.cc b/src/parsing/pattern-rewriter.cc
new file mode 100644
index 0000000..6e20282
--- /dev/null
+++ b/src/parsing/pattern-rewriter.cc
@@ -0,0 +1,628 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/ast/ast.h"
+#include "src/messages.h"
+#include "src/parsing/parameter-initializer-rewriter.h"
+#include "src/parsing/parser.h"
+
+namespace v8 {
+
+namespace internal {
+
+void Parser::PatternRewriter::DeclareAndInitializeVariables(
+    Block* block, const DeclarationDescriptor* declaration_descriptor,
+    const DeclarationParsingResult::Declaration* declaration,
+    ZoneList<const AstRawString*>* names, bool* ok) {
+  PatternRewriter rewriter;
+
+  rewriter.scope_ = declaration_descriptor->scope;
+  rewriter.parser_ = declaration_descriptor->parser;
+  rewriter.context_ = BINDING;
+  rewriter.pattern_ = declaration->pattern;
+  rewriter.initializer_position_ = declaration->initializer_position;
+  rewriter.block_ = block;
+  rewriter.descriptor_ = declaration_descriptor;
+  rewriter.names_ = names;
+  rewriter.ok_ = ok;
+  rewriter.recursion_level_ = 0;
+
+  rewriter.RecurseIntoSubpattern(rewriter.pattern_, declaration->initializer);
+}
+
+
+void Parser::PatternRewriter::RewriteDestructuringAssignment(
+    Parser* parser, RewritableAssignmentExpression* to_rewrite, Scope* scope) {
+  PatternRewriter rewriter;
+
+  DCHECK(!to_rewrite->is_rewritten());
+
+  bool ok = true;
+  rewriter.scope_ = scope;
+  rewriter.parser_ = parser;
+  rewriter.context_ = ASSIGNMENT;
+  rewriter.pattern_ = to_rewrite;
+  rewriter.block_ = nullptr;
+  rewriter.descriptor_ = nullptr;
+  rewriter.names_ = nullptr;
+  rewriter.ok_ = &ok;
+  rewriter.recursion_level_ = 0;
+
+  rewriter.RecurseIntoSubpattern(rewriter.pattern_, nullptr);
+  DCHECK(ok);
+}
+
+
+Expression* Parser::PatternRewriter::RewriteDestructuringAssignment(
+    Parser* parser, Assignment* assignment, Scope* scope) {
+  DCHECK_NOT_NULL(assignment);
+  DCHECK_EQ(Token::ASSIGN, assignment->op());
+  auto to_rewrite =
+      parser->factory()->NewRewritableAssignmentExpression(assignment);
+  RewriteDestructuringAssignment(parser, to_rewrite, scope);
+  return to_rewrite->expression();
+}
+
+
+bool Parser::PatternRewriter::IsAssignmentContext(PatternContext c) const {
+  return c == ASSIGNMENT || c == ASSIGNMENT_INITIALIZER;
+}
+
+
+bool Parser::PatternRewriter::IsBindingContext(PatternContext c) const {
+  return c == BINDING || c == INITIALIZER;
+}
+
+
+Parser::PatternRewriter::PatternContext
+Parser::PatternRewriter::SetAssignmentContextIfNeeded(Expression* node) {
+  PatternContext old_context = context();
+  if (node->IsAssignment() && node->AsAssignment()->op() == Token::ASSIGN) {
+    set_context(ASSIGNMENT);
+  }
+  return old_context;
+}
+
+
+Parser::PatternRewriter::PatternContext
+Parser::PatternRewriter::SetInitializerContextIfNeeded(Expression* node) {
+  // Set appropriate initializer context for BindingElement and
+  // AssignmentElement nodes
+  PatternContext old_context = context();
+  bool is_destructuring_assignment =
+      node->IsRewritableAssignmentExpression() &&
+      !node->AsRewritableAssignmentExpression()->is_rewritten();
+  bool is_assignment =
+      node->IsAssignment() && node->AsAssignment()->op() == Token::ASSIGN;
+  if (is_destructuring_assignment || is_assignment) {
+    switch (old_context) {
+      case BINDING:
+        set_context(INITIALIZER);
+        break;
+      case ASSIGNMENT:
+        set_context(ASSIGNMENT_INITIALIZER);
+        break;
+      default:
+        break;
+    }
+  }
+  return old_context;
+}
+
+
+void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
+  Expression* value = current_value_;
+
+  if (IsAssignmentContext()) {
+    // In an assignment context, simply perform the assignment
+    Assignment* assignment = factory()->NewAssignment(
+        Token::ASSIGN, pattern, value, pattern->position());
+    block_->statements()->Add(
+        factory()->NewExpressionStatement(assignment, pattern->position()),
+        zone());
+    return;
+  }
+
+  descriptor_->scope->RemoveUnresolved(pattern);
+
+  // Declare variable.
+  // Note that we *always* must treat the initial value via a separate init
+  // assignment for variables and constants because the value must be assigned
+  // when the variable is encountered in the source. But the variable/constant
+  // is declared (and set to 'undefined') upon entering the function within
+  // which the variable or constant is declared. Only function variables have
+  // an initial value in the declaration (because they are initialized upon
+  // entering the function).
+  //
+  // If we have a legacy const declaration, in an inner scope, the proxy
+  // is always bound to the declared variable (independent of possibly
+  // surrounding 'with' statements).
+  // For let/const declarations in harmony mode, we can also immediately
+  // pre-resolve the proxy because it resides in the same scope as the
+  // declaration.
+  const AstRawString* name = pattern->raw_name();
+  VariableProxy* proxy = parser_->NewUnresolved(name, descriptor_->mode);
+  Declaration* declaration = factory()->NewVariableDeclaration(
+      proxy, descriptor_->mode, descriptor_->scope,
+      descriptor_->declaration_pos);
+  Variable* var =
+      parser_->Declare(declaration, descriptor_->declaration_kind,
+                       descriptor_->mode != VAR, ok_, descriptor_->hoist_scope);
+  if (!*ok_) return;
+  DCHECK_NOT_NULL(var);
+  DCHECK(!proxy->is_resolved() || proxy->var() == var);
+  var->set_initializer_position(initializer_position_);
+
+  DCHECK(initializer_position_ != RelocInfo::kNoPosition);
+
+  Scope* declaration_scope = IsLexicalVariableMode(descriptor_->mode)
+                                 ? descriptor_->scope
+                                 : descriptor_->scope->DeclarationScope();
+  if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
+    parser_->ReportMessage(MessageTemplate::kTooManyVariables);
+    *ok_ = false;
+    return;
+  }
+  if (names_) {
+    names_->Add(name, zone());
+  }
+
+  // Initialize variables if needed. A
+  // declaration of the form:
+  //
+  //    var v = x;
+  //
+  // is syntactic sugar for:
+  //
+  //    var v; v = x;
+  //
+  // In particular, we need to re-lookup 'v' (in scope_, not
+  // declaration_scope) as it may be a different 'v' than the 'v' in the
+  // declaration (e.g., if we are inside a 'with' statement or 'catch'
+  // block).
+  //
+  // However, note that const declarations are different! A const
+  // declaration of the form:
+  //
+  //   const c = x;
+  //
+  // is *not* syntactic sugar for:
+  //
+  //   const c; c = x;
+  //
+  // The "variable" c initialized to x is the same as the declared
+  // one - there is no re-lookup (see the last parameter of the
+  // Declare() call above).
+  Scope* initialization_scope = IsImmutableVariableMode(descriptor_->mode)
+                                    ? declaration_scope
+                                    : descriptor_->scope;
+
+
+  // Global variable declarations must be compiled in a specific
+  // way. When the script containing the global variable declaration
+  // is entered, the global variable must be declared, so that if it
+  // doesn't exist (on the global object itself, see ES5 errata) it
+  // gets created with an initial undefined value. This is handled
+  // by the declarations part of the function representing the
+  // top-level global code; see Runtime::DeclareGlobalVariable. If
+  // it already exists (in the object or in a prototype), it is
+  // *not* touched until the variable declaration statement is
+  // executed.
+  //
+  // Executing the variable declaration statement will always
+  // guarantee to give the global object an own property.
+  // This way, global variable declarations can shadow
+  // properties in the prototype chain, but only after the variable
+  // declaration statement has been executed. This is important in
+  // browsers where the global object (window) has lots of
+  // properties defined in prototype objects.
+  if (initialization_scope->is_script_scope() &&
+      !IsLexicalVariableMode(descriptor_->mode)) {
+    // Compute the arguments for the runtime
+    // call.test-parsing/InitializedDeclarationsInStrictForOfError
+    ZoneList<Expression*>* arguments =
+        new (zone()) ZoneList<Expression*>(3, zone());
+    // We have at least 1 parameter.
+    arguments->Add(
+        factory()->NewStringLiteral(name, descriptor_->declaration_pos),
+        zone());
+    CallRuntime* initialize;
+
+    if (IsImmutableVariableMode(descriptor_->mode)) {
+      arguments->Add(value, zone());
+      value = NULL;  // zap the value to avoid the unnecessary assignment
+
+      // Construct the call to Runtime_InitializeConstGlobal
+      // and add it to the initialization statement block.
+      // Note that the function does different things depending on
+      // the number of arguments (1 or 2).
+      initialize =
+          factory()->NewCallRuntime(Runtime::kInitializeConstGlobal, arguments,
+                                    descriptor_->initialization_pos);
+    } else {
+      // Add language mode.
+      // We may want to pass singleton to avoid Literal allocations.
+      LanguageMode language_mode = initialization_scope->language_mode();
+      arguments->Add(factory()->NewNumberLiteral(language_mode,
+                                                 descriptor_->declaration_pos),
+                     zone());
+
+      // Be careful not to assign a value to the global variable if
+      // we're in a with. The initialization value should not
+      // necessarily be stored in the global object in that case,
+      // which is why we need to generate a separate assignment node.
+      if (value != NULL && !descriptor_->scope->inside_with()) {
+        arguments->Add(value, zone());
+        value = NULL;  // zap the value to avoid the unnecessary assignment
+        // Construct the call to Runtime_InitializeVarGlobal
+        // and add it to the initialization statement block.
+        initialize =
+            factory()->NewCallRuntime(Runtime::kInitializeVarGlobal, arguments,
+                                      descriptor_->declaration_pos);
+      } else {
+        initialize = NULL;
+      }
+    }
+
+    if (initialize != NULL) {
+      block_->statements()->Add(
+          factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition),
+          zone());
+    }
+  } else if (value != nullptr && (descriptor_->mode == CONST_LEGACY ||
+                                  IsLexicalVariableMode(descriptor_->mode))) {
+    // Constant initializations always assign to the declared constant which
+    // is always at the function scope level. This is only relevant for
+    // dynamically looked-up variables and constants (the
+    // start context for constant lookups is always the function context,
+    // while it is the top context for var declared variables). Sigh...
+    // For 'let' and 'const' declared variables in harmony mode the
+    // initialization also always assigns to the declared variable.
+    DCHECK_NOT_NULL(proxy);
+    DCHECK_NOT_NULL(proxy->var());
+    DCHECK_NOT_NULL(value);
+    // Add break location for destructured sub-pattern.
+    int pos = IsSubPattern() ? pattern->position() : RelocInfo::kNoPosition;
+    Assignment* assignment =
+        factory()->NewAssignment(Token::INIT, proxy, value, pos);
+    block_->statements()->Add(
+        factory()->NewExpressionStatement(assignment, pos), zone());
+    value = NULL;
+  }
+
+  // Add an assignment node to the initialization statement block if we still
+  // have a pending initialization value.
+  if (value != NULL) {
+    DCHECK(descriptor_->mode == VAR);
+    // 'var' initializations are simply assignments (with all the consequences
+    // if they are inside a 'with' statement - they may change a 'with' object
+    // property).
+    VariableProxy* proxy = initialization_scope->NewUnresolved(factory(), name);
+    // Add break location for destructured sub-pattern.
+    int pos = IsSubPattern() ? pattern->position() : RelocInfo::kNoPosition;
+    Assignment* assignment =
+        factory()->NewAssignment(Token::INIT, proxy, value, pos);
+    block_->statements()->Add(
+        factory()->NewExpressionStatement(assignment, pos), zone());
+  }
+}
+
+
+Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) {
+  auto temp = scope()->NewTemporary(ast_value_factory()->empty_string());
+  if (value != nullptr) {
+    auto assignment = factory()->NewAssignment(
+        Token::ASSIGN, factory()->NewVariableProxy(temp), value,
+        RelocInfo::kNoPosition);
+
+    block_->statements()->Add(
+        factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
+        zone());
+  }
+  return temp;
+}
+
+
+void Parser::PatternRewriter::VisitRewritableAssignmentExpression(
+    RewritableAssignmentExpression* node) {
+  if (!IsAssignmentContext()) {
+    // Mark the assignment as rewritten to prevent redundant rewriting, and
+    // perform BindingPattern rewriting
+    DCHECK(!node->is_rewritten());
+    node->Rewrite(node->expression());
+    return node->expression()->Accept(this);
+  }
+
+  if (node->is_rewritten()) return;
+  DCHECK(IsAssignmentContext());
+  Assignment* assign = node->expression()->AsAssignment();
+  DCHECK_NOT_NULL(assign);
+  DCHECK_EQ(Token::ASSIGN, assign->op());
+
+  auto initializer = assign->value();
+  auto value = initializer;
+
+  if (IsInitializerContext()) {
+    // let {<pattern> = <init>} = <value>
+    //   becomes
+    // temp = <value>;
+    // <pattern> = temp === undefined ? <init> : temp;
+    auto temp_var = CreateTempVar(current_value_);
+    Expression* is_undefined = factory()->NewCompareOperation(
+        Token::EQ_STRICT, factory()->NewVariableProxy(temp_var),
+        factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
+        RelocInfo::kNoPosition);
+    value = factory()->NewConditional(is_undefined, initializer,
+                                      factory()->NewVariableProxy(temp_var),
+                                      RelocInfo::kNoPosition);
+  }
+
+  PatternContext old_context = SetAssignmentContextIfNeeded(initializer);
+  int pos = assign->position();
+  Block* old_block = block_;
+  block_ = factory()->NewBlock(nullptr, 8, false, pos);
+  Variable* temp = nullptr;
+  Expression* pattern = assign->target();
+  Expression* old_value = current_value_;
+  current_value_ = value;
+  if (pattern->IsObjectLiteral()) {
+    VisitObjectLiteral(pattern->AsObjectLiteral(), &temp);
+  } else {
+    DCHECK(pattern->IsArrayLiteral());
+    VisitArrayLiteral(pattern->AsArrayLiteral(), &temp);
+  }
+  DCHECK_NOT_NULL(temp);
+  current_value_ = old_value;
+  Expression* expr = factory()->NewDoExpression(block_, temp, pos);
+  node->Rewrite(expr);
+  block_ = old_block;
+  if (block_) {
+    block_->statements()->Add(factory()->NewExpressionStatement(expr, pos),
+                              zone());
+  }
+  return set_context(old_context);
+}
+
+
+void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern,
+                                                 Variable** temp_var) {
+  auto temp = *temp_var = CreateTempVar(current_value_);
+
+  block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone());
+
+  for (ObjectLiteralProperty* property : *pattern->properties()) {
+    PatternContext context = SetInitializerContextIfNeeded(property->value());
+    RecurseIntoSubpattern(
+        property->value(),
+        factory()->NewProperty(factory()->NewVariableProxy(temp),
+                               property->key(), RelocInfo::kNoPosition));
+    set_context(context);
+  }
+}
+
+
+void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* node) {
+  Variable* temp_var = nullptr;
+  VisitObjectLiteral(node, &temp_var);
+}
+
+
+void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node,
+                                                Variable** temp_var) {
+  auto temp = *temp_var = CreateTempVar(current_value_);
+
+  block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone());
+
+  auto iterator = CreateTempVar(parser_->GetIterator(
+      factory()->NewVariableProxy(temp), factory(), RelocInfo::kNoPosition));
+  auto done = CreateTempVar(
+      factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition));
+  auto result = CreateTempVar();
+  auto v = CreateTempVar();
+
+  Spread* spread = nullptr;
+  for (Expression* value : *node->values()) {
+    if (value->IsSpread()) {
+      spread = value->AsSpread();
+      break;
+    }
+
+    PatternContext context = SetInitializerContextIfNeeded(value);
+    // if (!done) {
+    //   result = IteratorNext(iterator);
+    //   v = (done = result.done) ? undefined : result.value;
+    // }
+    auto next_block =
+        factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition);
+    next_block->statements()->Add(factory()->NewExpressionStatement(
+                                      parser_->BuildIteratorNextResult(
+                                          factory()->NewVariableProxy(iterator),
+                                          result, RelocInfo::kNoPosition),
+                                      RelocInfo::kNoPosition),
+                                  zone());
+
+    auto assign_to_done = factory()->NewAssignment(
+        Token::ASSIGN, factory()->NewVariableProxy(done),
+        factory()->NewProperty(
+            factory()->NewVariableProxy(result),
+            factory()->NewStringLiteral(ast_value_factory()->done_string(),
+                                        RelocInfo::kNoPosition),
+            RelocInfo::kNoPosition),
+        RelocInfo::kNoPosition);
+    auto next_value = factory()->NewConditional(
+        assign_to_done, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
+        factory()->NewProperty(
+            factory()->NewVariableProxy(result),
+            factory()->NewStringLiteral(ast_value_factory()->value_string(),
+                                        RelocInfo::kNoPosition),
+            RelocInfo::kNoPosition),
+        RelocInfo::kNoPosition);
+    next_block->statements()->Add(
+        factory()->NewExpressionStatement(
+            factory()->NewAssignment(Token::ASSIGN,
+                                     factory()->NewVariableProxy(v), next_value,
+                                     RelocInfo::kNoPosition),
+            RelocInfo::kNoPosition),
+        zone());
+
+    auto if_statement = factory()->NewIfStatement(
+        factory()->NewUnaryOperation(Token::NOT,
+                                     factory()->NewVariableProxy(done),
+                                     RelocInfo::kNoPosition),
+        next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition),
+        RelocInfo::kNoPosition);
+    block_->statements()->Add(if_statement, zone());
+
+    if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) {
+      RecurseIntoSubpattern(value, factory()->NewVariableProxy(v));
+    }
+    set_context(context);
+  }
+
+  if (spread != nullptr) {
+    // array = [];
+    // if (!done) %concat_iterable_to_array(array, iterator);
+    auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone());
+    auto array = CreateTempVar(factory()->NewArrayLiteral(
+        empty_exprs,
+        // Reuse pattern's literal index - it is unused since there is no
+        // actual literal allocated.
+        node->literal_index(), is_strong(scope()->language_mode()),
+        RelocInfo::kNoPosition));
+
+    auto arguments = new (zone()) ZoneList<Expression*>(2, zone());
+    arguments->Add(factory()->NewVariableProxy(array), zone());
+    arguments->Add(factory()->NewVariableProxy(iterator), zone());
+    auto spread_into_array_call =
+        factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX,
+                                  arguments, RelocInfo::kNoPosition);
+
+    auto if_statement = factory()->NewIfStatement(
+        factory()->NewUnaryOperation(Token::NOT,
+                                     factory()->NewVariableProxy(done),
+                                     RelocInfo::kNoPosition),
+        factory()->NewExpressionStatement(spread_into_array_call,
+                                          RelocInfo::kNoPosition),
+        factory()->NewEmptyStatement(RelocInfo::kNoPosition),
+        RelocInfo::kNoPosition);
+    block_->statements()->Add(if_statement, zone());
+
+    RecurseIntoSubpattern(spread->expression(),
+                          factory()->NewVariableProxy(array));
+  }
+}
+
+
+void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) {
+  Variable* temp_var = nullptr;
+  VisitArrayLiteral(node, &temp_var);
+}
+
+
+void Parser::PatternRewriter::VisitAssignment(Assignment* node) {
+  // let {<pattern> = <init>} = <value>
+  //   becomes
+  // temp = <value>;
+  // <pattern> = temp === undefined ? <init> : temp;
+  DCHECK_EQ(Token::ASSIGN, node->op());
+
+  auto initializer = node->value();
+  auto value = initializer;
+  auto temp = CreateTempVar(current_value_);
+
+  if (IsInitializerContext()) {
+    Expression* is_undefined = factory()->NewCompareOperation(
+        Token::EQ_STRICT, factory()->NewVariableProxy(temp),
+        factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
+        RelocInfo::kNoPosition);
+    value = factory()->NewConditional(is_undefined, initializer,
+                                      factory()->NewVariableProxy(temp),
+                                      RelocInfo::kNoPosition);
+  }
+
+  if (IsBindingContext() &&
+      descriptor_->declaration_kind == DeclarationDescriptor::PARAMETER &&
+      scope()->is_arrow_scope()) {
+    RewriteParameterInitializerScope(parser_->stack_limit(), initializer,
+                                     scope()->outer_scope(), scope());
+  }
+
+  PatternContext old_context = SetAssignmentContextIfNeeded(initializer);
+  RecurseIntoSubpattern(node->target(), value);
+  set_context(old_context);
+}
+
+
+// =============== AssignmentPattern only ==================
+
+void Parser::PatternRewriter::VisitProperty(v8::internal::Property* node) {
+  DCHECK(IsAssignmentContext());
+  auto value = current_value_;
+
+  Assignment* assignment =
+      factory()->NewAssignment(Token::ASSIGN, node, value, node->position());
+
+  block_->statements()->Add(
+      factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
+      zone());
+}
+
+
+// =============== UNREACHABLE =============================
+
+void Parser::PatternRewriter::Visit(AstNode* node) { UNREACHABLE(); }
+
+#define NOT_A_PATTERN(Node)                                        \
+  void Parser::PatternRewriter::Visit##Node(v8::internal::Node*) { \
+    UNREACHABLE();                                                 \
+  }
+
+NOT_A_PATTERN(BinaryOperation)
+NOT_A_PATTERN(Block)
+NOT_A_PATTERN(BreakStatement)
+NOT_A_PATTERN(Call)
+NOT_A_PATTERN(CallNew)
+NOT_A_PATTERN(CallRuntime)
+NOT_A_PATTERN(CaseClause)
+NOT_A_PATTERN(ClassLiteral)
+NOT_A_PATTERN(CompareOperation)
+NOT_A_PATTERN(Conditional)
+NOT_A_PATTERN(ContinueStatement)
+NOT_A_PATTERN(CountOperation)
+NOT_A_PATTERN(DebuggerStatement)
+NOT_A_PATTERN(DoExpression)
+NOT_A_PATTERN(DoWhileStatement)
+NOT_A_PATTERN(EmptyStatement)
+NOT_A_PATTERN(EmptyParentheses)
+NOT_A_PATTERN(ExportDeclaration)
+NOT_A_PATTERN(ExpressionStatement)
+NOT_A_PATTERN(ForInStatement)
+NOT_A_PATTERN(ForOfStatement)
+NOT_A_PATTERN(ForStatement)
+NOT_A_PATTERN(FunctionDeclaration)
+NOT_A_PATTERN(FunctionLiteral)
+NOT_A_PATTERN(IfStatement)
+NOT_A_PATTERN(ImportDeclaration)
+NOT_A_PATTERN(Literal)
+NOT_A_PATTERN(NativeFunctionLiteral)
+NOT_A_PATTERN(RegExpLiteral)
+NOT_A_PATTERN(ReturnStatement)
+NOT_A_PATTERN(SloppyBlockFunctionStatement)
+NOT_A_PATTERN(Spread)
+NOT_A_PATTERN(SuperPropertyReference)
+NOT_A_PATTERN(SuperCallReference)
+NOT_A_PATTERN(SwitchStatement)
+NOT_A_PATTERN(ThisFunction)
+NOT_A_PATTERN(Throw)
+NOT_A_PATTERN(TryCatchStatement)
+NOT_A_PATTERN(TryFinallyStatement)
+NOT_A_PATTERN(UnaryOperation)
+NOT_A_PATTERN(VariableDeclaration)
+NOT_A_PATTERN(WhileStatement)
+NOT_A_PATTERN(WithStatement)
+NOT_A_PATTERN(Yield)
+
+#undef NOT_A_PATTERN
+}  // namespace internal
+}  // namespace v8