/** Gets the string representation of an optional param. */
 private void appendOptionalArgString(
     StringBuilder builder, JSType paramType, boolean forAnnotations) {
   if (paramType.isUnionType()) {
     // Remove the optionality from the var arg.
     paramType =
         paramType
             .toMaybeUnionType()
             .getRestrictedUnion(registry.getNativeType(JSTypeNative.VOID_TYPE));
   }
   builder.append(paramType.toStringHelper(forAnnotations)).append("=");
 }
  @Override
  String toStringHelper(boolean forAnnotations) {
    StringBuilder result = new StringBuilder();
    boolean firstAlternate = true;

    result.append("(");
    SortedSet<JSType> sorted = new TreeSet<>(ALPHA);
    sorted.addAll(alternatesWithoutStucturalTyping);
    for (JSType t : sorted) {
      if (!firstAlternate) {
        result.append("|");
      }
      result.append(t.toStringHelper(forAnnotations));
      firstAlternate = false;
    }
    result.append(")");
    return result.toString();
  }
  /**
   * Informally, a function is represented by {@code function (params): returnType} where the {@code
   * params} is a comma separated list of types, the first one being a special {@code this:T} if the
   * function expects a known type for {@code this}.
   */
  @Override
  String toStringHelper(boolean forAnnotations) {
    if (!isPrettyPrint() || this == registry.getNativeType(JSTypeNative.FUNCTION_INSTANCE_TYPE)) {
      return "Function";
    }

    setPrettyPrint(false);

    StringBuilder b = new StringBuilder(32);
    b.append("function (");
    int paramNum = call.parameters.getChildCount();
    boolean hasKnownTypeOfThis = !(typeOfThis instanceof UnknownType);
    if (hasKnownTypeOfThis) {
      if (isConstructor()) {
        b.append("new:");
      } else {
        b.append("this:");
      }
      b.append(typeOfThis.toStringHelper(forAnnotations));
    }
    if (paramNum > 0) {
      if (hasKnownTypeOfThis) {
        b.append(", ");
      }
      Node p = call.parameters.getFirstChild();
      appendArgString(b, p, forAnnotations);

      p = p.getNext();
      while (p != null) {
        b.append(", ");
        appendArgString(b, p, forAnnotations);
        p = p.getNext();
      }
    }
    b.append("): ");
    b.append(call.returnType.toStringHelper(forAnnotations));

    setPrettyPrint(true);
    return b.toString();
  }