Further refactoring of summary tests

This CL makes the following changes:

- Makes `linkerInputs` private to the strategy classes (the only thing
  needed by tests is `testDartUri`).

- Changes the return type of addNamedSource to `void` (no caller was
  using the return value).

- Generalizes _FilesToLink so that it can be re-used for one-phase
  summary generation (where the inputs will be CompilationUnit objects
  rather than UnlinkedUnitBuilder objects).

- Moves _parseText to top level so that it can be more easily reused.

Change-Id: I333b278b9a157b5013199d0c21cc4c8d3423dbe7
Reviewed-on: https://dart-review.googlesource.com/73281
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer/test/src/summary/linker_test.dart b/pkg/analyzer/test/src/summary/linker_test.dart
index fdb3cf3..e738436 100644
--- a/pkg/analyzer/test/src/summary/linker_test.dart
+++ b/pkg/analyzer/test/src/summary/linker_test.dart
@@ -96,7 +96,7 @@
   var j;
 }
     ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     // No assertions--just make sure it doesn't crash.
   }
@@ -110,7 +110,7 @@
   void f() {}
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     // No assertions--just make sure it doesn't crash.
   }
@@ -124,7 +124,7 @@
   void f(g) {}
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     // No assertions--just make sure it doesn't crash.
   }
@@ -138,7 +138,7 @@
   var j;
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     // No assertions--just make sure it doesn't crash.
   }
@@ -153,7 +153,7 @@
   Future<T> f() => null;
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     // No assertions--just make sure it doesn't crash.
   }
@@ -167,7 +167,7 @@
   void f() {}
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
   }
 
@@ -180,7 +180,7 @@
   var c;
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     // No assertions--just make sure it doesn't crash.
   }
@@ -200,7 +200,7 @@
 import "b.dart";
 var z = y;
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     expect(_getVariable(library.getContainedName('z')).inferredType.toString(),
         'int');
   }
@@ -278,7 +278,7 @@
   F<int> f;
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
 
     ClassElementForLink_Class B = library.getContainedName('B');
@@ -289,28 +289,28 @@
 
   void test_getContainedName_nonStaticField() {
     createLinker('class C { var f; }');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     ClassElementForLink_Class c = library.getContainedName('C');
     expect(c.getContainedName('f'), isNot(isUndefined));
   }
 
   void test_getContainedName_nonStaticGetter() {
     createLinker('class C { get g => null; }');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     ClassElementForLink_Class c = library.getContainedName('C');
     expect(c.getContainedName('g'), isNot(isUndefined));
   }
 
   void test_getContainedName_nonStaticMethod() {
     createLinker('class C { m() {} }');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     ClassElementForLink_Class c = library.getContainedName('C');
     expect(c.getContainedName('m'), isNot(isUndefined));
   }
 
   void test_getContainedName_nonStaticSetter() {
     createLinker('class C { void set s(value) {} }');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     ClassElementForLink_Class c = library.getContainedName('C');
     expect(c.getContainedName('s='), isNot(isUndefined));
   }
@@ -324,7 +324,7 @@
 import 'a.dart';
 var y = x;
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     expect(_getVariable(library.getContainedName('y')).inferredType.toString(),
         '() → Null');
   }
@@ -344,7 +344,7 @@
 import 'a.dart';
 var y = C.x;
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     expect(_getVariable(library.getContainedName('y')).inferredType.toString(),
         '(D) → E');
   }
@@ -365,7 +365,7 @@
   void foo(bar) {}
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     ClassElementForLink_Class cls = library.getContainedName('C');
     expect(cls.methods, hasLength(1));
@@ -381,7 +381,7 @@
   final f = true ? <T>(T t) => 0 : <T>(T t) => 1;
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     ClassElementForLink_Class cls = library.getContainedName('C');
     expect(cls.fields, hasLength(1));
@@ -396,7 +396,7 @@
   var f = x; // Inferred type: dynamic
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     ClassElementForLink_Class cls = library.getContainedName('C');
     expect(cls.fields, hasLength(1));
@@ -413,7 +413,7 @@
   f(x) {} // Inferred param type: dynamic
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     ClassElementForLink_Class cls = library.getContainedName('C');
     expect(cls.methods, hasLength(1));
