DynamicObjectAccessor.cs 2.4 KB

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