DynamicObjectAccessor.cs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. using System.Dynamic;
  2. using System.Reflection;
  3. using Jint.Native;
  4. #pragma warning disable IL2092
  5. namespace Jint.Runtime.Interop.Reflection;
  6. internal sealed class DynamicObjectAccessor : ReflectionAccessor
  7. {
  8. private JintSetMemberBinder? _setter;
  9. private JintGetMemberBinder? _getter;
  10. public DynamicObjectAccessor() : base(memberType: null)
  11. {
  12. }
  13. public override bool Writable => true;
  14. protected override object? DoGetValue(object target, string memberName)
  15. {
  16. var dynamicObject = (DynamicObject) target;
  17. var getter = _getter ??= new JintGetMemberBinder(memberName, ignoreCase: true);
  18. dynamicObject.TryGetMember(getter, out var result);
  19. return result;
  20. }
  21. protected override void DoSetValue(object target, string memberName, object? value)
  22. {
  23. var dynamicObject = (DynamicObject) target;
  24. var setter = _setter ??= new JintSetMemberBinder(memberName, ignoreCase: true);
  25. dynamicObject.TrySetMember(setter, value);
  26. }
  27. protected override object? ConvertValueToSet(Engine engine, object value)
  28. {
  29. // we expect value to be generally CLR type, convert when possible
  30. return value switch
  31. {
  32. JsBoolean jsBoolean => jsBoolean._value ? JsBoolean.BoxedTrue : JsBoolean.BoxedFalse,
  33. JsString jsString => jsString.ToString(),
  34. JsNumber jsNumber => jsNumber._value,
  35. JsNull => null,
  36. JsUndefined => null,
  37. _ => value
  38. };
  39. }
  40. private sealed class JintGetMemberBinder : GetMemberBinder
  41. {
  42. public JintGetMemberBinder(string name, bool ignoreCase) : base(name, ignoreCase)
  43. {
  44. }
  45. public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject? errorSuggestion)
  46. {
  47. throw new NotImplementedException(nameof(FallbackGetMember) + " not implemented");
  48. }
  49. }
  50. private sealed class JintSetMemberBinder : SetMemberBinder
  51. {
  52. public JintSetMemberBinder(string name, bool ignoreCase) : base(name, ignoreCase)
  53. {
  54. }
  55. public override DynamicMetaObject FallbackSetMember(
  56. DynamicMetaObject target,
  57. DynamicMetaObject value,
  58. DynamicMetaObject? errorSuggestion)
  59. {
  60. throw new NotImplementedException(nameof(FallbackSetMember) + " not implemented");
  61. }
  62. }
  63. }