@@ -431,7 +431,7 @@
   void m(p) {}
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     ClassElementForLink_Class cls = library.getContainedName('B');
     expect(cls.methods, hasLength(1));
@@ -450,7 +450,7 @@
   f() {} // Inferred return type: dynamic
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     ClassElementForLink_Class cls = library.getContainedName('C');
     expect(cls.methods, hasLength(1));
@@ -466,7 +466,7 @@
   f() {}
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     ClassElementForLink_Class cls = library.getContainedName('C');
     expect(cls.methods, hasLength(1));
@@ -486,7 +486,7 @@
   map<R2>(f) => null;
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     ClassElementForLink_Class c = library.getContainedName('C');
     expect(c.methods, hasLength(1));
@@ -511,7 +511,7 @@
   map<R2>(fs) => null;
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     ClassElementForLink_Class c = library.getContainedName('C');
     expect(c.methods, hasLength(1));
@@ -533,7 +533,7 @@
 ''');
     expect(
         _getVariable(linker
-                .getLibrary(linkerInputs.testDartUri)
+                .getLibrary(testDartUri)
                 .getContainedName('C')
                 .getContainedName('y'))
             .inferredType
@@ -547,9 +547,7 @@
 var y = x;
 ''');
     expect(
-        _getVariable(linker
-                .getLibrary(linkerInputs.testDartUri)
-                .getContainedName('y'))
+        _getVariable(linker.getLibrary(testDartUri).getContainedName('y'))
             .inferredType
             .toString(),
         'dynamic');
@@ -565,7 +563,7 @@
 import 'a.dart';
 var z = y; // Inferred type: dynamic
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     expect(_getVariable(library.getContainedName('z')).inferredType.toString(),
         'dynamic');
   }
@@ -581,7 +579,7 @@
 import 'a.dart';
 var x = new C().f; // Inferred type: int
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     expect(_getVariable(library.getContainedName('x')).inferredType.toString(),
         'int');
   }
@@ -599,7 +597,7 @@
   var g = new C().f; // Inferred type: int
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     ClassElementForLink_Class classD = library.getContainedName('D');
     expect(classD.fields[0].inferredType.toString(), 'int');
   }
@@ -620,7 +618,7 @@
   f(i) {} // Inferred param type: int
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     ClassElementForLink_Class cls = library.getContainedName('D');
     expect(cls.methods, hasLength(1));
@@ -643,7 +641,7 @@
 import 'a.dart';
 var x = new C().f(); // Inferred type: int
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     expect(_getVariable(library.getContainedName('x')).inferredType.toString(),
         'int');
   }
@@ -664,7 +662,7 @@
   f() => 2; //Inferred return type: int
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     ClassElementForLink_Class cls = library.getContainedName('D');
     expect(cls.methods, hasLength(1));
@@ -677,9 +675,7 @@
     addBundle('/a.ds', bundle);
     createLinker('import "a.dart"; var x = C.f;', path: '/b.dart');
     expect(
-        _getVariable(linker
-                .getLibrary(linkerInputs.testDartUri)
-                .getContainedName('x'))
+        _getVariable(linker.getLibrary(testDartUri).getContainedName('x'))
             .inferredType
             .toString(),
         'int');
@@ -690,9 +686,7 @@
     addBundle('/a.ds', bundle);
     createLinker('import "a.dart"; var b = a;', path: '/b.dart');
     expect(
-        _getVariable(linker
-                .getLibrary(linkerInputs.testDartUri)
-                .getContainedName('b'))
+        _getVariable(linker.getLibrary(testDartUri).getContainedName('b'))
             .inferredType
             .toString(),
         'int');
@@ -719,7 +713,7 @@
   void foo(X2 x) {}
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
 
     ClassElementForLink_Class C = library.getContainedName('C');
@@ -735,7 +729,7 @@
 class D<T extends num> {}
 final x = new C<D>();
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     PropertyAccessorElementForLink_Variable x = library.getContainedName('x');
     ParameterizedType type1 = x.returnType;
@@ -753,7 +747,7 @@
 class C<T extends num> {}
 final x = new C();
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     PropertyAccessorElementForLink_Variable x = library.getContainedName('x');
     ParameterizedType type1 = x.returnType;
