generated from tc39/template-for-proposals
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathspec.emu
189 lines (179 loc) · 11.5 KB
/
spec.emu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
<!doctype html>
<meta charset="utf8">
<link rel="stylesheet" href="./spec.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">
<script src="./spec.js"></script>
<pre class="metadata">
title: JSON.parseImmutable
stage: 2
contributors: Robin Ricard, Rick Button, Ashley Claymore, Nicolò Ribaudo
</pre>
<emu-biblio href="./biblio.json"></emu-biblio>
<emu-clause id="sec-structured-data">
<h1>Structured Data</h1>
<emu-clause id="sec-json-object">
<h1>The JSON Object</h1>
<emu-clause id="sec-json.parse">
<h1>JSON.parse ( _text_ [ , _reviver_ ] )</h1>
<p>The `parse` function parses a JSON text (a JSON-formatted String) and produces an ECMAScript value. The JSON format represents literals, arrays, and objects with a syntax similar to the syntax for ECMAScript literals, Array Initializers, and Object Initializers. After parsing, JSON objects are realized as ECMAScript objects. JSON arrays are realized as ECMAScript Array instances. JSON strings, numbers, booleans, and null are realized as ECMAScript Strings, Numbers, Booleans, and *null*.</p>
<p>The optional _reviver_ parameter is a function that takes two parameters, _key_ and _value_. It can filter and transform the results. It is called with each of the _key_/_value_ pairs produced by the parse, and its return value is used instead of the original value. If it returns what it received, the structure is not modified. If it returns *undefined* then the property is deleted from the result.</p>
<emu-alg>
1. <del>Let _jsonString_ be ? ToString(_text_).</del>
1. <del>Parse StringToCodePoints(_jsonString_) as a JSON text as specified in ECMA-404. Throw a *SyntaxError* exception if it is not a valid JSON text as defined in that specification.</del>
1. <del>Let _scriptString_ be the string-concatenation of *"("*, _jsonString_, and *");"*.</del>
1. <del>Let _completion_ be the result of parsing and evaluating StringToCodePoints(_scriptString_) as if it was the source text of an ECMAScript |Script|. The extended PropertyDefinitionEvaluation semantics defined in must not be used during the evaluation.</del>
1. <del>Let _unfiltered_ be _completion_.[[Value]].</del>
1. <del>Assert: _unfiltered_ is either a String, Number, Boolean, Null, or an Object that is defined by either an |ArrayLiteral| or an |ObjectLiteral|.</del>
1. <ins>Let _unfiltered_ be ? ParseJSONText(_text_).</ins>
1. If IsCallable(_reviver_) is *true*, then
1. Let _root_ be OrdinaryObjectCreate(%Object.prototype%).
1. Let _rootName_ be the empty String.
1. Perform ! CreateDataPropertyOrThrow(_root_, _rootName_, _unfiltered_).
1. Return ? InternalizeJSONProperty(_root_, _rootName_, _reviver_).
1. Else,
1. Return _unfiltered_.
</emu-alg>
<p>This function is the <dfn>%JSONParse%</dfn> intrinsic object.</p>
<p>The *"length"* property of the `parse` function is 2.</p>
<emu-clause id="sec-parsejsontext" type="abstract operation">
<h1>
<ins>
ParseJSONText (
_text_: an ECMAScript language value
)
</ins>
</h1>
<dl class="header">
<dt>description</dt>
<dd>It parses a JSON text (a JSON-formatted String) and produces an ECMAScript value.</dd>
</dl>
<emu-alg>
1. Let _jsonString_ be ? ToString(_text_).
1. Parse StringToCodePoints(_jsonString_) as a JSON text as specified in ECMA-404. Throw a *SyntaxError* exception if it is not a valid JSON text as defined in that specification.
1. Let _scriptString_ be the string-concatenation of *"("*, _jsonString_, and *");"*.
1. Let _completion_ be the result of parsing and evaluating StringToCodePoints(_scriptString_) as if it was the source text of an ECMAScript |Script|. The extended PropertyDefinitionEvaluation semantics defined in must not be used during the evaluation.
1. Let _unfiltered_ be _completion_.[[Value]].
1. Assert: _unfiltered_ is either a String, Number, Boolean, Null, or an Object that is defined by either an |ArrayLiteral| or an |ObjectLiteral|.
1. Return _unfiltered_.
</emu-alg>
</emu-clause>
</emu-clause>
<emu-clause id="sec-json.parseimmutable">
<h1><ins>JSON.parseImmutable ( _text_ [ , _reviver_ ] )</ins></h1>
<p>The `parseImmutable` function parses a JSON text (a JSON-formatted String) and produces an ECMAScript value. The JSON format represents literals, arrays, and objects with a syntax similar to the syntax for ECMAScript literals, Array Initializers, and Object Initializers. After parsing, JSON objects are realized as ECMAScript records. JSON arrays are realized as ECMAScript tuples. JSON strings, numbers, booleans, and null are realized as ECMAScript Strings, Numbers, Booleans, and *null*.</p>
<p>The optional _reviver_ parameter is a function that takes two parameters, _key_ and _value_. It can filter and transform the results. It is called with each of the _key_/_value_ pairs produced by the parse, and its return value is used instead of the original value. If it returns what it received, the structure is not modified. If it returns *undefined* then the property is deleted from the result.</p>
<emu-alg>
1. Let _unfiltered_ be ? ParseJSONText(_text_).
1. Return ? BuildImmutableProperty(_unfiltered_, *""*, _reviver_).
</emu-alg>
<p>This function is the <dfn>%JSONParseImmutable%</dfn> intrinsic object.</p>
<p>The *"length"* property of the `parseImmutable` function is 2.</p>
<emu-clause id="sec-buildimmutableproperty" type="abstract operation">
<h1>
<ins>
BuildImmutableProperty (
_value_: an ECMAScript language value,
_name_: a String,
_reviver_: a function object or Undefined,
)
</ins>
</h1>
<dl class="header"></dl>
<emu-alg>
1. If Type(_value_) is Object, then
1. Let _isArray_ be ? IsArray(_val_).
1. If _isArray_ is *true*, then
1. Let _items_ be a new empty List.
1. Let _I_ be 0.
1. Let _len_ be ? LengthOfArrayLike(_val_).
1. Repeat, while _I_ < _len_,
1. Let _childName_ be ! ToString(_I_).
1. Let _childValue_ be ? Get(_value_, ! _childName_).
1. Let _newElement_ be ? BuildImmutableProperty(_childValue_, _childName_, _reviver_).
1. Assert: Type(_newElement_) is not Object.
1. Append _newElement_ to _items_.
1. Set _I_ to _I_ + 1.
1. Let _immutable_ be a new <emu-xref href="#sec-tuple-value">Tuple value</emu-xref> whose [[Sequence]] is _items_.
1. Else,
1. Let _props_ be ? EnumerableOwnPropertyNames(_obj_, ~key+value~).
1. Let _fields_ be a new empty List.
1. For each element _prop_ of _props_, do
1. Let _childName_ be ! GetV(_prop_, `"0"`).
1. Let _childValue_ be ! GetV(_prop_, `"1"`).
1. Let _newElement_ be ? BuildImmutableProperty(_childValue_, _childName_, _reviver_).
1. Assert: Type(_newElement_) is not Object.
1. If _newElement_ is not *undefined*, then
1. Let _field_ be the Record { [[Key]]: _childName_, [[Value]]: _newElement_ }.
1. Append _field_ to _fields_.
1. Let _immutable_ be ! CreateRecord(_fields_).
1. Else,
1. Let _immutable_ be _value_.
1. If IsCallable(_reviver_) is *true*, then
1. Let _immutable_ be ? Call(_reviver_, *undefined*, « _name_, _immutable_ »).
1. If Type(_immutable_) is Object, throw a *TypeError* exception.
1. Return _immutable_.
</emu-alg>
<p>It is not permitted for a conforming implementation of `JSON.parseImmutable` to extend the JSON grammars. If an implementation wishes to support a modified or extended JSON interchange format it must do so by defining a different parse function.</p>
<emu-note>
<p>In the case where there are duplicate name Strings within an object, lexically preceding values for the same key shall be overwritten.</p>
</emu-note>
</emu-clause>
<emu-note>
<p>There are two differences in the behaviour of the _reviver_ parameter of the *JSON.parse* and *JSON.parseImmutable* functions:</p>
<ul>
<li>*JSON.parse* passes the parent object as the *this* value, while *JSON.parseImmutable* passes *undefined*.</li>
<li>When _reviver_ returns *undefined* for an array element, it introduced an hole. When _reviver_ returns *undefined* for a tuple element, *undefined* is used as the resulting value.</li>
</ul>
</emu-note>
</emu-clause>
<emu-clause id="sec-json.stringify">
<h1>JSON.stringify ( _value_ [ , _replacer_ [ , _space_ ] ] )</h1>
<emu-clause id="sec-serializejsonproperty" type="abstract operation">
<h1>
SerializeJSONProperty (
_state_: unknown,
_key_: unknown,
_holder_: unknown,
)
</h1>
<dl class="header"></dl>
<emu-alg>
1. Let _value_ be ? Get(_holder_, _key_).
1. If Type(_value_) is Object or BigInt, then
1. Let _toJSON_ be ? GetV(_value_, *"toJSON"*).
1. If IsCallable(_toJSON_) is *true*, then
1. Set _value_ to ? Call(_toJSON_, _value_, « _key_ »).
1. If _state_.[[ReplacerFunction]] is not *undefined*, then
1. Set _value_ to ? Call(_state_.[[ReplacerFunction]], _holder_, « _key_, _value_ »).
1. If Type(_value_) is Object, then
1. If _value_ has a [[NumberData]] internal slot, then
1. Set _value_ to ? ToNumber(_value_).
1. Else if _value_ has a [[StringData]] internal slot, then
1. Set _value_ to ? ToString(_value_).
1. Else if _value_ has a [[BooleanData]] internal slot, then
1. Set _value_ to _value_.[[BooleanData]].
1. Else if _value_ has a [[BigIntData]] internal slot, then
1. Set _value_ to _value_.[[BigIntData]].
1. If _value_ is *null*, return *"null"*.
1. If _value_ is *true*, return *"true"*.
1. If _value_ is *false*, return *"false"*.
1. <ins>If Type(_value_) is Record or Type(_value_) is Tuple, set _value_ to ! ToObject(_value_).</ins>
1. If Type(_value_) is String, return QuoteJSONString(_value_).
1. If Type(_value_) is Number, then
1. If _value_ is finite, return ! ToString(_value_).
1. Return *"null"*.
1. If Type(_value_) is BigInt, throw a *TypeError* exception.
1. If Type(_value_) is Object and IsCallable(_value_) is *false*, then
1. <del>Let _isArray_ be ? IsArray(_value_).</del>
1. <ins>If ! IsTuple(_value_) is *true*, then</ins>
1. <ins>Let _isArrayLike_ be *true*.</ins>
1. <ins>Else,</ins>
1. <ins>Let _isArrayLike_ be ? IsArray(_value_).</ins>
1. If <del>_isArray_</del><ins>_isArrayLike_</ins> is *true*, return ? SerializeJSONArray(_state_, _value_).
1. Return ? SerializeJSONObject(_state_, _value_).
1. Return *undefined*.
</emu-alg>
</emu-clause>
</emu-clause>
</emu-clause>
</emu-clause>