DynamicObjectAccessor.cs 2.7 KB

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