private Expression InlineExpression(Expression thisExpression, MethodInfo targetMethod, Maybe <InlineableAttribute> inlinableAttribute, ReadOnlyCollection <Expression> targetArguments) { Try <LambdaExpression> @try = InlineVisitor.FindMethodToInline(targetMethod, inlinableAttribute.Value.InlineMethodName).Select <LambdaExpression>(delegate(MethodInfo methodInfo) { object[] parameterValuesToInline = InlineVisitor.GetParameterValuesToInline(targetMethod, targetArguments, methodInfo, this._inlineEnvironment); return((LambdaExpression)methodInfo.Invoke(null, parameterValuesToInline)); }).Recover((Exception exception) => Try.Create <LambdaExpression>(new Func <LambdaExpression>(targetMethod.Decompile)).Recover((Exception _) => new Failure <LambdaExpression>(exception))); IEnumerable <Expression> newExpr = (thisExpression == null) ? targetArguments : new Expression[] { thisExpression }.Concat(targetArguments); return(@try.Value.Splice(newExpr)); }
private static object[] GetParameterValuesToInline(MethodInfo targetMethod, ReadOnlyCollection <Expression> targetArguments, MethodInfo methodToInline, IEnumerable <object> inlineEnvironments) { var inner = targetMethod.GetParameters().Select((ParameterInfo parameter, int index) => new { value = targetArguments[index], parameter = parameter }).ToArray(); var outer = methodToInline.GetParameters().Select((ParameterInfo parameter, int index) => new { index, parameter }).ToArray(); IEnumerable <object> source = from inlineParam in outer join targetParam in inner on inlineParam.parameter.Name equals targetParam.parameter.Name into targetParameterTmpCollection from targetParameter in targetParameterTmpCollection.DefaultIfEmpty() let value = (targetParameter == null) ? InlineVisitor.GetValueFromEnvironment(inlineParam.parameter.ParameterType, inlineEnvironments, methodToInline) : InlineVisitor.GetValueByExpression(targetParameter.value, methodToInline) orderby inlineParam.index select value; return(source.ToArray <object>()); }