Always give class literals a block scope

Class methods always have the class scope on their scope chain in order
to implement strong mode checks. Previously, that scope wasn't attached
to the ClassLiteral for anonymous classes (since the scope contained
no bindings).

This patch simply puts that same scope on the ClassLiteral, anonymous
or not, which simplifies other code that needs to reason about the scope
of a class and its methods.

Review URL: https://codereview.chromium.org/1413903002

Cr-Commit-Position: refs/heads/master@{#31371}
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
index 5b07447..5889e46 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -1533,20 +1533,15 @@
 
 
 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) {
-  if (expr->scope() == NULL) {
-    // Visit class literal in the same scope, no declarations.
+  // Visit declarations and class literal in a block scope.
+  if (expr->scope()->ContextLocalCount() > 0) {
+    Node* context = BuildLocalBlockContext(expr->scope());
+    ContextScope scope(this, expr->scope(), context);
+    VisitDeclarations(expr->scope()->declarations());
     VisitClassLiteralContents(expr);
   } else {
-    // Visit declarations and class literal in a block scope.
-    if (expr->scope()->ContextLocalCount() > 0) {
-      Node* context = BuildLocalBlockContext(expr->scope());
-      ContextScope scope(this, expr->scope(), context);
-      VisitDeclarations(expr->scope()->declarations());
-      VisitClassLiteralContents(expr);
-    } else {
-      VisitDeclarations(expr->scope()->declarations());
-      VisitClassLiteralContents(expr);
-    }
+    VisitDeclarations(expr->scope()->declarations());
+    VisitClassLiteralContents(expr);
   }
 }
 
@@ -1644,8 +1639,7 @@
   literal = NewNode(op, literal, proto);
 
   // Assign to class variable.
-  if (expr->scope() != NULL) {
-    DCHECK_NOT_NULL(expr->class_variable_proxy());
+  if (expr->class_variable_proxy() != nullptr) {
     Variable* var = expr->class_variable_proxy()->var();
     FrameStateBeforeAndAfter states(this, BailoutId::None());
     VectorSlotPair feedback = CreateVectorSlotPair(
diff --git a/src/full-codegen/full-codegen.cc b/src/full-codegen/full-codegen.cc
index d7e95fb..8cb9dc3 100644
--- a/src/full-codegen/full-codegen.cc
+++ b/src/full-codegen/full-codegen.cc
@@ -1273,8 +1273,7 @@
 
     EmitClassDefineProperties(lit);
 
-    if (lit->scope() != NULL) {
-      DCHECK_NOT_NULL(lit->class_variable_proxy());
+    if (lit->class_variable_proxy() != nullptr) {
       EmitVariableAssignment(lit->class_variable_proxy()->var(),
                              Token::INIT_CONST, lit->ProxySlot());
     }
diff --git a/src/parser.cc b/src/parser.cc
index 3d61c7e7..e3a62c1 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -4895,15 +4895,13 @@
                                      block_scope->language_mode());
   }
 
+  // Note that we do not finalize this block scope because strong
+  // mode uses it as a sentinel value indicating an anonymous class.
   block_scope->set_end_position(end_pos);
 
   if (name != NULL) {
     DCHECK_NOT_NULL(proxy);
     proxy->var()->set_initializer_position(end_pos);
-  } else {
-    // Unnamed classes should not have scopes (the scope will be empty).
-    DCHECK_EQ(block_scope->num_var_or_const(), 0);
-    block_scope = nullptr;
   }
 
   return factory()->NewClassLiteral(name, block_scope, proxy, extends,