public virtual object Visit(Node node, TData data) { IdentifierNode identifierNode = node as IdentifierNode; if (identifierNode != null) { return(VisitIdentifier(identifierNode, data)); } InvocationNode invocationNode = node as InvocationNode; if (invocationNode != null) { return(VisitInvocationNode(invocationNode, data)); } NodeList <Node> nodeList = node as NodeList <Node>; if (nodeList != null) { return(VisitNodeList(nodeList, data)); } LiteralNode literalNode = node as LiteralNode; if (literalNode != null) { return(VisitLiteral(literalNode, data)); } throw new NotImplementedException(); }
public virtual object VisitInvocationNode(InvocationNode invocationNode, TData data) { string functionName = invocationNode.FunctionName.Identifier; int argumentCount = invocationNode.Arguments.Count; object[] arguments = new object[argumentCount]; Type[] argumentTypes = new Type[argumentCount]; bool hasNullArguments = false; for (int i = 0; i < argumentCount; i++) { arguments[i] = Visit(invocationNode.Arguments[i], data); if (arguments[i] == null) { hasNullArguments = true; argumentTypes[i] = typeof(object); } else { argumentTypes[i] = arguments[i].GetType(); } } MethodInfo methodInfo = _evaluationContext.FunctionBinder.Resolve(functionName, argumentTypes); if (methodInfo == null) { //If we have null arguments, we will propagate null without warning. if (!hasNullArguments) { _evaluationContext.Logger?.LogWarning($"Cannot resolve function {functionName} with argument types {string.Join(",", argumentTypes.Select(t => t.Name))}"); } return(null); } else { return(methodInfo.Invoke(null, arguments)); } }