ReflectionDescriptor.cs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. using System.Reflection;
  2. using Jint.Native;
  3. using Jint.Runtime.Interop;
  4. using Jint.Runtime.Interop.Reflection;
  5. namespace Jint.Runtime.Descriptors.Specialized
  6. {
  7. internal sealed class ReflectionDescriptor : PropertyDescriptor
  8. {
  9. private readonly Engine _engine;
  10. private readonly ReflectionAccessor _reflectionAccessor;
  11. private readonly object _target;
  12. public ReflectionDescriptor(
  13. Engine engine,
  14. ReflectionAccessor reflectionAccessor,
  15. object target,
  16. bool enumerable)
  17. : base((enumerable ? PropertyFlag.Enumerable : PropertyFlag.None) | PropertyFlag.CustomJsValue)
  18. {
  19. _flags |= PropertyFlag.NonData;
  20. _engine = engine;
  21. _reflectionAccessor = reflectionAccessor;
  22. _target = target;
  23. if (reflectionAccessor.Writable && engine.Options.Interop.AllowWrite)
  24. {
  25. Set = new SetterFunction(_engine, DoSet);
  26. }
  27. if (reflectionAccessor.Readable)
  28. {
  29. Get = new GetterFunction(_engine, DoGet);
  30. }
  31. }
  32. public override JsValue? Get { get; }
  33. public override JsValue? Set { get; }
  34. protected internal override JsValue? CustomValue
  35. {
  36. get => DoGet(null);
  37. set => DoSet(null, value);
  38. }
  39. private JsValue DoGet(JsValue? thisObj)
  40. {
  41. var value = _reflectionAccessor.GetValue(_engine, _target);
  42. var type = _reflectionAccessor.MemberType;
  43. return JsValue.FromObjectWithType(_engine, value, type);
  44. }
  45. private void DoSet(JsValue? thisObj, JsValue? v)
  46. {
  47. try
  48. {
  49. _reflectionAccessor.SetValue(_engine, _target, v!);
  50. }
  51. catch (TargetInvocationException exception)
  52. {
  53. ExceptionHelper.ThrowMeaningfulException(_engine, exception);
  54. }
  55. }
  56. }
  57. }