MethodInfoFunctionInstance.cs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. using System.Globalization;
  2. using System.Linq;
  3. using System.Reflection;
  4. using Jint.Native;
  5. using Jint.Native.Function;
  6. namespace Jint.Runtime.Interop
  7. {
  8. public sealed class MethodInfoFunctionInstance : FunctionInstance
  9. {
  10. private readonly MethodInfo[] _methods;
  11. public MethodInfoFunctionInstance(Engine engine, MethodInfo[] methods)
  12. : base(engine, null, null, false)
  13. {
  14. _methods = methods;
  15. Prototype = engine.Function.PrototypeObject;
  16. }
  17. public override JsValue Call(JsValue thisObject, JsValue[] arguments)
  18. {
  19. return Invoke(_methods, thisObject, arguments);
  20. }
  21. public JsValue Invoke(MethodInfo[] methodInfos, JsValue thisObject, JsValue[] arguments)
  22. {
  23. var methods = TypeConverter.FindBestMatch(Engine, methodInfos, arguments).ToList();
  24. var converter = Engine.ClrTypeConverter;
  25. foreach (var method in methods)
  26. {
  27. var parameters = new object[arguments.Length];
  28. var argumentsMatch = true;
  29. for (var i = 0; i < arguments.Length; i++)
  30. {
  31. var parameterType = method.GetParameters()[i].ParameterType;
  32. if (parameterType == typeof(JsValue))
  33. {
  34. parameters[i] = arguments[i];
  35. }
  36. else
  37. {
  38. if (!converter.TryConvert(arguments[i].ToObject(), parameterType, CultureInfo.InvariantCulture, out parameters[i]))
  39. {
  40. argumentsMatch = false;
  41. break;
  42. }
  43. if (typeof(System.Linq.Expressions.LambdaExpression).IsAssignableFrom(parameters[i].GetType()))
  44. {
  45. parameters[i] = (parameters[i] as System.Linq.Expressions.LambdaExpression).Compile();
  46. }
  47. }
  48. }
  49. if (!argumentsMatch)
  50. {
  51. continue;
  52. }
  53. // todo: cache method info
  54. return JsValue.FromObject(Engine, method.Invoke(thisObject.ToObject(), parameters.ToArray()));
  55. }
  56. throw new JavaScriptException(Engine.TypeError, "No public methods with the specified arguments were found.");
  57. }
  58. }
  59. }