22// for details. All rights reserved. Use of this source code is governed by a
33// BSD-style license that can be found in the LICENSE file.
44
5- // @dart = 2.5
6-
75// Patch file for dart:convert library.
86
97import 'dart:_js_helper' show argumentErrorValue, patch;
@@ -28,15 +26,15 @@ import 'dart:_native_typed_data' show NativeUint8List;
2826///
2927/// Throws [FormatException] if the input is not valid JSON text.
3028@patch
31- _parseJson (String source, reviver (key, value)) {
29+ _parseJson (String source, reviver (key, value)? ) {
3230 if (source is ! String ) throw argumentErrorValue (source);
3331
3432 var parsed;
3533 try {
3634 parsed = JS ('=Object|JSExtendableArray|Null|bool|num|String' ,
3735 'JSON.parse(#)' , source);
3836 } catch (e) {
39- throw new FormatException (JS ('String' , 'String(#)' , e));
37+ throw FormatException (JS < String > ('String' , 'String(#)' , e));
4038 }
4139
4240 if (reviver == null ) {
@@ -49,20 +47,20 @@ _parseJson(String source, reviver(key, value)) {
4947/// Walks the raw JavaScript value [json] , replacing JavaScript Objects with
5048/// Maps. [json] is expected to be freshly allocated so elements can be replaced
5149/// in-place.
52- _convertJsonToDart (json, reviver (key, value)) {
53- assert (reviver != null );
50+ _convertJsonToDart (json, reviver (Object ? key, Object ? value)) {
5451 walk (e) {
5552 // JavaScript null, string, number, bool are in the correct representation.
56- if (JS ('bool' , '# == null' , e) || JS ('bool' , 'typeof # != "object"' , e)) {
53+ if (JS <bool >('bool' , '# == null' , e) ||
54+ JS <bool >('bool' , 'typeof # != "object"' , e)) {
5755 return e;
5856 }
5957
6058 // This test is needed to avoid identifying '{"__proto__":[]}' as an Array.
6159 // TODO(sra): Replace this test with cheaper '#.constructor === Array' when
6260 // bug 621 below is fixed.
63- if (JS ('bool' , 'Object.getPrototypeOf(#) === Array.prototype' , e)) {
61+ if (JS < bool > ('bool' , 'Object.getPrototypeOf(#) === Array.prototype' , e)) {
6462 // In-place update of the elements since JS Array is a Dart List.
65- for (int i = 0 ; i < JS ('int' , '#.length' , e); i++ ) {
63+ for (int i = 0 ; i < JS < int > ('int' , '#.length' , e); i++ ) {
6664 // Use JS indexing to avoid range checks. We know this is the only
6765 // reference to the list, but the compiler will likely never be able to
6866 // tell that this instance of the list cannot have its length changed by
@@ -76,7 +74,7 @@ _convertJsonToDart(json, reviver(key, value)) {
7674
7775 // Otherwise it is a plain object, so copy to a JSON map, so we process
7876 // and revive all entries recursively.
79- _JsonMap map = new _JsonMap (e);
77+ _JsonMap map = _JsonMap (e);
8078 var processed = map._processed;
8179 List <String > keys = map._computeKeys ();
8280 for (int i = 0 ; i < keys.length; i++ ) {
@@ -98,19 +96,20 @@ _convertJsonToDartLazy(object) {
9896 if (object == null ) return null ;
9997
10098 // JavaScript string, number, bool already has the correct representation.
101- if (JS ('bool' , 'typeof # != "object"' , object)) {
99+ if (JS < bool > ('bool' , 'typeof # != "object"' , object)) {
102100 return object;
103101 }
104102
105103 // This test is needed to avoid identifying '{"__proto__":[]}' as an array.
106104 // TODO(sra): Replace this test with cheaper '#.constructor === Array' when
107105 // bug https://code.google.com/p/v8/issues/detail?id=621 is fixed.
108- if (JS ('bool' , 'Object.getPrototypeOf(#) !== Array.prototype' , object)) {
109- return new _JsonMap (object);
106+ if (JS <bool >(
107+ 'bool' , 'Object.getPrototypeOf(#) !== Array.prototype' , object)) {
108+ return _JsonMap (object);
110109 }
111110
112111 // Update the elements in place since JS arrays are Dart lists.
113- for (int i = 0 ; i < JS ('int' , '#.length' , object); i++ ) {
112+ for (int i = 0 ; i < JS < int > ('int' , '#.length' , object); i++ ) {
114113 // Use JS indexing to avoid range checks. We know this is the only
115114 // reference to the list, but the compiler will likely never be able to
116115 // tell that this instance of the list cannot have its length changed by
@@ -157,12 +156,12 @@ class _JsonMap extends MapBase<String, dynamic> {
157156
158157 Iterable <String > get keys {
159158 if (_isUpgraded) return _upgradedMap.keys;
160- return new _JsonMapKeyIterable (this );
159+ return _JsonMapKeyIterable (this );
161160 }
162161
163162 Iterable get values {
164163 if (_isUpgraded) return _upgradedMap.values;
165- return new MappedIterable (_computeKeys (), (each) => this [each]);
164+ return MappedIterable (_computeKeys (), (each) => this [each]);
166165 }
167166
168167 operator []= (key, value) {
@@ -209,7 +208,7 @@ class _JsonMap extends MapBase<String, dynamic> {
209208 return value;
210209 }
211210
212- remove (Object key) {
211+ remove (Object ? key) {
213212 if (! _isUpgraded && ! containsKey (key)) return null ;
214213 return _upgrade ().remove (key);
215214 }
@@ -249,7 +248,7 @@ class _JsonMap extends MapBase<String, dynamic> {
249248 // Check if invoking the callback function changed
250249 // the key set. If so, throw an exception.
251250 if (! identical (keys, _data)) {
252- throw new ConcurrentModificationError (this );
251+ throw ConcurrentModificationError (this );
253252 }
254253 }
255254 }
@@ -270,7 +269,7 @@ class _JsonMap extends MapBase<String, dynamic> {
270269
271270 List <String > _computeKeys () {
272271 assert (! _isUpgraded);
273- List keys = _data;
272+ List ? keys = _data;
274273 if (keys == null ) {
275274 keys = _data = new JSArray <String >.typed (_getPropertyNames (_original));
276275 }
@@ -293,7 +292,7 @@ class _JsonMap extends MapBase<String, dynamic> {
293292 // safely force a concurrent modification error in case
294293 // someone is iterating over the map here.
295294 if (keys.isEmpty) {
296- keys.add (null );
295+ keys.add ("" );
297296 } else {
298297 keys.clear ();
299298 }
@@ -316,15 +315,15 @@ class _JsonMap extends MapBase<String, dynamic> {
316315 // Private JavaScript helper methods.
317316 // ------------------------------------------
318317
319- static bool _hasProperty (object, String key) =>
320- JS ( 'bool' , 'Object.prototype.hasOwnProperty.call(#,#)' , object, key);
318+ static bool _hasProperty (object, String key) => JS < bool >(
319+ 'bool' , 'Object.prototype.hasOwnProperty.call(#,#)' , object, key);
321320 static _getProperty (object, String key) => JS ('' , '#[#]' , object, key);
322321 static _setProperty (object, String key, value) =>
323322 JS ('' , '#[#]=#' , object, key, value);
324323 static List _getPropertyNames (object) =>
325324 JS ('JSExtendableArray' , 'Object.keys(#)' , object);
326325 static bool _isUnprocessed (object) =>
327- JS ('bool' , 'typeof(#)=="undefined"' , object);
326+ JS < bool > ('bool' , 'typeof(#)=="undefined"' , object);
328327 static _newJavaScriptObject () => JS ('=Object' , 'Object.create(null)' );
329328}
330329
@@ -352,14 +351,14 @@ class _JsonMapKeyIterable extends ListIterable<String> {
352351
353352 /// Delegate to [parent.containsKey] to ensure the performance expected
354353 /// from [Map.keys.containsKey] .
355- bool contains (Object key) => _parent.containsKey (key);
354+ bool contains (Object ? key) => _parent.containsKey (key);
356355}
357356
358357@patch
359358class JsonDecoder {
360359 @patch
361- StringConversionSink startChunkedConversion (Sink <Object > sink) {
362- return new _JsonDecoderSink (_reviver, sink);
360+ StringConversionSink startChunkedConversion (Sink <Object ? > sink) {
361+ return _JsonDecoderSink (_reviver, sink);
363362 }
364363}
365364
@@ -368,17 +367,16 @@ class JsonDecoder {
368367///
369368/// The sink only creates one object, but its input can be chunked.
370369// TODO(floitsch): don't accumulate everything before starting to decode.
371- class _JsonDecoderSink extends _StringSinkConversionSink {
372- final Function (Object key, Object value) _reviver;
373- final Sink <Object > _sink;
370+ class _JsonDecoderSink extends _StringSinkConversionSink < StringBuffer > {
371+ final Object ? Function (Object ? key, Object ? value)? _reviver;
372+ final Sink <Object ? > _sink;
374373
375- _JsonDecoderSink (this ._reviver, this ._sink) : super (new StringBuffer ('' ));
374+ _JsonDecoderSink (this ._reviver, this ._sink) : super (StringBuffer ('' ));
376375
377376 void close () {
378377 super .close ();
379- StringBuffer buffer = _stringSink;
380- String accumulated = buffer.toString ();
381- buffer.clear ();
378+ String accumulated = _stringSink.toString ();
379+ _stringSink.clear ();
382380 Object decoded = _parseJson (accumulated, _reviver);
383381 _sink.add (decoded);
384382 _sink.close ();
@@ -393,20 +391,21 @@ class Utf8Decoder {
393391 }
394392
395393 @patch
396- static String _convertIntercepted (
397- bool allowMalformed, List <int > codeUnits, int start, int end) {
394+ static String ? _convertIntercepted (
395+ bool allowMalformed, List <int > codeUnits, int start, int ? end) {
398396 // Test `codeUnits is NativeUint8List`. Dart's NativeUint8List is
399397 // implemented by JavaScript's Uint8Array.
400- if (JS ('bool' , '# instanceof Uint8Array' , codeUnits)) {
398+ if (JS < bool > ('bool' , '# instanceof Uint8Array' , codeUnits)) {
401399 // JS 'cast' to avoid a downcast equivalent to the is-check we hand-coded.
402- NativeUint8List casted = JS ('NativeUint8List' , '#' , codeUnits);
400+ NativeUint8List casted =
401+ JS <NativeUint8List >('NativeUint8List' , '#' , codeUnits);
403402 return _convertInterceptedUint8List (allowMalformed, casted, start, end);
404403 }
405404 return null ; // This call was not intercepted.
406405 }
407406
408- static String _convertInterceptedUint8List (
409- bool allowMalformed, NativeUint8List codeUnits, int start, int end) {
407+ static String ? _convertInterceptedUint8List (
408+ bool allowMalformed, NativeUint8List codeUnits, int start, int ? end) {
410409 if (allowMalformed) {
411410 // TextDecoder with option {fatal: false} does not produce the same result
412411 // as [Utf8Decoder]. It disagrees on the number of `U+FFFD` (REPLACEMENT
@@ -433,21 +432,23 @@ class Utf8Decoder {
433432 return _useTextDecoderChecked (decoder, codeUnits);
434433 }
435434
436- return _useTextDecoderChecked (decoder,
437- JS ('NativeUint8List' , '#.subarray(#, #)' , codeUnits, start, end));
435+ return _useTextDecoderChecked (
436+ decoder,
437+ JS <NativeUint8List >(
438+ 'NativeUint8List' , '#.subarray(#, #)' , codeUnits, start, end));
438439 }
439440
440- static String _useTextDecoderChecked (decoder, NativeUint8List codeUnits) {
441+ static String ? _useTextDecoderChecked (decoder, NativeUint8List codeUnits) {
441442 if (_unsafe (codeUnits)) return null ;
442443 return _useTextDecoderUnchecked (decoder, codeUnits);
443444 }
444445
445- static String _useTextDecoderUnchecked (decoder, NativeUint8List codeUnits) {
446+ static String ? _useTextDecoderUnchecked (decoder, NativeUint8List codeUnits) {
446447 // If the input is malformed, catch the exception and return `null` to fall
447448 // back on unintercepted decoder. The fallback will either succeed in
448449 // decoding, or report the problem better than TextDecoder.
449450 try {
450- return JS ('String' , '#.decode(#)' , decoder, codeUnits);
451+ return JS < String > ('String' , '#.decode(#)' , decoder, codeUnits);
451452 } catch (e) {}
452453 return null ;
453454 }
@@ -477,10 +478,9 @@ class Utf8Decoder {
477478 return false ;
478479 }
479480
480- // TextDecoder is not defined on some browsers and on the stand-alone d8 and
481- // jsshell engines. Use a lazy initializer to do feature detection once.
482- static final _decoder = _makeDecoder ();
483- static _makeDecoder () {
481+ /// TextDecoder is not defined on some browsers and on the stand-alone d8 and
482+ /// jsshell engines. Use a lazy initializer to do feature detection once.
483+ static final _decoder = () {
484484 try {
485485 // Use `{fatal: true}`. 'fatal' does not correspond exactly to
486486 // `!allowMalformed`: TextDecoder rejects unpaired surrogates which
@@ -490,7 +490,7 @@ class Utf8Decoder {
490490 return JS ('' , 'new TextDecoder("utf-8", {fatal: true})' );
491491 } catch (e) {}
492492 return null ;
493- }
493+ }();
494494}
495495
496496@patch
0 commit comments