internal static List<LambdaExpression> GetReturnConversions(ParameterConversionConfiguration conversionConfig, Type initialReturnType, ExcelReturnRegistration returnRegistration) { var appliedConversions = new List<LambdaExpression>(); // paramReg might be modified internally by the conversions, but won't become a different object var returnType = initialReturnType; // Might become a different type as we convert foreach (var returnConversion in conversionConfig.ReturnConversions) { var lambda = returnConversion.Convert(returnType, returnRegistration); if (lambda == null) continue; // We got one to apply... // Some sanity checks Debug.Assert(lambda.Parameters.Count == 1); Debug.Assert(lambda.Parameters[0].Type == returnType); appliedConversions.Add(lambda); // Change the Return Type to be whatever the conversion function returns // for the next round of processing returnType = lambda.ReturnType; } if (appliedConversions.Count == 0) return null; return appliedConversions; }
/// <summary> /// Creates a new ExcelFunctionRegistration with the given LambdaExpression. /// Uses the passes in attributes for registration. /// /// The number of ExcelParameterRegistrations passed in must match the number of parameters in the LambdaExpression. /// </summary> /// <param name="functionLambda"></param> /// <param name="functionAttribute"></param> /// <param name="parameterRegistrations"></param> public ExcelFunctionRegistration(LambdaExpression functionLambda, ExcelFunctionAttribute functionAttribute, IEnumerable <ExcelParameterRegistration> parameterRegistrations = null) { if (functionLambda == null) { throw new ArgumentNullException("functionLambda"); } if (functionAttribute == null) { throw new ArgumentNullException("functionAttribute"); } FunctionLambda = functionLambda; FunctionAttribute = functionAttribute; if (parameterRegistrations == null) { if (functionLambda.Parameters.Count != 0) { throw new ArgumentOutOfRangeException("parameterRegistrations", "No parameter registrations provided, but function has parameters."); } ParameterRegistrations = new List <ExcelParameterRegistration>(); } else { ParameterRegistrations = new List <ExcelParameterRegistration>(parameterRegistrations); if (functionLambda.Parameters.Count != ParameterRegistrations.Count) { throw new ArgumentOutOfRangeException("parameterRegistrations", "Mismatched number of ParameterRegistrations provided."); } } // Create the lists - hope the rest is filled in right...? CustomAttributes = new List <object>(); ReturnRegistration = new ExcelReturnRegistration(); }
/// <summary> /// Creates a new ExcelFunctionRegistration from a LambdaExpression. /// Uses the Name and Parameter Names to fill in the default attributes. /// </summary> /// <param name="functionLambda"></param> public ExcelFunctionRegistration(LambdaExpression functionLambda) { if (functionLambda == null) throw new ArgumentNullException("functionLambda"); FunctionLambda = functionLambda; FunctionAttribute = new ExcelFunctionAttribute { Name = functionLambda.Name }; ParameterRegistrations = functionLambda.Parameters .Select( p => new ExcelParameterRegistration(new ExcelArgumentAttribute { Name = p.Name })) .ToList(); CustomAttributes = new List<object>(); ReturnRegistration = new ExcelReturnRegistration(); }
// NOTE: 16 parameter max for Expression.GetDelegateType // Copies all the (non Excel...) attributes from the method into the CustomAttribute lists. // TODO: What about native async function, which returns 'Void'? /// <summary> /// Creates a new ExcelFunctionRegistration from a MethodInfo, with a LambdaExpression that represents a call to the method. /// Uses the Name and Parameter Names from the MethodInfo to fill in the default attributes. /// All CustomAttributes on the method and parameters are copies to the respective collections in the ExcelFunctionRegistration. /// </summary> /// <param name="methodInfo"></param> public ExcelFunctionRegistration(MethodInfo methodInfo) { CustomAttributes = new List <object>(); var paramExprs = methodInfo.GetParameters() .Select(pi => Expression.Parameter(pi.ParameterType, pi.Name)) .ToList(); FunctionLambda = Expression.Lambda(Expression.Call(methodInfo, paramExprs), methodInfo.Name, paramExprs); var allMethodAttributes = methodInfo.GetCustomAttributes(true); foreach (var att in allMethodAttributes) { var funcAtt = att as ExcelFunctionAttribute; if (funcAtt != null) { FunctionAttribute = funcAtt; // At least ensure that name is set - from the method if need be. if (string.IsNullOrEmpty(FunctionAttribute.Name)) { FunctionAttribute.Name = methodInfo.Name; } } else { CustomAttributes.Add(att); } } // Check that ExcelFunctionAttribute has been set if (FunctionAttribute == null) { FunctionAttribute = new ExcelFunctionAttribute { Name = methodInfo.Name }; } ParameterRegistrations = methodInfo.GetParameters().Select(pi => new ExcelParameterRegistration(pi)).ToList(); ReturnRegistration = new ExcelReturnRegistration(); ReturnRegistration.CustomAttributes.AddRange(methodInfo.ReturnParameter.GetCustomAttributes(true)); // Check that we haven't made a mistake Debug.Assert(IsValid()); }
/// <summary> /// Creates a new ExcelFunctionRegistration from a LambdaExpression. /// Uses the Name and Parameter Names to fill in the default attributes. /// </summary> /// <param name="functionLambda"></param> public ExcelFunctionRegistration(LambdaExpression functionLambda) { if (functionLambda == null) { throw new ArgumentNullException("functionLambda"); } FunctionLambda = functionLambda; FunctionAttribute = new ExcelFunctionAttribute { Name = functionLambda.Name }; ParameterRegistrations = functionLambda.Parameters .Select(p => new ExcelParameterRegistration(new ExcelArgumentAttribute { Name = p.Name })) .ToList(); CustomAttributes = new List <object>(); ReturnRegistration = new ExcelReturnRegistration(); }
/// <summary> /// Creates a new ExcelFunctionRegistration with the given LambdaExpression. /// Uses the passes in attributes for registration. /// /// The number of ExcelParameterRegistrations passed in must match the number of parameters in the LambdaExpression. /// </summary> /// <param name="functionLambda"></param> /// <param name="functionAttribute"></param> /// <param name="parameterRegistrations"></param> public ExcelFunctionRegistration(LambdaExpression functionLambda, ExcelFunctionAttribute functionAttribute, IEnumerable<ExcelParameterRegistration> parameterRegistrations = null) { if (functionLambda == null) throw new ArgumentNullException("functionLambda"); if (functionAttribute == null) throw new ArgumentNullException("functionAttribute"); FunctionLambda = functionLambda; FunctionAttribute = functionAttribute; if (parameterRegistrations == null) { if (functionLambda.Parameters.Count != 0) throw new ArgumentOutOfRangeException("parameterRegistrations", "No parameter registrations provided, but function has parameters."); ParameterRegistrations = new List<ExcelParameterRegistration>(); } else { ParameterRegistrations = new List<ExcelParameterRegistration>(parameterRegistrations); if (functionLambda.Parameters.Count != ParameterRegistrations.Count) throw new ArgumentOutOfRangeException("parameterRegistrations", "Mismatched number of ParameterRegistrations provided."); } // Create the lists - hope the rest is filled in right...? CustomAttributes = new List<object>(); ReturnRegistration = new ExcelReturnRegistration(); }
// NOTE: 16 parameter max for Expression.GetDelegateType // Copies all the (non Excel...) attributes from the method into the CustomAttribute lists. // TODO: What about native async function, which returns 'Void'? /// <summary> /// Creates a new ExcelFunctionRegistration from a MethodInfo, with a LambdaExpression that represents a call to the method. /// Uses the Name and Parameter Names from the MethodInfo to fill in the default attributes. /// All CustomAttributes on the method and parameters are copies to the respective collections in the ExcelFunctionRegistration. /// </summary> /// <param name="methodInfo"></param> public ExcelFunctionRegistration(MethodInfo methodInfo) { CustomAttributes = new List<object>(); var paramExprs = methodInfo.GetParameters() .Select(pi => Expression.Parameter(pi.ParameterType, pi.Name)) .ToList(); FunctionLambda = Expression.Lambda(Expression.Call(methodInfo, paramExprs), methodInfo.Name, paramExprs); var allMethodAttributes = methodInfo.GetCustomAttributes(true); foreach (var att in allMethodAttributes) { var funcAtt = att as ExcelFunctionAttribute; if (funcAtt != null) { FunctionAttribute = funcAtt; // At least ensure that name is set - from the method if need be. if (string.IsNullOrEmpty(FunctionAttribute.Name)) FunctionAttribute.Name = methodInfo.Name; } else { CustomAttributes.Add(att); } } // Check that ExcelFunctionAttribute has been set if (FunctionAttribute == null) { FunctionAttribute = new ExcelFunctionAttribute { Name = methodInfo.Name }; } ParameterRegistrations = methodInfo.GetParameters().Select(pi => new ExcelParameterRegistration(pi)).ToList(); ReturnRegistration = new ExcelReturnRegistration(); ReturnRegistration.CustomAttributes.AddRange(methodInfo.ReturnParameter.GetCustomAttributes(true)); // Check that we haven't made a mistake Debug.Assert(IsValid()); }
internal static LambdaExpression GetReturnConversion(ParameterConversionConfiguration conversionConfig, Type initialReturnType, ExcelReturnRegistration returnRegistration) { return(ComposeLambdas(GetReturnConversions(conversionConfig, initialReturnType, returnRegistration))); }
public ShimParameter(Type type, ExcelReturnRegistration reg, ParameterConversionConfiguration config) : this(type, reg.CustomAttributes) { ReturnRegistration = reg; PreparePropertyConverters(config, reg, ParameterConversionRegistration.GetReturnConversion); }
internal static LambdaExpression GetReturnConversion(ParameterConversionConfiguration conversionConfig, Type initialReturnType, ExcelReturnRegistration returnRegistration) { return ComposeLambdas(GetReturnConversions(conversionConfig, initialReturnType, returnRegistration)); }