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 {