code: public static Node getNameNode(Node n) {
      checkState(n.isFunction() || n.isClass(), n);
      Node parent = n.getParent();
      switch (parent.getToken()) {
        case NAME:
          // var name = function() ...
          // var name2 = function name1() ...
          return parent;
  
        case ASSIGN: {
          // qualified.name = function() ...
          // qualified.name2 = function name1() ...
          Node firstChild = parent.getFirstChild();
          return firstChild.isQualifiedName() ? firstChild : null;
        }
  
        default:
          // function name() ...
          //   or
          // class Name ...
          Node funNameNode = n.getFirstChild();
          // Don't return the name node for anonymous functions/classes.
          // TODO(tbreisacher): Currently we do two kinds of "empty" checks because
          // anonymous classes have an EMPTY name node while anonymous functions
          // have a STRING node with an empty string. Consider making these the same.
          return (funNameNode.isEmpty() || funNameNode.getString().isEmpty()) ? null : funNameNode;
      }
    }
docs: Gets the node of a function or class's name. This method recognizes five forms:
  <ul>
  <li>{@code class name {...}}</li>
  <li>{@code var name = class {...}}</li>
  <li>{@code qualified.name = class {...}}</li>
  <li>{@code var name2 = class name1 {...}}</li>
  <li>{@code qualified.name2 = class name1 {...}}</li>
  </ul>
  In two last cases with named function expressions, the second name is
  returned (the variable or qualified name).
  
  @param n A function or class node
  @return the node best representing the class's name