diff --git a/lib/src/model.dart b/lib/src/model.dart index 90ca35802f..fbd024bdc7 100644 --- a/lib/src/model.dart +++ b/lib/src/model.dart @@ -1560,8 +1560,8 @@ abstract class GetterSetterCombo implements ModelElement { if (targetClass.name == target.name) { return original.replaceAll(constructorName, "${target.linkedName}"); } - return original.replaceAll( - "${targetClass.name}.${target.name}", "${targetClass.linkedName}.${target.linkedName}"); + return original.replaceAll("${targetClass.name}.${target.name}", + "${targetClass.linkedName}.${target.linkedName}"); } String _constantValueBase() { @@ -2892,7 +2892,8 @@ abstract class ModelElement extends Canonicalization /// /// For example: libraryName.className.methodName @override - String get fullyQualifiedName => _memoizer.memoized(_buildFullyQualifiedName); + String get fullyQualifiedName => _memoizer.memoized(_buildFullyQualifiedName, + altKey: 'fullyQualifiedName'); String _fullyQualifiedNameWithoutLibrary() { // Remember, periods are legal in library names. @@ -2904,7 +2905,8 @@ abstract class ModelElement extends Canonicalization // library.fullyQualifiedName seems somehow to break things. //String get fullyQualifiedNameWithoutLibrary => _memoizer.memoized2(fullyQualifiedName.replaceFirst, "${library.fullyQualifiedName}.", ''); String get fullyQualifiedNameWithoutLibrary => - _memoizer.memoized(_fullyQualifiedNameWithoutLibrary); + _memoizer.memoized(_fullyQualifiedNameWithoutLibrary, + altKey: 'fullyQualifiedNameWithoutLibrary'); String get sourceFileName => element.source.fullName; diff --git a/lib/src/model_utils.dart b/lib/src/model_utils.dart index 5dbcfbf622..b21e9e4e99 100644 --- a/lib/src/model_utils.dart +++ b/lib/src/model_utils.dart @@ -172,15 +172,17 @@ String crossdartifySource( /// An UnmodifiableListView that computes equality and hashCode based on the /// equality and hashCode of its contained objects. -class _HashableList extends UnmodifiableListView { - _HashableList(Iterable iterable) : super(iterable); +class _HashableList { + final List _source; + int _hashCache; + _HashableList(this._source); @override bool operator ==(other) { if (other is _HashableList) { - if (this.length == other.length) { - for (var index = 0; index < length; ++index) { - if (this[index] != other[index]) return false; + if (_source.length == other._source.length) { + for (var index = 0; index < _source.length; ++index) { + if (_source[index] != other._source[index]) return false; } return true; } @@ -189,7 +191,7 @@ class _HashableList extends UnmodifiableListView { } @override - get hashCode => hashObjects(this); + get hashCode => _hashCache ??= hashObjects(_source); } /// Like [Memoizer], except in checked mode will validate that the value of the @@ -252,11 +254,11 @@ class ValidatingMemoizer extends Memoizer { /// ``` class Memoizer { /// Map of a function and its positional parameters (if any), to a value. - Map<_HashableList, dynamic> _memoizationTable = new Map(); + final Map<_HashableList, dynamic> _memoizationTable = new HashMap(); /// Reset the memoization table, forcing calls of the underlying functions. void invalidateMemos() { - _memoizationTable = new Map(); + _memoizationTable.clear(); } /// A wrapper around putIfAbsent, exposed to allow overrides. @@ -266,8 +268,9 @@ class Memoizer { /// Calls and caches the return value of [f]() if not in the cache, then /// returns the cached value of [f](). - R memoized(Function f) { - _HashableList key = new _HashableList([f]); + R memoized(Function f, {String altKey}) { + Object obj = altKey ?? f; + _HashableList key = new _HashableList([obj]); return _cacheIfAbsent(key, f); }