code: String getName(Node node) {
      switch (node.getToken()) {
        case CLASS:
        case FUNCTION:
          return NodeUtil.getName(node);
        case GETPROP:
          Node lhsOfDot = node.getFirstChild();
          Node rhsOfDot = lhsOfDot.getNext();
          String lhsOfDotName = getName(lhsOfDot);
          String rhsOfDotName = getName(rhsOfDot);
          if ("prototype".equals(rhsOfDotName)) {
            return lhsOfDotName + delimiter;
          } else {
            return lhsOfDotName + delimiter + rhsOfDotName;
          }
        case GETELEM:
          Node outsideBrackets = node.getFirstChild();
          Node insideBrackets = outsideBrackets.getNext();
          String nameOutsideBrackets = getName(outsideBrackets);
          String nameInsideBrackets = getName(insideBrackets);
          if ("prototype".equals(nameInsideBrackets)) {
            return nameOutsideBrackets + delimiter;
          } else {
            return nameOutsideBrackets + delimiter + nameInsideBrackets;
          }
        case NAME:
          return node.getString();
        case STRING:
        case STRING_KEY:
        case MEMBER_FUNCTION_DEF:
          return TokenStream.isJSIdentifier(node.getString()) ?
              node.getString() : ("__" + nextUniqueInt++);
        case NUMBER:
          return NodeUtil.getStringValue(node);
        case THIS:
          return "this";
        case CALL:
        case COMPUTED_PROP:
          return getName(node.getFirstChild());
        default:
          StringBuilder sb = new StringBuilder();
          for (Node child = node.getFirstChild(); child != null;
               child = child.getNext()) {
            if (sb.length() > 0) {
              sb.append(delimiter);
            }
            sb.append(getName(child));
          }
          return sb.toString();
      }
    }
docs: Returns a qualified name of the specified node. Dots and brackets
  are changed to the delimiter passed in when constructing the
  NodeNameExtractor object.  We also replace ".prototype" with the
  delimiter to keep names short, while still differentiating them
  from static properties.  (Prototype properties will end up
  looking like "a$b$$c" if this.delimiter = '$'.)