@@ -768,7 +762,7 @@
 typedef T F<T extends num>();
 final x = new List<F>();
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     PropertyAccessorElementForLink_Variable x = library.getContainedName('x');
     ParameterizedType type1 = x.returnType;
@@ -788,7 +782,7 @@
   'f': f
 };
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     // No assertions--just make sure it doesn't crash.
   }
@@ -890,7 +884,7 @@
   void f() {}
 }
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     library.libraryCycleForLink.ensureLinked();
     // No assertions--just make sure it doesn't crash.
   }
@@ -925,21 +919,21 @@
 
   void test_topLevelFunction_isStatic() {
     createLinker('f() {}');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     TopLevelFunctionElementForLink f = library.getContainedName('f');
     expect(f.isStatic, true);
   }
 
   void test_topLevelGetter_isStatic() {
     createLinker('get x => null;');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     PropertyAccessorElementForLink_Executable x = library.getContainedName('x');
     expect(x.isStatic, true);
   }
 
   void test_topLevelSetter_isStatic() {
     createLinker('void set x(value) {}');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     PropertyAccessorElementForLink_Executable x =
         library.getContainedName('x=');
     expect(x.isStatic, true);
@@ -947,7 +941,7 @@
 
   void test_topLevelVariable_isStatic() {
     createLinker('var x;');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     PropertyAccessorElementForLink_Variable x = library.getContainedName('x');
     expect(x.isStatic, true);
     expect(x.variable.isStatic, true);
@@ -1006,7 +1000,7 @@
 int j;
 var v = 0;
 ''');
-    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    LibraryElementForLink library = linker.getLibrary(testDartUri);
     PropertyAccessorElementForLink_Variable c = library.getContainedName('c');
     expect(c.variable.initializer, isNotNull);
     PropertyAccessorElementForLink_Variable i = library.getContainedName('i');
diff --git a/pkg/analyzer/test/src/summary/test_strategies.dart b/pkg/analyzer/test/src/summary/test_strategies.dart
index 033b824..01a5b13 100644
--- a/pkg/analyzer/test/src/summary/test_strategies.dart
+++ b/pkg/analyzer/test/src/summary/test_strategies.dart
@@ -31,60 +31,6 @@
 }
 
 /**
- * Instances of the class [LinkerInputs] encapsulate the necessary information
- * to pass to the summary linker.
- */
-class LinkerInputs {
-  final bool _allowMissingFiles;
-  final Map<String, UnlinkedUnit> _uriToUnit;
-  final Uri testDartUri;
-  final UnlinkedUnit unlinkedDefiningUnit;
-  final Map<String, LinkedLibrary> _dependentLinkedLibraries;
-  final Map<String, UnlinkedUnit> _dependentUnlinkedUnits;
-
-  LinkerInputs(
-      this._allowMissingFiles,
-      this._uriToUnit,
-      this.testDartUri,
-      this.unlinkedDefiningUnit,
-      this._dependentLinkedLibraries,
-      this._dependentUnlinkedUnits);
-
-  Set<String> get linkedLibraries => _uriToUnit.keys.toSet();
-
-  String getDeclaredVariable(String name) {
-    return null;
-  }
-
-  LinkedLibrary getDependency(String absoluteUri) {
-    Map<String, LinkedLibrary> sdkLibraries =
-        SerializedMockSdk.instance.uriToLinkedLibrary;
-    LinkedLibrary linkedLibrary =
-        sdkLibraries[absoluteUri] ?? _dependentLinkedLibraries[absoluteUri];
-    if (linkedLibrary == null && !_allowMissingFiles) {
-      Set<String> librariesAvailable = sdkLibraries.keys.toSet();
-      librariesAvailable.addAll(_dependentLinkedLibraries.keys);
-      fail('Linker unexpectedly requested LinkedLibrary for "$absoluteUri".'
-          '  Libraries available: ${librariesAvailable.toList()}');
-    }
-    return linkedLibrary;
-  }
-
-  UnlinkedUnit getUnit(String absoluteUri) {
-    if (absoluteUri == null) {
-      return null;
-    }
-    UnlinkedUnit unit = _uriToUnit[absoluteUri] ??
-        SerializedMockSdk.instance.uriToUnlinkedUnit[absoluteUri] ??
-        _dependentUnlinkedUnits[absoluteUri];
-    if (unit == null && !_allowMissingFiles) {
-      fail('Linker unexpectedly requested unit for "$absoluteUri".');
-    }
-    return unit;
-  }
-}
-
-/**
  * [SerializedMockSdk] is a singleton class representing the result of
  * serializing the mock SDK to summaries.  It is computed once and then shared
  * among test invocations so that we don't bog down the tests.
@@ -127,13 +73,11 @@
 /// The tests themselves can then be provided via mixin, allowing summaries to
 /// be tested in a variety of ways.
 abstract class SummaryBaseTestStrategy {
-  LinkerInputs get linkerInputs;
-
   /**
    * Add the given source file so that it may be referenced by the file under
    * test.
    */
-  Source addNamedSource(String filePath, String contents);
+  void addNamedSource(String filePath, String contents);
 }
 
 /// Abstract base class for black-box tests of summaries.
@@ -187,7 +131,7 @@
     super.serializeLibraryText(text, allowErrors: allowErrors);
 
     UnlinkedUnit getPart(String absoluteUri) {
-      return linkerInputs.getUnit(absoluteUri);
+      return _linkerInputs.getUnit(absoluteUri);
     }
 
     UnlinkedPublicNamespace getImport(String absoluteUri) {
@@ -195,8 +139,8 @@
     }
 
     linked = new LinkedLibrary.fromBuffer(prelink(
-        linkerInputs.testDartUri.toString(),
-        linkerInputs.unlinkedDefiningUnit,
+        _linkerInputs._testDartUri.toString(),
+        _linkerInputs._unlinkedDefiningUnit,
         getPart,
         getImport,
         (String declaredVariable) => null).toBuffer());
@@ -223,6 +167,11 @@
 abstract class SummaryLinkerTestStrategy extends SummaryBaseTestStrategy {
   Linker get linker;
 
+  /// Gets the URI of the main library under test.
+  ///
+  /// May only be called after [createLinker].
+  Uri get testDartUri;
+
   LibraryElementInBuildUnit get testLibrary;
 
   /**
@@ -253,8 +202,12 @@
   Linker linker;
 
   @override
-  LibraryElementInBuildUnit get testLibrary => _testLibrary ??=
-      linker.getLibrary(linkerInputs.testDartUri) as LibraryElementInBuildUnit;
+  Uri get testDartUri => _linkerInputs._testDartUri;
+
+  @override
+  LibraryElementInBuildUnit get testLibrary =>
+      _testLibrary ??= linker.getLibrary(_linkerInputs._testDartUri)
+          as LibraryElementInBuildUnit;
 
   @override
   bool get _allowMissingFiles => false;
@@ -266,20 +219,21 @@
 
   @override
   void createLinker(String text, {String path: '/test.dart'}) {
-    linkerInputs = createLinkerInputs(text, path: path);
+    _linkerInputs = _createLinkerInputs(text, path: path);
     Map<String, LinkedLibraryBuilder> linkedLibraries = setupForLink(
-        linkerInputs.linkedLibraries,
-        linkerInputs.getUnit,
-        linkerInputs.getDeclaredVariable);
+        _linkerInputs.linkedLibraries,
+        _linkerInputs.getUnit,
+        _linkerInputs.getDeclaredVariable);
     linker = new Linker(
-        linkedLibraries, linkerInputs.getDependency, linkerInputs.getUnit);
+        linkedLibraries, _linkerInputs.getDependency, _linkerInputs.getUnit);
   }
 
   @override
   PackageBundleBuilder createPackageBundle(String text,
       {String path: '/test.dart', String uri}) {
     PackageBundleAssembler assembler = new PackageBundleAssembler();
-    LinkerInputs linkerInputs = createLinkerInputs(text, path: path, uri: uri);
+    _LinkerInputs linkerInputs =
+        _createLinkerInputs(text, path: path, uri: uri);
     Map<String, LinkedLibraryBuilder> linkedLibraries = link(
         linkerInputs.linkedLibraries,
         linkerInputs.getDependency,
@@ -296,14 +250,17 @@
 /**
  * [_FilesToLink] stores information about a set of files to be linked together.
  * This information is grouped into a class to allow it to be reset easily when
- * [_SummaryBaseTestStrategyTwoPhase.createLinkerInputs] is called.
+ * [_SummaryBaseTestStrategyTwoPhase._createLinkerInputs] is called.
+ *
+ * The generic parameter [U] is the type of information stored for each
+ * compilation unit.
  */
-class _FilesToLink {
+class _FilesToLink<U> {
   /**
-   * Map from absolute URI to the [UnlinkedUnit] for each compilation unit
-   * passed to [addNamedSource].
+   * Map from absolute URI to the [U] for each compilation unit passed to
+   * [addNamedSource].
    */
-  Map<String, UnlinkedUnitBuilder> uriToUnit = <String, UnlinkedUnitBuilder>{};
+  Map<String, U> uriToUnit = <String, U>{};
 
   /**
    * Information about summaries to be included in the link process.
@@ -311,6 +268,60 @@
   SummaryDataStore summaryDataStore = new SummaryDataStore([]);
 }
 
+/**
+ * Instances of the class [_LinkerInputs] encapsulate the necessary information
+ * to pass to the summary linker.
+ */
+class _LinkerInputs {
+  final bool _allowMissingFiles;
+  final Map<String, UnlinkedUnit> _uriToUnit;
+  final Uri _testDartUri;
+  final UnlinkedUnit _unlinkedDefiningUnit;
+  final Map<String, LinkedLibrary> _dependentLinkedLibraries;
+  final Map<String, UnlinkedUnit> _dependentUnlinkedUnits;
+
+  _LinkerInputs(
+      this._allowMissingFiles,
+      this._uriToUnit,
+      this._testDartUri,
+      this._unlinkedDefiningUnit,
+      this._dependentLinkedLibraries,
+      this._dependentUnlinkedUnits);
+
+  Set<String> get linkedLibraries => _uriToUnit.keys.toSet();
+
+  String getDeclaredVariable(String name) {
+    return null;
+  }
+
+  LinkedLibrary getDependency(String absoluteUri) {
+    Map<String, LinkedLibrary> sdkLibraries =
+        SerializedMockSdk.instance.uriToLinkedLibrary;
+    LinkedLibrary linkedLibrary =
+        sdkLibraries[absoluteUri] ?? _dependentLinkedLibraries[absoluteUri];
+    if (linkedLibrary == null && !_allowMissingFiles) {
+      Set<String> librariesAvailable = sdkLibraries.keys.toSet();
+      librariesAvailable.addAll(_dependentLinkedLibraries.keys);
+      fail('Linker unexpectedly requested LinkedLibrary for "$absoluteUri".'
+          '  Libraries available: ${librariesAvailable.toList()}');
+    }
+    return linkedLibrary;
+  }
+
+  UnlinkedUnit getUnit(String absoluteUri) {
+    if (absoluteUri == null) {
+      return null;
+    }
+    UnlinkedUnit unit = _uriToUnit[absoluteUri] ??
+        SerializedMockSdk.instance.uriToUnlinkedUnit[absoluteUri] ??
+        _dependentUnlinkedUnits[absoluteUri];
+    if (unit == null && !_allowMissingFiles) {
+      fail('Linker unexpectedly requested unit for "$absoluteUri".');
+    }
+    return unit;
+  }
+}
+
 /// Implementation of [SummaryBaseTestStrategy] that drives summary generation
 /// using the old two-phase API.
 abstract class _SummaryBaseTestStrategyTwoPhase
@@ -318,31 +329,28 @@
   /**
    * Information about the files to be linked.
    */
-  _FilesToLink _filesToLink = new _FilesToLink();
+  _FilesToLink<UnlinkedUnitBuilder> _filesToLink =
+      new _FilesToLink<UnlinkedUnitBuilder>();
 
-  @override
-  LinkerInputs linkerInputs;
+  _LinkerInputs _linkerInputs;
 
   bool get _allowMissingFiles;
 
   @override
-  Source addNamedSource(String filePath, String contents) {
+  void addNamedSource(String filePath, String contents) {
     CompilationUnit unit = _parseText(contents);
     UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
     _filesToLink.uriToUnit[absUri(filePath)] = unlinkedUnit;
-    // Tests using SummaryLinkerTest don't actually need the returned
-    // Source, so we can safely return `null`.
-    return null;
   }
 
-  LinkerInputs createLinkerInputs(String text,
+  _LinkerInputs _createLinkerInputs(String text,
       {String path: '/test.dart', String uri}) {
     uri ??= absUri(path);
     Uri testDartUri = Uri.parse(uri);
     UnlinkedUnitBuilder unlinkedDefiningUnit =
         createUnlinkedSummary(testDartUri, text);
     _filesToLink.uriToUnit[testDartUri.toString()] = unlinkedDefiningUnit;
-    LinkerInputs linkerInputs = new LinkerInputs(
+    _LinkerInputs linkerInputs = new _LinkerInputs(
         _allowMissingFiles,
         _filesToLink.uriToUnit,
         testDartUri,
@@ -350,25 +358,25 @@
         _filesToLink.summaryDataStore.linkedMap,
         _filesToLink.summaryDataStore.unlinkedMap);
     // Reset _filesToLink in case the test needs to start a new package bundle.
-    _filesToLink = new _FilesToLink();
+    _filesToLink = new _FilesToLink<UnlinkedUnitBuilder>();
     return linkerInputs;
   }
 
   UnlinkedUnitBuilder createUnlinkedSummary(Uri uri, String text) =>
       serializeAstUnlinked(_parseText(text));
+}
 
-  CompilationUnit _parseText(String text) {
-    CharSequenceReader reader = new CharSequenceReader(text);
-    Scanner scanner =
-        new Scanner(null, reader, AnalysisErrorListener.NULL_LISTENER);
-    Token token = scanner.tokenize();
-    Parser parser = new Parser(
-        NonExistingSource.unknown, AnalysisErrorListener.NULL_LISTENER);
-    (parser as ParserAdapter).fastaParser.isMixinSupportEnabled = true;
-    CompilationUnit unit = parser.parseCompilationUnit(token);
-    unit.lineInfo = new LineInfo(scanner.lineStarts);
-    return unit;
-  }
+CompilationUnit _parseText(String text) {
+  CharSequenceReader reader = new CharSequenceReader(text);
+  Scanner scanner =
+      new Scanner(null, reader, AnalysisErrorListener.NULL_LISTENER);
+  Token token = scanner.tokenize();
+  Parser parser = new Parser(
+      NonExistingSource.unknown, AnalysisErrorListener.NULL_LISTENER);
+  (parser as ParserAdapter).fastaParser.isMixinSupportEnabled = true;
+  CompilationUnit unit = parser.parseCompilationUnit(token);
+  unit.lineInfo = new LineInfo(scanner.lineStarts);
+  return unit;
 }
 
 /// Implementation of [SummaryBlackBoxTestStrategy] that drives summary
@@ -396,17 +404,17 @@
   @override
   void serializeLibraryText(String text, {bool allowErrors: false}) {
     Map<String, UnlinkedUnitBuilder> uriToUnit = this._filesToLink.uriToUnit;
-    linkerInputs = createLinkerInputs(text);
+    _linkerInputs = _createLinkerInputs(text);
     linked = link(
-        linkerInputs.linkedLibraries,
-        linkerInputs.getDependency,
-        linkerInputs.getUnit,
-        (name) => null)[linkerInputs.testDartUri.toString()];
+        _linkerInputs.linkedLibraries,
+        _linkerInputs.getDependency,
+        _linkerInputs.getUnit,
+        (name) => null)[_linkerInputs._testDartUri.toString()];
     expect(linked, isNotNull);
     _validateLinkedLibrary(linked);
-    unlinkedUnits = <UnlinkedUnit>[linkerInputs.unlinkedDefiningUnit];
+    unlinkedUnits = <UnlinkedUnit>[_linkerInputs._unlinkedDefiningUnit];
     for (String relativeUriStr
-        in linkerInputs.unlinkedDefiningUnit.publicNamespace.parts) {
+        in _linkerInputs._unlinkedDefiningUnit.publicNamespace.parts) {
       Uri relativeUri;
       try {
         relativeUri = Uri.parse(relativeUriStr);
@@ -416,7 +424,8 @@
       }
 
       UnlinkedUnit unit = uriToUnit[
-          resolveRelativeUri(linkerInputs.testDartUri, relativeUri).toString()];
+          resolveRelativeUri(_linkerInputs._testDartUri, relativeUri)
+              .toString()];
       if (unit == null) {
         if (!_allowMissingFiles) {
           fail('Test referred to unknown unit $relativeUriStr');