Clean up the old memoizer (#1854)

* Remove memoizer from dartdoc (never wound up being viable) and clean up grind so it depends on less

* Restore relevant parts of model_utils_test
diff --git a/lib/src/dartdoc_options.dart b/lib/src/dartdoc_options.dart
index 328f9da..4f0d747 100644
--- a/lib/src/dartdoc_options.dart
+++ b/lib/src/dartdoc_options.dart
@@ -20,6 +20,7 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:args/args.dart';
 import 'package:dartdoc/dartdoc.dart';
+import 'package:dartdoc/src/io_utils.dart';
 import 'package:dartdoc/src/tuple.dart';
 import 'package:path/path.dart' as pathLib;
 import 'package:yaml/yaml.dart';
@@ -39,21 +40,6 @@
 final String directoryCurrentPath =
     pathLib.canonicalize(Directory.current.path);
 
-String resolveTildePath(String originalPath) {
-  if (originalPath == null || !originalPath.startsWith('~/')) {
-    return originalPath;
-  }
-
-  String homeDir;
-
-  if (Platform.isWindows) {
-    homeDir = pathLib.absolute(Platform.environment['USERPROFILE']);
-  } else {
-    homeDir = pathLib.absolute(Platform.environment['HOME']);
-  }
-
-  return pathLib.join(homeDir, originalPath.substring(2));
-}
 
 class DartdocOptionError extends DartdocFailure {
   DartdocOptionError(String details) : super(details);
diff --git a/lib/src/io_utils.dart b/lib/src/io_utils.dart
index 913a0cd..6318dcf 100644
--- a/lib/src/io_utils.dart
+++ b/lib/src/io_utils.dart
@@ -12,6 +12,24 @@
 
 import 'package:path/path.dart' as pathLib;
 
+/// Return a resolved path including the home directory in place of tilde
+/// references.
+String resolveTildePath(String originalPath) {
+  if (originalPath == null || !originalPath.startsWith('~/')) {
+    return originalPath;
+  }
+
+  String homeDir;
+
+  if (Platform.isWindows) {
+    homeDir = pathLib.absolute(Platform.environment['USERPROFILE']);
+  } else {
+    homeDir = pathLib.absolute(Platform.environment['HOME']);
+  }
+
+  return pathLib.join(homeDir, originalPath.substring(2));
+}
+
 /// Lists the contents of [dir].
 ///
 /// If [recursive] is `true`, lists subdirectory contents (defaults to `false`).
diff --git a/lib/src/model_utils.dart b/lib/src/model_utils.dart
index a9432c5..0331511 100644
--- a/lib/src/model_utils.dart
+++ b/lib/src/model_utils.dart
@@ -4,7 +4,6 @@
 
 library dartdoc.model_utils;
 
-import 'dart:collection';
 import 'dart:convert';
 import 'dart:io';
 
@@ -12,10 +11,8 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source_io.dart';
-import 'package:collection/collection.dart';
 import 'package:dartdoc/src/model.dart';
 import 'package:path/path.dart' as pathLib;
-import 'package:quiver/core.dart';
 
 final Map<String, String> _fileContents = <String, String>{};
 
@@ -178,195 +175,4 @@
     newSource = sanitizer.convert(source);
   }
   return newSource;
-}
-
-/// An UnmodifiableListView that computes equality and hashCode based on the
-/// equality and hashCode of its contained objects.
-class _HashableList {
-  final List _source;
-  int _hashCache;
-  _HashableList(this._source);
-
-  @override
-  bool operator ==(other) {
-    if (other is _HashableList) {
-      if (_source.length == other._source.length) {
-        for (var index = 0; index < _source.length; ++index) {
-          if (_source[index] != other._source[index]) return false;
-        }
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  int get hashCode => _hashCache ??= hashObjects(_source);
-}
-
-/// Like [Memoizer], except in checked mode will validate that the value of the
-/// memoized function is unchanging using [DeepCollectionEquality].  Still
-/// returns the cached value assuming the assertion passes.
-class ValidatingMemoizer extends Memoizer {
-  bool _assert_on_difference = false;
-
-  ValidatingMemoizer() : super() {
-    // Assignment within assert to take advantage of the expression only
-    // being executed in checked mode.
-    assert(_assert_on_difference = true);
-    invalidateMemos();
-  }
-
-  /// In checked mode and when constructed with assert_on_difference == true,
-  /// validate that the return value from f() equals the memoized value.
-  /// Otherwise, a wrapper around putIfAbsent.
-  @override
-  R _cacheIfAbsent<R>(_HashableList key, R Function() f) {
-    if (_assert_on_difference) {
-      if (_memoizationTable.containsKey(key)) {
-        R value = f();
-        if (!new DeepCollectionEquality()
-            .equals(value, _memoizationTable[key])) {
-          throw new AssertionError('${value} != $_memoizationTable[key]');
-        }
-      }
-    }
-    return super._cacheIfAbsent(key, f);
-  }
-}
-
-/// A basic Memoizer class.  Instantiate as a member variable, extend, or use
-/// as a mixin to track object-specific cached values, or instantiate directly
-/// to track other values.
-///
-/// For all methods in this class, the parameter [f] must be a tear-off method
-/// or top level function (not an inline closure) for memoization to work.
-/// [Memoizer] depends on the equality operator on the given function to detect
-/// when we are calling the same function.
-///
-/// Use:
-///
-/// ```dart
-/// String aTestFunction(String greeting, String name) => "${greeting}, ${name}";
-/// int aSlowFunction() { doSome(); return expensiveCalculations(); }
-///
-/// myMemoizer.memoized2(aTestFunction, "Hello, "world");
-/// myMemoizer.memoized(aSlowFunction);
-/// ```
-///
-/// *Not*:
-///
-/// ```dart
-/// String aTestFunction(String greeting, String name) => "${greeting}, ${name}";
-///
-/// myMemoizer.memoized2((a, b) => aTestFunction(a, b), "Hello", "world");
-/// myMemoizer.memoized(() => aSlowFunction());;
-/// ```
-class Memoizer {
-  /// Map of a function and its positional parameters (if any), to a value.
-  final Map<_HashableList, dynamic> _memoizationTable = new HashMap();
-
-  /// Reset the memoization table, forcing calls of the underlying functions.
-  void invalidateMemos() {
-    _memoizationTable.clear();
-  }
-
-  /// A wrapper around putIfAbsent, exposed to allow overrides.
-  R _cacheIfAbsent<R>(_HashableList key, R Function() f) {
-    return _memoizationTable.putIfAbsent(key, f);
-  }
-
-  /// Calls and caches the return value of [f]() if not in the cache, then
-  /// returns the cached value of [f]().
-  R memoized<R>(Function f, {String altKey}) {
-    Object obj = altKey ?? f;
-    _HashableList key = new _HashableList([obj]);
-    return _cacheIfAbsent(key, f);
-  }
-
-  /// Calls and caches the return value of [f]([param1]) if not in the cache, then
-  /// returns the cached value of [f]([param1]).
-  R memoized1<R, A>(R Function(A) f, A param1) {
-    _HashableList key = new _HashableList([f, param1]);
-    return _cacheIfAbsent(key, () => f(param1));
-  }
-
-  /// Calls and caches the return value of [f]([param1], [param2]) if not in the
-  /// cache, then returns the cached value of [f]([param1], [param2]).
-  R memoized2<R, A, B>(R Function(A, B) f, A param1, B param2) {
-    _HashableList key = new _HashableList([f, param1, param2]);
-    return _cacheIfAbsent(key, () => f(param1, param2));
-  }
-
-  /// Calls and caches the return value of [f]([param1], [param2], [param3]) if
-  /// not in the cache, then returns the cached value of [f]([param1],
-  /// [param2], [param3]).
-  R memoized3<R, A, B, C>(R Function(A, B, C) f, A param1, B param2, C param3) {
-    _HashableList key = new _HashableList([f, param1, param2, param3]);
-    return _cacheIfAbsent(key, () => f(param1, param2, param3));
-  }
-
-  /// Calls and caches the return value of [f]([param1], [param2], [param3],
-  /// [param4]) if not in the cache, then returns the cached value of
-  /// [f]([param1], [param2], [param3], [param4]).
-  R memoized4<R, A, B, C, D>(
-      R Function(A, B, C, D) f, A param1, B param2, C param3, D param4) {
-    _HashableList key = new _HashableList([f, param1, param2, param3, param4]);
-    return _cacheIfAbsent(key, () => f(param1, param2, param3, param4));
-  }
-
-  /// Calls and caches the return value of [f]([param1], [param2], [param3],
-  /// [param4], [param5]) if not in the cache, then returns the cached value of [f](
-  /// [param1], [param2], [param3], [param4], [param5]).
-  R memoized5<R, A, B, C, D, E>(R Function(A, B, C, D, E) f, A param1, B param2,
-      C param3, D param4, E param5) {
-    _HashableList key =
-        new _HashableList([f, param1, param2, param3, param4, param5]);
-    return _cacheIfAbsent(key, () => f(param1, param2, param3, param4, param5));
-  }
-
-  /// Calls and caches the return value of [f]([param1], [param2], [param3],
-  /// [param4], [param5], [param6]) if not in the cache, then returns the cached
-  /// value of [f]([param1], [param2], [param3], [param4], [param5], [param6]).
-  R memoized6<R, A, B, C, D, E, F>(R Function(A, B, C, D, E, F) f, A param1,
-      B param2, C param3, D param4, E param5, F param6) {
-    _HashableList key =
-        new _HashableList([f, param1, param2, param3, param4, param5, param6]);
-    return _cacheIfAbsent(
-        key, () => f(param1, param2, param3, param4, param5, param6));
-  }
-
-  /// Calls and caches the return value of [f]([param1], [param2], [param3],
-  /// [param4], [param5], [param6], [param7]) if not in the cache, then returns
-  /// the cached value of [f]([param1], [param2], [param3], [param4], [param5],
-  /// [param6], [param7]).
-  R memoized7<R, A, B, C, D, E, F, G>(R Function(A, B, C, D, E, F, G) f,
-      A param1, B param2, C param3, D param4, E param5, F param6, G param7) {
-    _HashableList key = new _HashableList(
-        [f, param1, param2, param3, param4, param5, param6, param7]);
-    return _cacheIfAbsent(
-        key, () => f(param1, param2, param3, param4, param5, param6, param7));
-  }
-
-  /// Calls and caches the return value of [f]([param1], [param2], [param3],
-  /// [param4], [param5], [param6], [param7], [param8]) if not in the cache,
-  /// then returns the cached value of [f]([param1], [param2], [param3],
-  /// [param4], [param5], [param6], [param7], [param8]).
-  R memoized8<R, A, B, C, D, E, F, G, H>(
-      R Function(A, B, C, D, E, F, G, H) f,
-      A param1,
-      B param2,
-      C param3,
-      D param4,
-      E param5,
-      F param6,
-      G param7,
-      H param8) {
-    _HashableList key = new _HashableList(
-        [f, param1, param2, param3, param4, param5, param6, param7, param8]);
-    return _cacheIfAbsent(
-        key,
-        () =>
-            f(param1, param2, param3, param4, param5, param6, param7, param8));
-  }
-}
+}
\ No newline at end of file
diff --git a/test/model_utils_test.dart b/test/model_utils_test.dart
index 038b51f..7bc35cd 100644
--- a/test/model_utils_test.dart
+++ b/test/model_utils_test.dart
@@ -7,94 +7,6 @@
 import 'package:dartdoc/src/model_utils.dart';
 import 'package:test/test.dart';
 
-class ValidatingMemoizerUser extends ValidatingMemoizer {
-  int foo = 0;
-  // These are actually not things you would ordinarily memoize, because
-  // they change.  But they are useful for testing.
-  List<int> _toMemoize() {
-    return [foo++];
-  }
-
-  List<int> get toMemoize => memoized(_toMemoize);
-}
-
-class MemoizerUser extends Memoizer {
-  int foo = 0;
-  // These are actually not things you would ordinarily memoize, because
-  // they change.  But they are useful for testing.
-  int _toMemoize() {
-    return foo++;
-  }
-
-  int get toMemoize => memoized(_toMemoize);
-
-  String _memoizedParameter1(String param) => "${foo++} ${param}";
-  String memoizedParameter1(String param) =>
-      memoized1(_memoizedParameter1, param);
-
-  String _memoizedParameter2(String param, String param2) =>
-      "${foo++} ${param} ${param2}";
-  String memoizedParameter2(String param, String param2) =>
-      memoized2(_memoizedParameter2, param, param2);
-
-  String _memoizedParameter3(String param, String param2, String param3) =>
-      "${foo++} ${param} ${param2} ${param3}";
-  String memoizedParameter3(String param, String param2, String param3) =>
-      memoized3(_memoizedParameter3, param, param2, param3);
-
-  String _memoizedParameter4(
-          String param, String param2, String param3, String param4) =>
-      "${foo++} ${param} ${param2} ${param3} ${param4}";
-  String memoizedParameter4(
-          String param, String param2, String param3, String param4) =>
-      memoized4(_memoizedParameter4, param, param2, param3, param4);
-
-  String _memoizedParameter5(String param, String param2, String param3,
-          String param4, String param5) =>
-      "${foo++} ${param} ${param2} ${param3} ${param4} ${param5}";
-  String memoizedParameter5(String param, String param2, String param3,
-          String param4, String param5) =>
-      memoized5(_memoizedParameter5, param, param2, param3, param4, param5);
-
-  String _memoizedParameter6(String param, String param2, String param3,
-          String param4, String param5, String param6) =>
-      "${foo++} ${param} ${param2} ${param3} ${param4} ${param5} ${param6}";
-  String memoizedParameter6(String param, String param2, String param3,
-          String param4, String param5, String param6) =>
-      memoized6(
-          _memoizedParameter6, param, param2, param3, param4, param5, param6);
-
-  String _memoizedParameter7(String param, String param2, String param3,
-          String param4, String param5, String param6, String param7) =>
-      "${foo++} ${param} ${param2} ${param3} ${param4} ${param5} ${param6} ${param7}";
-  String memoizedParameter7(String param, String param2, String param3,
-          String param4, String param5, String param6, String param7) =>
-      memoized7(_memoizedParameter7, param, param2, param3, param4, param5,
-          param6, param7);
-
-  String _memoizedParameter8(
-          String param,
-          String param2,
-          String param3,
-          String param4,
-          String param5,
-          String param6,
-          String param7,
-          String param8) =>
-      "${foo++} ${param} ${param2} ${param3} ${param4} ${param5} ${param6} ${param7} ${param8}";
-  String memoizedParameter8(
-          String param,
-          String param2,
-          String param3,
-          String param4,
-          String param5,
-          String param6,
-          String param7,
-          String param8) =>
-      memoized8(_memoizedParameter8, param, param2, param3, param4, param5,
-          param6, param7, param8);
-}
-
 void main() {
   group('model_utils stripIndentFromSource', () {
     test('no indent', () {
@@ -140,75 +52,4 @@
           'void foo() {\n  print(1);\n}\n');
     });
   });
-
-  group('model_utils ValidatingMemoizer', () {
-    test('assert on changing underlying function', () {
-      var m = new ValidatingMemoizerUser();
-      expect(m.toMemoize.first, equals(0));
-      expect(() => m.toMemoize, throwsA(new TypeMatcher<AssertionError>()));
-    });
-  });
-
-  group('model_utils Memoizer', () {
-    test('basic memoization and invalidation', () {
-      var m = new MemoizerUser();
-      expect(m.toMemoize, equals(0), reason: "initialization problem");
-      expect(m.toMemoize, equals(0), reason: "failed to memoize");
-      m.invalidateMemos();
-      expect(m.toMemoize, equals(1), reason: "failed to invalidate");
-    });
-
-    test('memoization of a method with parameter', () {
-      var m = new MemoizerUser();
-      expect(m.memoizedParameter1("hello"), equals("0 hello"),
-          reason: "initialization problem");
-      expect(m.memoizedParameter1("hello"), equals("0 hello"),
-          reason: "failed to memoize");
-      expect(m.memoizedParameter1("goodbye"), equals("1 goodbye"));
-      expect(m.memoizedParameter1("something"), equals("2 something"));
-      m.invalidateMemos();
-      expect(m.memoizedParameter1("hello"), equals("3 hello"),
-          reason: "failed to invalidate");
-    });
-
-    test('memoization of many parameters', () {
-      var m = new MemoizerUser();
-      expect(m.memoizedParameter1("hello"), equals("0 hello"));
-      expect(m.memoizedParameter2("hello", "obi"), equals("1 hello obi"));
-      expect(m.memoizedParameter3("hello", "obi", "wan"),
-          equals("2 hello obi wan"));
-      expect(m.memoizedParameter4("hello", "obi", "wan", "how"),
-          equals("3 hello obi wan how"));
-      expect(m.memoizedParameter5("hello", "obi", "wan", "how", "are"),
-          equals("4 hello obi wan how are"));
-      expect(m.memoizedParameter6("hello", "obi", "wan", "how", "are", "you"),
-          equals("5 hello obi wan how are you"));
-      expect(
-          m.memoizedParameter7(
-              "hello", "obi", "wan", "how", "are", "you", "doing"),
-          equals("6 hello obi wan how are you doing"));
-      expect(
-          m.memoizedParameter8(
-              "hello", "obi", "wan", "how", "are", "you", "doing", "today"),
-          equals("7 hello obi wan how are you doing today"));
-      expect(m.memoizedParameter1("hello"), equals("0 hello"));
-      expect(m.memoizedParameter2("hello", "obi"), equals("1 hello obi"));
-      expect(m.memoizedParameter3("hello", "obi", "wan"),
-          equals("2 hello obi wan"));
-      expect(m.memoizedParameter4("hello", "obi", "wan", "how"),
-          equals("3 hello obi wan how"));
-      expect(m.memoizedParameter5("hello", "obi", "wan", "how", "are"),
-          equals("4 hello obi wan how are"));
-      expect(m.memoizedParameter6("hello", "obi", "wan", "how", "are", "you"),
-          equals("5 hello obi wan how are you"));
-      expect(
-          m.memoizedParameter7(
-              "hello", "obi", "wan", "how", "are", "you", "doing"),
-          equals("6 hello obi wan how are you doing"));
-      expect(
-          m.memoizedParameter8(
-              "hello", "obi", "wan", "how", "are", "you", "doing", "today"),
-          equals("7 hello obi wan how are you doing today"));
-    });
-  });
 }
diff --git a/tool/grind.dart b/tool/grind.dart
index 455eaae..a5ac8f7 100644
--- a/tool/grind.dart
+++ b/tool/grind.dart
@@ -5,9 +5,7 @@
 import 'dart:async';
 import 'dart:io' hide ProcessException;
 
-import 'package:dartdoc/src/dartdoc_options.dart';
 import 'package:dartdoc/src/io_utils.dart';
-import 'package:dartdoc/src/model_utils.dart';
 import 'package:grinder/grinder.dart';
 import 'package:io/io.dart';
 import 'package:path/path.dart' as pathLib;
@@ -47,8 +45,6 @@
 Directory createTempSync(String prefix) =>
     Directory.systemTemp.createTempSync(prefix);
 
-final Memoizer tempdirsCache = new Memoizer();
-
 /// Global so that the lock is retained for the life of the process.
 Future<void> _lockFuture;
 Completer<FlutterRepo> _cleanFlutterRepo;
@@ -98,23 +94,32 @@
   return _cleanFlutterRepo.future;
 }
 
