MethodInfoFunctionInstance.cs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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. using System;
  9. public sealed class MethodInfoFunctionInstance : FunctionInstance
  10. {
  11. private readonly MethodInfo[] _methods;
  12. public MethodInfoFunctionInstance(Engine engine, MethodInfo[] methods)
  13. : base(engine, null, null, false)
  14. {
  15. _methods = methods;
  16. Prototype = engine.Function.PrototypeObject;
  17. }
  18. public override JsValue Call(JsValue thisObject, JsValue[] arguments)
  19. {
  20. return Invoke(_methods, thisObject, arguments);
  21. }
  22. public JsValue Invoke(MethodInfo[] methodInfos, JsValue thisObject, JsValue[] arguments)
  23. {
  24. var methods = TypeConverter.FindBestMatch(Engine, methodInfos, arguments).ToList();
  25. foreach (var method in methods)
  26. {
  27. var parameters = new object[arguments.Length];
  28. try
  29. {
  30. for (var i = 0; i < arguments.Length; i++)
  31. {
  32. var parameterType = method.GetParameters()[i].ParameterType;
  33. if (parameterType == typeof(JsValue))
  34. {
  35. parameters[i] = arguments[i];
  36. }
  37. else
  38. {
  39. parameters[i] = Engine.ClrTypeConverter.Convert(
  40. arguments[i].ToObject(),
  41. parameterType,
  42. CultureInfo.InvariantCulture);
  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. var result = JsValue.FromObject(Engine, method.Invoke(thisObject.ToObject(), parameters.ToArray()));
  50. // todo: cache method info
  51. return result;
  52. }
  53. catch (Exception ex)
  54. {
  55. throw new JintInteropException(ex);
  56. }
  57. }
  58. throw new JavaScriptException(Engine.TypeError, "No public methods with the specified arguments were found.");
  59. }
  60. }
  61. }