package gw.rating.flow.domain uses gw.api.locale.DisplayKey uses gw.lang.reflect.IMethodInfo uses gw.lang.reflect.IType uses gw.rating.flow.util.RateFlowReflection class RateFunctionOperand extends CalcStepValueOperand { public final var FunctionName : String public final var RateFunctionArguments : List public final var MethodInfo : IMethodInfo final var _functionObject : String construct(definitionOperand : CalcStepDefinitionOperand, opType : CalcStepOperatorType) { this(definitionOperand, opType, 0, 0) } construct(definitionOperand : CalcStepDefinitionOperand, opType : CalcStepOperatorType, numLeft: int, numRight: int) { super(opType, numLeft, numRight) _highlightElement = new RateRoutineHighlightElement(definitionOperand) FunctionName = definitionOperand.FunctionName RateFunctionArguments = new ArrayList() MethodInfo = RateFlowReflection.getMethodInfoForMethod(definitionOperand.CalcStep.CalcRoutineDefinition.PolicyLinePatternCode, FunctionName) var sources = RateFlowReflection.getSourceForMethod(definitionOperand.CalcStep.CalcRoutineDefinition.PolicyLinePatternCode, FunctionName) _functionObject = sources.first().SymbolName if (MethodInfo != null) { // store the arguments in the order that matches the function definition var arguments = orderArguments(definitionOperand.ArgumentSources, MethodInfo) arguments.each(\ arg -> { switch (arg.OperandType) { case CalcStepOperandType.TC_CONSTANT: RateFunctionArguments.add(new RateFunctionConstantArgument(arg)) break case CalcStepOperandType.TC_LOCALVAR: if (arg.VariableFieldName.HasContent) { RateFunctionArguments.add(new RateFunctionLocalMultiFactorFieldVariableArgument(arg)) } else { RateFunctionArguments.add(new RateFunctionLocalVariableArgument(arg)) } break case CalcStepOperandType.TC_INSCOPE: RateFunctionArguments.add(new RateFunctionProductModelPathArgument(arg)) break case CalcStepOperandType.TC_LOOPVAR: RateFunctionArguments.add(new RateFunctionLoopVariableArgument(arg)) break default: throw new IllegalStateException("Unknown OperandType: " + arg.OperandType) } }) } } // this function is static because it is called from the constructor, // and public so that it can be independently tested. static function orderArguments(args : entity.CalcStepDefinitionArgument[], methodInfo : IMethodInfo) : CalcStepDefinitionArgument[] { try{ return methodInfo.Parameters.map(\ p -> args.singleWhere(\ a -> a.Parameter == p.Name)) } catch(e: IllegalStateException) { // determine the missing parameters var allMissingParams = methodInfo.Parameters*.Name.subtract(args*.Parameter) var supplied = args*.Parameter.join(", ") throw new IllegalStateException("Missing required parameters: ${allMissingParams.join(",")}; supplied: ${supplied}", e) } } override protected function generateValue(context: GenerationContext){ if (MethodInfo == null) { HighlightElement.addToContextOrThrow(context.Context, DisplayKey.get("Validation.Rating.RateRoutineDefinition.MissingRateFunction", FunctionName)) } var parsedName = FunctionName.split("\\(")[0] context.append(_functionObject + ".${parsedName}(") RateFunctionArguments.eachWithIndex(\ a, i -> { context.WorksheetHelper.wrapArgument(a, \ -> context.append(a.generate())) if (i < RateFunctionArguments.Count - 1) { context.append(", ") } }) context.append(')') } override property get OperandType() : CalcStepOperandType { return CalcStepOperandType.TC_RATEFUNC } override function toString() : String { return FunctionName } public static function getFunctionReturnType(lineCode : String, functionName : String) : IType { return RateFlowReflection.getMethodInfoForMethod(lineCode, functionName).ReturnType } override function getDataType(context: GenerationContext) : IType { return MethodInfo.ReturnType } }