Camera Information System
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

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();
}
}