code: private void traverseClass(Node n) {
      final Node className = n.getFirstChild();
      final Node extendsClause = className.getNext();
      final Node body = extendsClause.getNext();
  
      boolean isClassExpression = NodeUtil.isClassExpression(n);
  
      traverseBranch(extendsClause, n);
  
      for (Node child = body.getFirstChild(); child != null;) {
        Node next = child.getNext(); // see traverseChildren
        if (child.isComputedProp()) {
          traverseBranch(child.getFirstChild(), child);
        }
        child = next;
      }
  
      if (!isClassExpression) {
        // Class declarations are in the scope containing the declaration.
        traverseBranch(className, n);
      }
  
      curNode = n;
      pushScope(n);
  
      if (isClassExpression) {
        // Class expression names are only accessible within the function
        // scope.
        traverseBranch(className, n);
      }
  
      // Body
      traverseBranch(body, n);
  
      popScope();
    }
docs: Traverses a class.  Note that we traverse some of the child nodes slightly out of order to
  ensure children are visited in the correct scope.  The following children are in the outer
  scope: (1) the 'extends' clause, (2) any computed method keys, (3) the class name for class
  declarations only (class expression names are traversed in the class scope).  This requires
  that we visit the extends node (second child) and any computed member keys (grandchildren of
  the last, body, child) before visiting the name (first child) or body (last child).