You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.6 KiB
88 lines
2.6 KiB
2 years ago
|
using EC.Helper.RabbitFunc.Runtime;
|
||
|
using System.Collections.ObjectModel;
|
||
|
using System.Text;
|
||
|
using MissingMethodException = EC.Helper.RabbitFunc.Runtime.MissingMethodException;
|
||
|
|
||
|
namespace EC.Helper.RabbitFunc.Expressions;
|
||
|
|
||
|
public class MethodCallExpression : Expression
|
||
|
{
|
||
|
internal MethodCallExpression(Expression instance, string methodName, IList<Expression> arguments)
|
||
|
: base(ExpressionType.MethodCall)
|
||
|
{
|
||
|
Instance = instance;
|
||
|
MethodName = methodName;
|
||
|
Arguments = new ReadOnlyCollection<Expression>(arguments);
|
||
|
}
|
||
|
|
||
|
public Expression Instance { get; }
|
||
|
|
||
|
public string MethodName { get; }
|
||
|
|
||
|
public ReadOnlyCollection<Expression> Arguments { get; }
|
||
|
|
||
|
internal LambdaExpression GetLambda(RabbitDomain domain)
|
||
|
{
|
||
|
LambdaExpression lambda;
|
||
|
if (domain != null)
|
||
|
{
|
||
|
lambda = domain.GetLambda(MethodName);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lambda = Rabbit.GetSystemLambda(MethodName);
|
||
|
}
|
||
|
|
||
|
return lambda;
|
||
|
}
|
||
|
|
||
|
public override object Eval(RuntimeContext context)
|
||
|
{
|
||
|
if (context == null)
|
||
|
throw new ArgumentNullException(nameof(context));
|
||
|
|
||
|
if (Instance == null)
|
||
|
{
|
||
|
var lambdaExpression = GetLambda(context.Domain);
|
||
|
if (lambdaExpression == null)
|
||
|
throw new MissingMethodException(string.Format("missing method:{0}", MethodName));
|
||
|
if (Arguments.Count != lambdaExpression.Parameters.Count)
|
||
|
throw new RuntimeException(string.Format("method:{0}. parame count error!", MethodName));
|
||
|
|
||
|
var lambdaContext = new RuntimeContext(context);
|
||
|
for (int i = 0; i < Arguments.Count; i++)
|
||
|
{
|
||
|
var parameter = lambdaExpression.Parameters[i];
|
||
|
var argument = Arguments[i];
|
||
|
var value = argument.Eval(context);
|
||
|
lambdaContext.Variable(parameter.Name, value);
|
||
|
}
|
||
|
|
||
|
return lambdaExpression.Body.Eval(lambdaContext);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
throw new NotSupportedException();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override string ToString()
|
||
|
{
|
||
|
var sb = new StringBuilder();
|
||
|
sb.Append(MethodName).Append('(');
|
||
|
using (var e = Arguments.GetEnumerator())
|
||
|
{
|
||
|
if (e.MoveNext())
|
||
|
{
|
||
|
sb.Append(e.Current.ToString());
|
||
|
while (e.MoveNext())
|
||
|
{
|
||
|
sb.Append(',');
|
||
|
sb.Append(e.Current.ToString());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
sb.Append(')');
|
||
|
return sb.ToString();
|
||
|
}
|
||
|
}
|