|
@@ -1,5 +1,6 @@
|
|
|
using Jint.Native.Object;
|
|
|
using Jint.Runtime;
|
|
|
+using Jint.Runtime.Descriptors;
|
|
|
using Jint.Runtime.Interop;
|
|
|
|
|
|
namespace Jint.Native.Json
|
|
@@ -7,6 +8,7 @@ namespace Jint.Native.Json
|
|
|
public sealed class JsonInstance : ObjectInstance
|
|
|
{
|
|
|
private readonly Engine _engine;
|
|
|
+ private JsValue _reviver;
|
|
|
|
|
|
private JsonInstance(Engine engine)
|
|
|
: base(engine)
|
|
@@ -36,10 +38,93 @@ namespace Jint.Native.Json
|
|
|
FastAddProperty("stringify", new ClrFunctionInstance(Engine, Stringify, 3), true, false, true);
|
|
|
}
|
|
|
|
|
|
+ private JsValue AbstractWalkOperation(ObjectInstance thisObject, string prop)
|
|
|
+ {
|
|
|
+ JsValue value = thisObject.Get(prop);
|
|
|
+ if (value.IsObject())
|
|
|
+ {
|
|
|
+ var valueAsObject = value.AsObject();
|
|
|
+ if (valueAsObject.Class == "Array")
|
|
|
+ {
|
|
|
+ var valAsArray = value.AsArray();
|
|
|
+ var i = 0;
|
|
|
+ var arrLen = valAsArray.GetLength();
|
|
|
+ while (i < arrLen)
|
|
|
+ {
|
|
|
+ var newValue = AbstractWalkOperation(valAsArray, TypeConverter.ToString(i));
|
|
|
+ if (newValue.IsUndefined())
|
|
|
+ {
|
|
|
+ valAsArray.Delete(TypeConverter.ToString(i), false);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ valAsArray.DefineOwnProperty
|
|
|
+ (
|
|
|
+ TypeConverter.ToString(i),
|
|
|
+ new PropertyDescriptor
|
|
|
+ (
|
|
|
+ value: newValue,
|
|
|
+ writable: true,
|
|
|
+ enumerable: true,
|
|
|
+ configurable: true
|
|
|
+ ),
|
|
|
+ false
|
|
|
+ );
|
|
|
+ }
|
|
|
+ i = i + 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ var keys = valueAsObject.GetOwnProperties();
|
|
|
+ foreach (var p in keys)
|
|
|
+ {
|
|
|
+ var newElement = AbstractWalkOperation(valueAsObject, p.Key);
|
|
|
+ if (newElement.IsUndefined())
|
|
|
+ {
|
|
|
+ valueAsObject.Delete(p.Key, false);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ valueAsObject.DefineOwnProperty(
|
|
|
+ p.Key,
|
|
|
+ new PropertyDescriptor
|
|
|
+ (
|
|
|
+ value: newElement,
|
|
|
+ writable: true,
|
|
|
+ enumerable: true,
|
|
|
+ configurable: true
|
|
|
+ ),
|
|
|
+ false
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return _reviver.Invoke(thisObject, new JsValue[] { prop, value });
|
|
|
+ }
|
|
|
+
|
|
|
public JsValue Parse(JsValue thisObject, JsValue[] arguments)
|
|
|
{
|
|
|
var parser = new JsonParser(_engine);
|
|
|
- return parser.Parse(TypeConverter.ToString(arguments[0]));
|
|
|
+ var res = parser.Parse(TypeConverter.ToString(arguments[0]));
|
|
|
+ if (arguments.Length > 1)
|
|
|
+ {
|
|
|
+ this._reviver = arguments[1];
|
|
|
+ ObjectInstance revRes = ObjectConstructor.CreateObjectConstructor(_engine).Construct(Arguments.Empty);
|
|
|
+ revRes.DefineOwnProperty(
|
|
|
+ "",
|
|
|
+ new PropertyDescriptor(
|
|
|
+ value: res,
|
|
|
+ writable: true,
|
|
|
+ enumerable: true,
|
|
|
+ configurable: true
|
|
|
+ ),
|
|
|
+ false
|
|
|
+ );
|
|
|
+ return AbstractWalkOperation(revRes, "");
|
|
|
+ }
|
|
|
+ return res;
|
|
|
}
|
|
|
|
|
|
public JsValue Stringify(JsValue thisObject, JsValue[] arguments)
|