-Directory get dartdocDocsDir =>
-    tempdirsCache.memoized1(createTempSync, 'dartdoc');
-Directory get dartdocDocsDirRemote =>
-    tempdirsCache.memoized1(createTempSync, 'dartdoc_remote');
-Directory get sdkDocsDir => tempdirsCache.memoized1(createTempSync, 'sdkdocs');
+Directory _dartdocDocsDir;
+Directory get dartdocDocsDir => _dartdocDocsDir ??= createTempSync('dartdoc');
+
+Directory _dartdocDocsDirRemote;
+Directory get dartdocDocsDirRemote => _dartdocDocsDirRemote ??= createTempSync('dartdoc_remote');
+
+Directory _sdkDocsDir;
+Directory get sdkDocsDir => _sdkDocsDir ??= createTempSync('sdkdocs');
+
 Directory cleanFlutterDir = new Directory(
     pathLib.join(resolveTildePath('~/.dartdoc_grinder'), 'cleanFlutter'));
-Directory get flutterDir => tempdirsCache.memoized1(createTempSync, 'flutter');
+
+Directory _flutterDir;
+Directory get flutterDir => _flutterDir ??= createTempSync('flutter');
+
 Directory get testPackage =>
     new Directory(pathLib.joinAll(['testing', 'test_package']));
 Directory get pluginPackage =>
     new Directory(pathLib.joinAll(['testing', 'test_package_flutter_plugin']));
 
+Directory _testPackageDocsDir;
 Directory get testPackageDocsDir =>
-    tempdirsCache.memoized1(createTempSync, 'test_package');
-Directory get pluginPackageDocsDir =>
-    tempdirsCache.memoized1(createTempSync, 'test_package_flutter_plugin');
+    _testPackageDocsDir ??= createTempSync('test_package');
+
+Directory _pluginPackageDocsDir;
+Directory get pluginPackageDocsDir => _pluginPackageDocsDir ??= createTempSync('test_package_flutter_plugin');
 
 /// Version of dartdoc we should use when making comparisons.
 String get dartdocOriginalBranch {