function matcherFunctionCodeForAlgebraicType()

in src/plugins/algebraic-type-templated-matching.ts [109:164]


function matcherFunctionCodeForAlgebraicType(
  algebraicType: AlgebraicType.Type,
  functionParameterProvider: (algebraicType: AlgebraicType.Type) => string[],
): string[] {
  const functionDeclaration: string =
    'static T match(' +
    functionParameterProvider(algebraicType).join(', ') +
    ') {';
  const matcherFunctionParameterName: string =
    matcherFunctionParameterNameForAlgebraicType(algebraicType);
  const assertionCode: string =
    'NSCAssert(' +
    matcherFunctionParameterName +
    ' != nil, @"The ADT object ' +
    matcherFunctionParameterName +
    ' is nil");';
  const resultDeclaration: string = '__block std::unique_ptr<T> result;';

  const blockCode: string[] = algebraicType.subtypes.reduce(
    (soFar, subtype) =>
      buildLocalFunctionBlockDefinitionsForSubtype(
        algebraicType,
        soFar,
        subtype,
      ),
    [],
  );

  const keywordPartsForMatchInvocation: string[] =
    algebraicType.subtypes.reduce(
      (soFar, subtype, idx) =>
        AlgebraicTypeUtilsForMatching.buildKeywordPartsForInvokingMatchMethodForSubtype(
          algebraicType,
          soFar,
          subtype,
          idx,
        ),
      [],
    );
  const matchInvocationCode: string =
    '[' +
    matcherFunctionParameterName +
    ' ' +
    keywordPartsForMatchInvocation.join(' ') +
    '];';
  const returnCode: string = 'return *result;';
  const functionCode: string[] = [assertionCode, resultDeclaration, '']
    .concat(blockCode)
    .concat(matchInvocationCode)
    .concat(returnCode);

  const endFunctionDeclaration = '}';
  return [functionDeclaration]
    .concat(functionCode.map(StringUtils.indent(2)))
    .concat(endFunctionDeclaration);
}