[strong] Simplify the classes-referring-to-classes check.
authormarja <marja@chromium.org>
Fri, 24 Apr 2015 13:05:17 +0000 (06:05 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 24 Apr 2015 13:04:54 +0000 (13:04 +0000)
Follow up for r28032.

We don't need to store the "corresponding outer scope class variables", it's
enough if we transmit the declaration group start to the inner class
variable.

R=rossberg@chromium.org
BUG=v8:3956
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#28048}

src/parser.cc
src/scopes.cc
src/variables.h

index f97174136887ae5be63b81dc44b3a8eea62b9da2..af186270ee87307f13fd3694bf7c9de8aa78c9b3 100644 (file)
@@ -2199,6 +2199,10 @@ Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
       scope_->class_declaration_group_start());
   Variable* outer_class_variable = Declare(declaration, true, CHECK_OK);
   proxy->var()->set_initializer_position(position());
+  // This is needed because a class ("class Name { }") creates two bindings (one
+  // in the outer scope, and one in the class scope). The method is a function
+  // scope inside the inner scope (class scope). The consecutive class
+  // declarations are in the outer scope.
   if (value->class_variable_proxy() && value->class_variable_proxy()->var() &&
       outer_class_variable->is_class()) {
     // In some cases, the outer variable is not detected as a class variable;
@@ -2208,8 +2212,8 @@ Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
     value->class_variable_proxy()
         ->var()
         ->AsClassVariable()
-        ->set_corresponding_outer_class_variable(
-            outer_class_variable->AsClassVariable());
+        ->set_declaration_group_start(
+            outer_class_variable->AsClassVariable()->declaration_group_start());
   }
 
   Token::Value init_op =
index 86c75ad8d7c23b91200ff4d3c78d1f982d2f261c..8b623f90ce908ac548bfd8ea46bdcf088121bbcf 100644 (file)
@@ -1168,48 +1168,40 @@ bool Scope::CheckStrongModeDeclaration(VariableProxy* proxy, Variable* var) {
     for (scope = this; scope && scope != var->scope();
          scope = scope->outer_scope()) {
       ClassVariable* class_var = scope->ClassVariableForMethod();
-      if (class_var) {
-        // A method is referring to some other class, possibly declared
-        // later. Referring to a class declared earlier is always OK and covered
-        // by the code outside this if. Here we only need to allow special cases
-        // for referring to a class which is declared later.
-
-        // Referring to a class C declared later is OK under the following
-        // circumstances:
-
-        // 1. The class declarations are in a consecutive group with no other
-        // declarations or statements in between, and
-
-        // 2. There is no dependency cycle where the first edge is an
-        // initialization time dependency (computed property name or extends
-        // clause) from C to something that depends on this class directly or
-        // transitively.
-
-        // This is needed because a class ("class Name { }") creates two
-        // bindings (one in the outer scope, and one in the class scope). The
-        // method is a function scope inside the inner scope (class scope). The
-        // consecutive class declarations are in the outer scope.
-        class_var = class_var->corresponding_outer_class_variable();
-        if (class_var &&
-            class_var->declaration_group_start() ==
-                var->AsClassVariable()->declaration_group_start()) {
-          return true;
-        }
-
-        // TODO(marja,rossberg): implement the dependency cycle detection. Here
-        // we undershoot the target and allow referring to any class in the same
-        // consectuive declaration group.
-
-        // The cycle detection can work roughly like this: 1) detect init-time
-        // references here (they are free variables which are inside the class
-        // scope but not inside a method scope - no parser changes needed to
-        // detect them) 2) if we encounter an init-time reference here, allow
-        // it, but record it for a later dependency cycle check 3) also record
-        // non-init-time references here 4) after scope analysis is done,
-        // analyse the dependency cycles: an illegal cycle is one starting with
-        // an init-time reference and leading back to the starting point with
-        // either non-init-time and init-time references.
+      // A method is referring to some other class, possibly declared
+      // later. Referring to a class declared earlier is always OK and covered
+      // by the code outside this if. Here we only need to allow special cases
+      // for referring to a class which is declared later.
+
+      // Referring to a class C declared later is OK under the following
+      // circumstances:
+
+      // 1. The class declarations are in a consecutive group with no other
+      // declarations or statements in between, and
+
+      // 2. There is no dependency cycle where the first edge is an
+      // initialization time dependency (computed property name or extends
+      // clause) from C to something that depends on this class directly or
+      // transitively.
+      if (class_var &&
+          class_var->declaration_group_start() ==
+              var->AsClassVariable()->declaration_group_start()) {
+        return true;
       }
+
+      // TODO(marja,rossberg): implement the dependency cycle detection. Here we
+      // undershoot the target and allow referring to any class in the same
+      // consectuive declaration group.
+
+      // The cycle detection can work roughly like this: 1) detect init-time
+      // references here (they are free variables which are inside the class
+      // scope but not inside a method scope - no parser changes needed to
+      // detect them) 2) if we encounter an init-time reference here, allow it,
+      // but record it for a later dependency cycle check 3) also record
+      // non-init-time references here 4) after scope analysis is done, analyse
+      // the dependency cycles: an illegal cycle is one starting with an
+      // init-time reference and leading back to the starting point with either
+      // non-init-time and init-time references.
     }
   }
 
index 31bfe42dc098e43fa4b6deabdfda076a96ee7596..384a8859545045ac502c5f80cc7a8229ddd81d75 100644 (file)
@@ -192,16 +192,11 @@ class ClassVariable : public Variable {
                 int declaration_group_start = -1)
       : Variable(scope, name, mode, Variable::CLASS, initialization_flag,
                  maybe_assigned_flag),
-        declaration_group_start_(declaration_group_start),
-        corresponding_outer_class_variable_(nullptr) {}
+        declaration_group_start_(declaration_group_start) {}
 
   int declaration_group_start() const { return declaration_group_start_; }
-
-  ClassVariable* corresponding_outer_class_variable() const {
-    return corresponding_outer_class_variable_;
-  }
-  void set_corresponding_outer_class_variable(ClassVariable* var) {
-    corresponding_outer_class_variable_ = var;
+  void set_declaration_group_start(int declaration_group_start) {
+    declaration_group_start_ = declaration_group_start;
   }
 
  private:
@@ -209,7 +204,6 @@ class ClassVariable : public Variable {
   // needed for strong mode scoping checks. TODO(marja, rossberg): Implement
   // checks for functions too.
   int declaration_group_start_;
-  ClassVariable* corresponding_outer_class_variable_;
 };
 } }  // namespace v8::internal