PropertyDescriptor.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using Jint.Native;
  2. using Jint.Native.Object;
  3. using Jint.Runtime.Descriptors.Specialized;
  4. namespace Jint.Runtime.Descriptors
  5. {
  6. public class PropertyDescriptor : IPropertyDescriptor
  7. {
  8. public static readonly IPropertyDescriptor Undefined = new PropertyDescriptor();
  9. protected PropertyDescriptor()
  10. {
  11. }
  12. public PropertyDescriptor(JsValue value, bool? writable, bool? enumerable, bool? configurable)
  13. {
  14. Value = value;
  15. if (writable.HasValue)
  16. {
  17. Writable = writable.Value;
  18. }
  19. if (enumerable.HasValue)
  20. {
  21. Enumerable = enumerable.Value;
  22. }
  23. if (configurable.HasValue)
  24. {
  25. Configurable = configurable.Value;
  26. }
  27. }
  28. public PropertyDescriptor(JsValue get, JsValue set, bool? enumerable = null, bool? configurable = null)
  29. {
  30. Get = get;
  31. Set = set;
  32. if (enumerable.HasValue)
  33. {
  34. Enumerable = enumerable.Value;
  35. }
  36. if (configurable.HasValue)
  37. {
  38. Configurable = configurable.Value;
  39. }
  40. }
  41. public PropertyDescriptor(IPropertyDescriptor descriptor)
  42. {
  43. Get = descriptor.Get;
  44. Set = descriptor.Set;
  45. Value = descriptor.Value;
  46. Enumerable = descriptor.Enumerable;
  47. Configurable = descriptor.Configurable;
  48. Writable = descriptor.Writable;
  49. }
  50. public JsValue Get { get; set; }
  51. public JsValue Set { get; set; }
  52. public bool? Enumerable { get; set; }
  53. public bool? Writable { get; set; }
  54. public bool? Configurable { get; set; }
  55. public virtual JsValue Value { get; set; }
  56. public static PropertyDescriptor ToPropertyDescriptor(Engine engine, JsValue o)
  57. {
  58. var obj = o.TryCast<ObjectInstance>();
  59. if (obj == null)
  60. {
  61. throw new JavaScriptException(engine.TypeError);
  62. }
  63. if ((obj.HasProperty("value") || obj.HasProperty("writable")) &&
  64. (obj.HasProperty("get") || obj.HasProperty("set")))
  65. {
  66. throw new JavaScriptException(engine.TypeError);
  67. }
  68. var desc = new PropertyDescriptor();
  69. if (obj.HasProperty("enumerable"))
  70. {
  71. desc.Enumerable = TypeConverter.ToBoolean(obj.Get("enumerable"));
  72. }
  73. if (obj.HasProperty("configurable"))
  74. {
  75. desc.Configurable = TypeConverter.ToBoolean(obj.Get("configurable"));
  76. }
  77. if (obj.HasProperty("value"))
  78. {
  79. var value = obj.Get("value");
  80. desc.Value = value;
  81. }
  82. if (obj.HasProperty("writable"))
  83. {
  84. desc.Writable = TypeConverter.ToBoolean(obj.Get("writable"));
  85. }
  86. if (obj.HasProperty("get"))
  87. {
  88. var getter = obj.Get("get");
  89. if (getter != JsValue.Undefined && getter.TryCast<ICallable>() == null)
  90. {
  91. throw new JavaScriptException(engine.TypeError);
  92. }
  93. desc.Get = getter;
  94. }
  95. if (obj.HasProperty("set"))
  96. {
  97. var setter = obj.Get("set");
  98. if (setter != Native.Undefined.Instance && setter.TryCast<ICallable>() == null)
  99. {
  100. throw new JavaScriptException(engine.TypeError);
  101. }
  102. desc.Set = setter;
  103. }
  104. if (desc.Get != null || desc.Get != null)
  105. {
  106. if (desc.Value != null || desc.Writable.HasValue)
  107. {
  108. throw new JavaScriptException(engine.TypeError);
  109. }
  110. }
  111. return desc;
  112. }
  113. public static JsValue FromPropertyDescriptor(Engine engine, IPropertyDescriptor desc)
  114. {
  115. if (ReferenceEquals(desc, Undefined))
  116. {
  117. return Native.Undefined.Instance;
  118. }
  119. var obj = engine.Object.Construct(Arguments.Empty);
  120. if (desc.IsDataDescriptor())
  121. {
  122. obj.SetOwnProperty("value", new ConfigurableEnumerableWritablePropertyDescriptor(desc.Value != null ? desc.Value : Native.Undefined.Instance));
  123. obj.SetOwnProperty("writable", new ConfigurableEnumerableWritablePropertyDescriptor(desc.Writable.HasValue && desc.Writable.Value));
  124. }
  125. else
  126. {
  127. obj.SetOwnProperty("get", new ConfigurableEnumerableWritablePropertyDescriptor(desc.Get ?? Native.Undefined.Instance));
  128. obj.SetOwnProperty("set", new ConfigurableEnumerableWritablePropertyDescriptor(desc.Set ?? Native.Undefined.Instance));
  129. }
  130. obj.SetOwnProperty("enumerable", new ConfigurableEnumerableWritablePropertyDescriptor(desc.Enumerable.HasValue && desc.Enumerable.Value));
  131. obj.SetOwnProperty("configurable", new ConfigurableEnumerableWritablePropertyDescriptor(desc.Configurable.HasValue && desc.Configurable.Value));
  132. return obj;
  133. }
  134. }
  135. }