DynamicObjectAccessor.cs 2.3 KB

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