<commit_before>// Copyright 2018-2020, University of Colorado Boulder

/**
 * IO Type for JS's built-in function type.
 *
 * @author <NAME> (PhET Interactive Simulations)
 * @author <NAME> (PhET Interactive Simulations)
 */

import tandemNamespace from '../tandemNamespace.js';
import IOType from './IOType.js';

// {Map.<parameterTypeName:string, IOType>} - cache each parameterized IOType so that it is only created once
const cache = new Map();

/**
 * Parametric IO Type constructor--given return type and parameter types, this function returns a type wrapped IO Type for
 * that "class" of functions. "Class" here refers to the supported parameter and return IO Types.
 * This caching implementation should be kept in sync with the other parametric IO Type caching implementations.
 * @param {IOType} returnType - IO Type of the return type of the function that can support cross-frame serialization
 * @param {IOType[]} functionParameterTypes - IO Types for the individual arguments of the function.
 */
const FunctionIO = ( returnType, functionParameterTypes ) => {
  for ( let i = 0; i < functionParameterTypes.length; i++ ) {
    assert && assert( functionParameterTypes[ i ], 'parameter type was not truthy' );
  }
  assert && assert( returnType, 'return type was not truthy' );

  // REVIEW https://github.com/phetsims/tandem/issues/169 Why is this different than the typeName later in this file?
  const cacheKey = `${returnType.typeName}.${functionParameterTypes.map( type => type.typeName ).join( ',' )}`;

  if ( !cache.has( cacheKey ) ) {

    // gather a list of argument names for the documentation string
    let argsString = functionParameterTypes.map( parameterType => parameterType.typeName ).join( ', ' );
    if ( argsString === '' ) {
      argsString = 'VoidIO';
    }
    const parameterTypesString = functionParameterTypes.map( parameterType => parameterType.typeName ).join( ',' );

    cache.set( cacheKey, new IOType( `FunctionIO(${parameterTypesString})=>${returnType.typeName}`, {
      valueType: 'function',

      isFunctionType: true,

      // These are the parameters to this FunctionIO, not to the function it wraps. That is why it includes the return type.
      // NOTE: the order is very important, for instance phetioCommandProcessor relies on the parameters being before
      // the return type.  If we decide this is too brittle, perhaps we should subclass IOType to FunctionIOType, and it
      // can track its functionParameterTypes separately from the returnType.
      parameterTypes: functionParameterTypes.concat( [ returnType ] ),<commit_msg>none instead of VoidIO, https://github.com/phetsims/phet-io-wrappers/issues/104<commit_after>// Copyright 2018-2020, University of Colorado Boulder

/**
 * IO Type for JS's built-in function type.
 *
 * @author <NAME> (PhET Interactive Simulations)
 * @author <NAME> (PhET Interactive Simulations)
 */

import tandemNamespace from '../tandemNamespace.js';
import IOType from './IOType.js';

// {Map.<parameterTypeName:string, IOType>} - cache each parameterized IOType so that it is only created once
const cache = new Map();

/**
 * Parametric IO Type constructor--given return type and parameter types, this function returns a type wrapped IO Type for
 * that "class" of functions. "Class" here refers to the supported parameter and return IO Types.
 * This caching implementation should be kept in sync with the other parametric IO Type caching implementations.
 * @param {IOType} returnType - IO Type of the return type of the function that can support cross-frame serialization
 * @param {IOType[]} functionParameterTypes - IO Types for the individual arguments of the function.
 */
const FunctionIO = ( returnType, functionParameterTypes ) => {
  for ( let i = 0; i < functionParameterTypes.length; i++ ) {
    assert && assert( functionParameterTypes[ i ], 'parameter type was not truthy' );
  }
  assert && assert( returnType, 'return type was not truthy' );

  // REVIEW https://github.com/phetsims/tandem/issues/169 Why is this different than the typeName later in this file?
  const cacheKey = `${returnType.typeName}.${functionParameterTypes.map( type => type.typeName ).join( ',' )}`;

  if ( !cache.has( cacheKey ) ) {

    // gather a list of argument names for the documentation string
    let argsString = functionParameterTypes.map( parameterType => parameterType.typeName ).join( ', ' );
    if ( argsString === '' ) {
      argsString = 'none';
    }
    const parameterTypesString = functionParameterTypes.map( parameterType => parameterType.typeName ).join( ',' );

    cache.set( cacheKey, new IOType( `FunctionIO(${parameterTypesString})=>${returnType.typeName}`, {
      valueType: 'function',

      isFunctionType: true,

      // These are the parameters to this FunctionIO, not to the function it wraps. That is why it includes the return type.
      // NOTE: the order is very important, for instance phetioCommandProcessor relies on the parameters being before
      // the return type.  If we decide this is too brittle, perhaps we should subclass IOType to FunctionIOType, and it
      // can track its functionParameterTypes separately from the returnType.
      parameterTypes: functionParameterTypes.concat( [ returnType ] ),
{'fraction_non_alphanumeric': 0.100228223659186, 'fraction_numerical': 0.005135032331685051, 'mean_word_length': 3.961320754716981, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 19, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '317547', 'n_tokens_mistral': 1412, 'n_tokens_neox': 1373, 'n_words': 560}