100 lines
3.2 KiB
C#
100 lines
3.2 KiB
C#
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using Upsilon.Evaluator;
|
|
using Upsilon.StandardLibraries;
|
|
|
|
namespace Upsilon.BaseTypes.UserData
|
|
{
|
|
public class UserDataMethod
|
|
{
|
|
public class UserDataMethodPart
|
|
{
|
|
public UserDataMethodPart(MethodInfo method)
|
|
{
|
|
Method = method;
|
|
var pars = method.GetParameters();
|
|
Attribute = (ScriptFunctionAttribute) method.GetCustomAttribute(typeof(ScriptFunctionAttribute));
|
|
|
|
var ls = new List<UserDataMethodParameter>();
|
|
foreach (var parameter in pars)
|
|
{
|
|
if (parameter.ParameterType == typeof(Script))
|
|
continue;
|
|
if (parameter.ParameterType == typeof(EvaluationScope))
|
|
continue;
|
|
ls.Add(new UserDataMethodParameter(parameter));
|
|
}
|
|
Parameters = ls.ToArray();
|
|
}
|
|
|
|
public MethodInfo Method { get; }
|
|
public ScriptFunctionAttribute Attribute { get; }
|
|
public UserDataMethodParameter[] Parameters { get; }
|
|
}
|
|
|
|
public struct UserDataMethodParameter
|
|
{
|
|
public UserDataMethodParameter(ParameterInfo info)
|
|
{
|
|
Type = info.ParameterType;
|
|
if (Type.IsGenericType)
|
|
Type = Type.GetGenericTypeDefinition();
|
|
IsOptional = info.IsOptional;
|
|
}
|
|
|
|
public System.Type Type { get; }
|
|
public bool IsOptional { get; }
|
|
}
|
|
|
|
public string Name { get; }
|
|
private List<UserDataMethodPart> MethodParts { get; }
|
|
public System.Type ReturnType { get; }
|
|
|
|
public UserDataMethod(MethodInfo method)
|
|
{
|
|
Name = method.Name;
|
|
var part = new UserDataMethodPart(method);
|
|
MethodParts = new List<UserDataMethodPart>()
|
|
{
|
|
part
|
|
};
|
|
ReturnType = part.Method.ReturnType;
|
|
}
|
|
|
|
public void LoadMethodPart(MethodInfo method)
|
|
{
|
|
var part = new UserDataMethodPart(method);
|
|
MethodParts.Add(part);
|
|
}
|
|
|
|
public List<UserDataMethodPart> GetMethods()
|
|
{
|
|
return MethodParts;
|
|
}
|
|
|
|
public MethodInfo GetMethod(ref object[] arguments)
|
|
{
|
|
foreach (var userDataMethodPart in MethodParts)
|
|
{
|
|
var methodBase = userDataMethodPart.Method;
|
|
if (UpsilonBinder.Default.IsValidMatch(methodBase, arguments.Select(x => x.GetType()).ToArray()))
|
|
{
|
|
var parameters = methodBase.GetParameters();
|
|
for (var i = 0; i < parameters.Length; i++)
|
|
{
|
|
var argument = arguments[i];
|
|
var requiredType = parameters[i].ParameterType;
|
|
arguments[i] =
|
|
UpsilonBinder.Default.ChangeType(argument, requiredType, CultureInfo.InvariantCulture);
|
|
}
|
|
|
|
return methodBase;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
} |