@@ -390,47 +390,48 @@ class _Type extends Type {
390
390
391
391
/// Given an internal runtime type object, wraps it in a `_Type` object
392
392
/// that implements the dart:core Type interface.
393
- Type wrapType (type) {
393
+ Type wrapType (type) => _wrapType (type, false );
394
+
395
+ /// Helper function to wrap a type.
396
+ ///
397
+ /// When isNormalized is true, the parameter is known to be in a canonicalized
398
+ /// normal form, so the algorithm can directly wrap and return the value.
399
+ Type _wrapType (type, isNormalized) {
394
400
// If we've already wrapped this type once, use the previous wrapper. This
395
401
// way, multiple references to the same type return an identical Type.
396
402
if (JS ('!' , '#.hasOwnProperty(#)' , type, _typeObject)) {
397
403
return JS ('' , '#[#]' , type, _typeObject);
398
404
}
399
- var result = JS <Type ?>('' , '#.get(#)' , _normalizedTypeObjectMap, type) ??
400
- canonicalizeNormalizedTypeObject (type);
405
+ var result = isNormalized
406
+ ? _Type (type)
407
+ : (type is LegacyType
408
+ ? _wrapType (type.type, false )
409
+ : _canonicalizeNormalizedTypeObject (type));
401
410
JS ('' , '#[#] = #' , type, _typeObject, result);
402
411
return result;
403
412
}
404
413
405
- /// Constructs and caches a normalized version of a type.
414
+ /// Constructs a normalized version of a type.
406
415
///
407
416
/// Used for type object identity. Currently only removes legacy wrappers,
408
417
/// ignoring other normalization operations.
409
- Type canonicalizeNormalizedTypeObject (dartType) {
410
- // Check if a normalized type corresponding to this type has already been
411
- // generated. Search for and potentially cache both the type and its
412
- // legacy-wrapped version.
413
- var result = JS <Type ?>('' , '#.get(#)' , _normalizedTypeObjectMap, dartType);
414
- if (result != null ) {
415
- return result;
416
- }
417
- var type = dartType is LegacyType ? dartType.type : dartType;
418
- var legacyType = legacy (type);
418
+ Type _canonicalizeNormalizedTypeObject (type) {
419
+ assert (type is ! LegacyType );
419
420
var args = getGenericArgs (type);
421
+ var normType;
420
422
if (args == null || args.isEmpty) {
421
- var norm = _Type (type);
422
- JS ('' , '#.set(#, #)' , _normalizedTypeObjectMap, type, norm);
423
- JS ('' , '#.set(#, #)' , _normalizedTypeObjectMap, legacyType, norm);
424
- return norm;
425
- }
426
- var genericClass = getGenericClass (type);
427
- var normArgs = args
428
- .map ((generic) => unwrapType (canonicalizeNormalizedTypeObject (generic)))
429
- .toList ();
430
- var norm = _Type (constFn (JS ('!' , '#(...#)' , genericClass, normArgs))());
431
- JS ('' , '#.set(#, #)' , _normalizedTypeObjectMap, type, norm);
432
- JS ('' , '#.set(#, #)' , _normalizedTypeObjectMap, legacyType, norm);
433
- return norm;
423
+ normType = type;
424
+ } else {
425
+ var genericClass = getGenericClass (type);
426
+ // We don't call _canonicalizeNormalizedTypeObject recursively but call wrap
427
+ // + unwrap to handle legacy types automatically and force caching the
428
+ // canonicalized type under the _typeObject cache property directly. This
429
+ // way we ensure we always use the canonical normalized instance for each
430
+ // type parameter.
431
+ var normArgs = args.map ((a) => unwrapType (wrapType (a))).toList ();
432
+ normType = JS ('!' , '#(...#)' , genericClass, normArgs);
433
+ }
434
+ return _wrapType (normType, true );
434
435
}
435
436
436
437
/// The symbol used to store the cached `Type` object associated with a class.
@@ -471,10 +472,6 @@ final _fnTypeTypeMap = JS('', 'new Map()');
471
472
/// index path (if present) is the canonical function type.
472
473
final List _fnTypeSmallMap = JS ('' , '[new Map(), new Map(), new Map()]' );
473
474
474
- /// Memo table that maps DartType objects to their type objects (`_Type` ).
475
- /// Used for computing identity for runtime type objects.
476
- final _normalizedTypeObjectMap = JS ('' , 'new Map()' );
477
-
478
475
@NoReifyGeneric ()
479
476
T _memoizeArray <T >(map, arr, T create ()) => JS ('' , '''(() => {
480
477
let len = $arr .length;
0 commit comments