MethodInfoFunctionInstance.cs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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.Options.GetTypeConverter().Convert(
  40. arguments[i].ToObject(),
  41. parameterType,
  42. CultureInfo.InvariantCulture);
  43. }
  44. }
  45. var result = JsValue.FromObject(Engine, method.Invoke(thisObject.ToObject(), parameters.ToArray()));
  46. // todo: cache method info
  47. return result;
  48. }
  49. catch (Exception ex)
  50. {
  51. throw new JintInteropException(ex);
  52. }
  53. }
  54. throw new JavaScriptException(Engine.TypeError, "No public methods with the specified arguments were found.");
  55. }
  56. }
  57. }