countFunctions = (expression) => {
    const countNodes = (nodes) =>
        nodes.map(countNode).reduce((a, b) => a + b, 0);
    const countNode = (node) => {
      if (node.functionDefinitionValue) {
        return 1;
      } else if (node.arrayValue) {
        return countNodes(node.arrayValue.values);
      } else if (node.dictionaryValue) {
        return countNodes(Object.values(node.dictionaryValue.values));
      } else if (node.functionInvocationValue) {
        const fn = node.functionInvocationValue;
        return countNodes(Object.values(fn.arguments));
      }
      return 0;
    };
    return countNodes(Object.values(expression.values));
  }
Deterministically generates names for the unnamed variables, based on the
body.

@param {!ee.Function.Signature} signature The signature which may contain
    null argument names.
@param {!Array<!ee.ComputedObject>} vars A list of variables, some of which
    may be nameless. These will be updated to include names when this
    method returns.
@param {!Function} body The JavaScript function to evaluate.
@return {!ee.Function.Signature} The signature with null arg names resolved.
@private
@suppress {accessControls} We are accessing the protected varName.