Eliminate dartdoc-global cache of ModelElements/Analyzer bits (#1800)

* Move global markdown object cache into PackageGraph

* dartfmt
diff --git a/lib/src/markdown_processor.dart b/lib/src/markdown_processor.dart
index 0d20fc6..5e635a7 100644
--- a/lib/src/markdown_processor.dart
+++ b/lib/src/markdown_processor.dart
@@ -12,7 +12,6 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:dartdoc/src/element_type.dart';
 import 'package:dartdoc/src/model.dart';
-import 'package:dartdoc/src/model_utils.dart';
 import 'package:dartdoc/src/tuple.dart';
 import 'package:dartdoc/src/warnings.dart';
 import 'package:html/parser.dart' show parse;
@@ -311,9 +310,6 @@
 
 // Basic map of reference to ModelElement, for cases where we're searching
 // outside of scope.
-// TODO(jcollins-g): function caches with maps are very common in dartdoc.
-//                   Extract into library.
-Map<String, Set<ModelElement>> _findRefElementCache;
 // TODO(jcollins-g): Rewrite this to handle constructors in a less hacky way
 // TODO(jcollins-g): This function breaks down naturally into many helpers, extract them
 // TODO(jcollins-g): Subcomponents of this function shouldn't be adding nulls to results, strip the
@@ -410,32 +406,13 @@
   results.remove(null);
 
   // We now need the ref element cache to keep from repeatedly searching [Package.allModelElements].
-  // TODO(jcollins-g): Find somewhere to cache elements outside package.libraries
-  //                   so we can give the right warning (no canonical found)
-  //                   when referring to objects in libraries outside the
-  //                   documented set.
-  if (results.isEmpty && _findRefElementCache == null) {
-    assert(packageGraph.allLibrariesAdded);
-    _findRefElementCache = new Map();
-    for (final modelElement
-        in filterNonDocumented(packageGraph.allLocalModelElements)) {
-      _findRefElementCache.putIfAbsent(
-          modelElement.fullyQualifiedNameWithoutLibrary, () => new Set());
-      _findRefElementCache.putIfAbsent(
-          modelElement.fullyQualifiedName, () => new Set());
-      _findRefElementCache[modelElement.fullyQualifiedName].add(modelElement);
-      _findRefElementCache[modelElement.fullyQualifiedNameWithoutLibrary]
-          .add(modelElement);
-    }
-  }
-
   // But if not, look for a fully qualified match.  (That only makes sense
   // if the codeRef might be qualified, and contains periods.)
   if (results.isEmpty &&
       codeRefChomped.contains('.') &&
-      _findRefElementCache.containsKey(codeRefChomped)) {
+      packageGraph.findRefElementCache.containsKey(codeRefChomped)) {
     for (final ModelElement modelElement
-        in _findRefElementCache[codeRefChomped]) {
+        in packageGraph.findRefElementCache[codeRefChomped]) {
       if (!_ConsiderIfConstructor(codeRef, modelElement)) continue;
       // For fully qualified matches, the original preferredClass passed
       // might make no sense.  Instead, use the enclosing class from the
@@ -464,8 +441,10 @@
   results.remove(null);
 
   // And if we still haven't found anything, just search the whole ball-of-wax.
-  if (results.isEmpty && _findRefElementCache.containsKey(codeRefChomped)) {
-    for (final modelElement in _findRefElementCache[codeRefChomped]) {
+  if (results.isEmpty &&
+      packageGraph.findRefElementCache.containsKey(codeRefChomped)) {
+    for (final modelElement
+        in packageGraph.findRefElementCache[codeRefChomped]) {
       if (codeRefChomped == modelElement.fullyQualifiedNameWithoutLibrary ||
           (modelElement is Library &&
               codeRefChomped == modelElement.fullyQualifiedName)) {
@@ -486,8 +465,9 @@
           .sublist(0, codeRefChompedParts.length - 1)
           .join('.');
       String maybeEnumMember = codeRefChompedParts.last;
-      if (_findRefElementCache.containsKey(maybeEnumName)) {
-        for (final modelElement in _findRefElementCache[maybeEnumName]) {
+      if (packageGraph.findRefElementCache.containsKey(maybeEnumName)) {
+        for (final modelElement
+            in packageGraph.findRefElementCache[maybeEnumName]) {
           if (modelElement is Enum) {
             if (modelElement.constants.any((e) => e.name == maybeEnumMember)) {
               results.add(modelElement);
diff --git a/lib/src/model.dart b/lib/src/model.dart
index 5c6ba0f..bb7b470 100644
--- a/lib/src/model.dart
+++ b/lib/src/model.dart
@@ -1377,8 +1377,7 @@
 }
 
 /// Classes extending this class have canonicalization support in Dartdoc.
-abstract class Canonicalization
-    implements Locatable, Documentable {
+abstract class Canonicalization implements Locatable, Documentable {
   bool get isCanonical;
   Library get canonicalLibrary;
 
@@ -4541,6 +4540,25 @@
     return _implementors;
   }
 
+  Map<String, Set<ModelElement>> _findRefElementCache;
+  Map<String, Set<ModelElement>> get findRefElementCache {
+    if (_findRefElementCache == null) {
+      assert(packageGraph.allLibrariesAdded);
+      _findRefElementCache = new Map();
+      for (final modelElement
+          in filterNonDocumented(packageGraph.allLocalModelElements)) {
+        _findRefElementCache.putIfAbsent(
+            modelElement.fullyQualifiedNameWithoutLibrary, () => new Set());
+        _findRefElementCache.putIfAbsent(
+            modelElement.fullyQualifiedName, () => new Set());
+        _findRefElementCache[modelElement.fullyQualifiedName].add(modelElement);
+        _findRefElementCache[modelElement.fullyQualifiedNameWithoutLibrary]
+            .add(modelElement);
+      }
+    }
+    return _findRefElementCache;
+  }
+
   // All library objects related to this package; a superset of _libraries.
   final Map<LibraryElement, Library> allLibraries = new Map();
 
diff --git a/test/model_test.dart b/test/model_test.dart
index bd33c5b..46bbfec 100644
--- a/test/model_test.dart
+++ b/test/model_test.dart
@@ -16,7 +16,7 @@
 import 'src/utils.dart' as utils;
 
 /// For testing sort behavior.
-class TestLibraryContainer extends LibraryContainer with Nameable{
+class TestLibraryContainer extends LibraryContainer with Nameable {
   @override
   final List<String> containerOrder;
   @override
diff --git a/test/tool_runner_test.dart b/test/tool_runner_test.dart
index 5a09e0b..6911103 100644
--- a/test/tool_runner_test.dart
+++ b/test/tool_runner_test.dart
@@ -74,8 +74,7 @@
         'TEST INPUT',
       );
       expect(errors, isNotEmpty);
-      expect(
-          errors[0], contains('Tool "drill" returned non-zero exit code'));
+      expect(errors[0], contains('Tool "drill" returned non-zero exit code'));
       expect(result, isEmpty);
     });
     test("fails if tool in tool map doesn't exist", () {
diff --git a/testing/test_package/lib/example.dart b/testing/test_package/lib/example.dart
index 115651a..b6388fe 100644
--- a/testing/test_package/lib/example.dart
+++ b/testing/test_package/lib/example.dart
@@ -605,4 +605,4 @@
   ///    <div style="opacity: 0.5;">[HtmlInjection]</div>
   /// {@end-inject-html}
   void injectSimpleHtml();
-}
\ No newline at end of file
+}