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);
}