"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ exports.default = function (realm) { var obj = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype, "JSON"); // ECMA262 24.3.3 obj.defineNativeProperty(realm.intrinsics.SymbolToStringTag, new _index.StringValue(realm, "JSON"), { writable: false }); // ECMA262 24.3.2 obj.defineNativeMethod("stringify", 3, function (context, _ref3) { var _ref4 = _slicedToArray(_ref3, 3), value = _ref4[0], replacer = _ref4[1], space = _ref4[2]; replacer = replacer.throwIfNotConcrete(); space = space.throwIfNotConcrete(); // 1. Let stack be a new empty List. var stack = []; // 2. Let indent be the empty String. var indent = ""; // 3. Let PropertyList and ReplacerFunction be undefined. var PropertyList = void 0, ReplacerFunction = void 0; // 4. If Type(replacer) is Object, then if (replacer instanceof _index.ObjectValue) { // a. If IsCallable(replacer) is true, then if ((0, _index2.IsCallable)(realm, replacer)) { // i. Let ReplacerFunction be replacer. ReplacerFunction = replacer; } else { // b. Else, // i. Let isArray be ? IsArray(replacer). var isArray = (0, _index2.IsArray)(realm, replacer); // ii. If isArray is true, then if (isArray === true) { // i. Let PropertyList be a new empty List. PropertyList = []; // ii. Let len be ? ToLength(? Get(replacer, "length")). var len = _singletons.To.ToLength(realm, (0, _index2.Get)(realm, replacer, "length")); // iii. Let k be 0. var k = 0; // iv. Repeat while k= 0) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "cyclical error"); } // 2. Append value to stack. context.stack.push(value); // 3. Let stepback be indent. var stepback = context.indent; // 4. Let indent be the concatenation of indent and gap. context.indent += context.gap; // 5. Let partial be a new empty List. var partial = []; // 6. Let len be ? ToLength(? Get(value, "length")). var len = _singletons.To.ToLength(realm, (0, _index2.Get)(realm, value, "length")); // 7. Let index be 0. var index = 0; // 8. Repeat while index < len while (index < len) { // a. Let strP be ? SerializeJSONProperty(! ToString(index), value). var strP = SerializeJSONProperty(realm, new _index.StringValue(realm, index + ""), value, context); // b. If strP is undefined, then if (strP === undefined) { // i. Append "null" to partial. partial.push("null"); } else { // c. Else, // i. Append strP to partial. partial.push(strP); } // d. Increment index by 1. index++; } // 9. If partial is empty, then var final = ""; if (!partial.length) { // a. Let final be "[]". final = "[]"; } else { // 10. Else, // a. If gap is the empty String, then if (!context.gap) { // i. Let properties be a String formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with code unit 0x002C (COMMA). A comma is not inserted either before the first String or after the last String. var properties = partial.join(","); // ii. Let final be the result of concatenating "[", properties, and "]". final = "[" + properties + "]"; } else { // b. Else, // i. Let separator be the result of concatenating code unit 0x002C (COMMA), code unit 0x000A (LINE FEED), and indent. // ii. Let properties be a String formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with separator. The separator String is not inserted either before the first String or after the last String. // iii. Let final be the result of concatenating "[", code unit 0x000A (LINE FEED), indent, properties, code unit 0x000A (LINE FEED), stepback, and "]". } } // 11. Remove the last element of stack. context.stack.pop(); // 12. Let indent be stepback. context.indent = stepback; // 13. Return final. return final; } function QuoteJSONString(realm, value) { return JSON.stringify(value.value); } function SerializeJSONObject(realm, value, context) { // 1. If stack contains value, throw a TypeError exception because the structure is cyclical. if (context.stack.indexOf(value) >= 0) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "cyclical error"); } // 2. Append value to stack. context.stack.push(value); // 3. Let stepback be indent. var stepback = context.indent; // 4. Let indent be the concatenation of indent and gap. context.indent += context.gap; // 5. If PropertyList is not undefined, then var K = void 0; if (context.PropertyList !== undefined) { // a. Let K be PropertyList. K = context.PropertyList; } else { // 6. Else, // a. Let K be ? EnumerableOwnProperties(value, "key"). K = (0, _index2.EnumerableOwnProperties)(realm, value, "key"); } // 7. Let partial be a new empty List. var partial = []; // 8. For each element P of K, var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = K[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var P = _step.value; (0, _invariant2.default)(P instanceof _index.StringValue); // a. Let strP be ? SerializeJSONProperty(P, value). var strP = SerializeJSONProperty(realm, P, value, context); // b. If strP is not undefined, then if (strP !== undefined) { // i. Let member be QuoteJSONString(P). var member = QuoteJSONString(realm, P); // ii. Let member be the concatenation of member and the string ":". member += ":"; // iii. If gap is not the empty String, then if (context.gap) { // 1. Let member be the concatenation of member and code unit 0x0020 (SPACE). member += " "; } // iv. Let member be the concatenation of member and strP. member += strP; // v. Append member to partial. partial.push(member); } } // 9. If partial is empty, then } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } var final = ""; if (!partial.length) { // a. Let final be "{}". final = "{}"; } else { // 10. Else, // a. If gap is the empty String, then if (!context.gap) { // i. Let properties be a String formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with code unit 0x002C (COMMA). A comma is not inserted either before the first String or after the last String. var properties = partial.join(","); // ii. Let final be the result of concatenating "{", properties, and "}". final = "{" + properties + "}"; } else { // b. Else gap is not the empty String, // i. Let separator be the result of concatenating code unit 0x002C (COMMA), code unit 0x000A (LINE FEED), and indent. // ii. Let properties be a String formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with separator. The separator String is not inserted either before the first String or after the last String. // iii. Let final be the result of concatenating "{", code unit 0x000A (LINE FEED), indent, properties, code unit 0x000A (LINE FEED), stepback, and "}". } } // 11. Remove the last element of stack. context.stack.pop(); // 12. Let indent be stepback. context.indent = stepback; // 13. Return final. return final; } function SerializeJSONProperty(realm, key, holder, context) { // 1. Let value be ? Get(holder, key). var value = (0, _index2.Get)(realm, holder, key).throwIfNotConcrete(); // 2. If Type(value) is Object, then if (value instanceof _index.ObjectValue) { // a. Let toJSON be ? Get(value, "toJSON"). var toJSON = (0, _index2.Get)(realm, value, "toJSON"); // b. If IsCallable(toJSON) is true, then if ((0, _index2.IsCallable)(realm, toJSON)) { // i. Let value be ? Call(toJSON, value, « key »). value = (0, _index2.Call)(realm, toJSON, value, [key]); } } // 3. If ReplacerFunction is not undefined, then if (context.ReplacerFunction) { // a. Let value be ? Call(ReplacerFunction, holder, « key, value »). value = (0, _index2.Call)(realm, context.ReplacerFunction, holder, [key, value]); } // 4. If Type(value) is Object, then if (value instanceof _index.ObjectValue) { // a. If value has a [[NumberData]] internal slot, then if (value.$NumberData) { // b. Let value be ? ToNumber(value). value = new _index.NumberValue(realm, _singletons.To.ToNumber(realm, value)); } else if (value.$StringData) { // c. Else if value has a [[StringData]] internal slot, then // d. Let value be ? ToString(value). value = new _index.StringValue(realm, _singletons.To.ToString(realm, value)); } else if (value.$BooleanData) { // e. Else if value has a [[BooleanData]] internal slot, then // f. Let value be the value of the [[BooleanData]] internal slot of value. value = value.$BooleanData; } } // 5. If value is null, return "null". if (value instanceof _index.NullValue) return "null"; // 6. If value is true, return "true". if (value instanceof _index.BooleanValue && value.value) return "true"; // 7. If value is false, return "false". if (value instanceof _index.BooleanValue && !value.value) return "false"; // 8. If Type(value) is String, return QuoteJSONString(value). if (value instanceof _index.StringValue) return QuoteJSONString(realm, value); // 9. If Type(value) is Number, then if (value instanceof _index.NumberValue) { // a. If value is finite, return ! ToString(value). if (isFinite(value.value)) { return _singletons.To.ToString(realm, value); } else { // b. Else, return "null". return "null"; } } // 10. If Type(value) is Object and IsCallable(value) is false, then if (value instanceof _index.ObjectValue && !(0, _index2.IsCallable)(realm, value)) { // a. Let isArray be ? IsArray(value). var isArray = (0, _index2.IsArray)(realm, value); // b. If isArray is true, return ? SerializeJSONArray(value). if (isArray) { return SerializeJSONArray(realm, value, context); } else { // c. Else, return ? SerializeJSONObject(value). return SerializeJSONObject(realm, value, context); } } // 1. Return undefined. return undefined; } function InternalCloneObject(realm, val) { var clone = _singletons.Create.ObjectCreate(realm, realm.intrinsics.ObjectPrototype); var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = val.properties[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var _ref = _step2.value; var _ref2 = _slicedToArray(_ref, 2); var key = _ref2[0]; var binding = _ref2[1]; if (binding === undefined || binding.descriptor === undefined) continue; // deleted (0, _invariant2.default)(binding.descriptor !== undefined); var value = binding.descriptor.value; _singletons.Properties.ThrowIfMightHaveBeenDeleted(value); if (value === undefined) { _index.AbstractValue.reportIntrospectionError(val, key); // cannot handle accessors throw new _errors.FatalError(); } (0, _invariant2.default)(value instanceof _index.Value); _singletons.Create.CreateDataProperty(realm, clone, key, InternalJSONClone(realm, value)); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } if (val.isPartialObject()) clone.makePartial(); if (val.isSimpleObject()) clone.makeSimple(); clone.isTemplate = true; // because this object doesn't exist ahead of time, and the visitor would otherwise declare it in the common scope return clone; } var JSONStringifyStr = "global.JSON.stringify(A)"; var JSONStringify = (0, _builder2.default)(JSONStringifyStr); var JSONParseStr = "global.JSON.parse(A)"; var JSONParse = (0, _builder2.default)(JSONParseStr); function InternalJSONClone(realm, val) { if (val instanceof _index.AbstractValue) { if (val instanceof _index.AbstractObjectValue) { var strVal = _index.AbstractValue.createFromTemplate(realm, JSONStringify, _index.StringValue, [val], JSONStringifyStr); var obVal = _index.AbstractValue.createFromTemplate(realm, JSONParse, _index.ObjectValue, [strVal], JSONParseStr); obVal.values = new _index3.ValuesDomain(new Set([InternalCloneObject(realm, val.getTemplate())])); return obVal; } // TODO #1010: NaN and Infinity must be mapped to null. return val; } if (val instanceof _index.NumberValue && !isFinite(val.value) || val instanceof _index.UndefinedValue || val instanceof _index.NullValue) { return realm.intrinsics.null; } if (val instanceof _index.PrimitiveValue) { return val; } if (val instanceof _index.ObjectValue) { var clonedObj = void 0; var isArray = (0, _index2.IsArray)(realm, val); if (isArray === true) { clonedObj = _singletons.Create.ObjectCreate(realm, realm.intrinsics.ArrayPrototype); var I = 0; var len = _singletons.To.ToLength(realm, (0, _index2.Get)(realm, val, "length")); while (I < len) { var P = _singletons.To.ToString(realm, new _index.NumberValue(realm, I)); var newElement = (0, _index2.Get)(realm, val, P); if (!(newElement instanceof _index.UndefinedValue)) { // TODO #1011: An abstract value that ultimately yields undefined should still be skipped _singletons.Create.CreateDataProperty(realm, clonedObj, P, InternalJSONClone(realm, newElement)); } I += 1; } } else { clonedObj = _singletons.Create.ObjectCreate(realm, realm.intrinsics.ObjectPrototype); var valIsPartial = false; if (val.isPartialObject()) { valIsPartial = true; val.makeNotPartial(); } var keys = (0, _index2.EnumerableOwnProperties)(realm, val, "key"); if (valIsPartial) val.makePartial(); var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = keys[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var _P = _step3.value; (0, _invariant2.default)(_P instanceof _index.StringValue); var _newElement = (0, _index2.Get)(realm, val, _P); if (!(_newElement instanceof _index.UndefinedValue)) { // TODO #1011: An abstract value that ultimately yields undefined should still be skipped _singletons.Create.CreateDataProperty(realm, clonedObj, _P, InternalJSONClone(realm, _newElement)); } } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } } if (val.isPartialObject()) clonedObj.makePartial(); clonedObj.makeSimple(); // The result of a JSON clone is always simple return clonedObj; } (0, _invariant2.default)(false); } //# sourceMappingURL=JSON.js.map