diff --git a/pkg/analyzer/test/src/summary/linker_test.dart b/pkg/analyzer/test/src/summary/linker_test.dart
index 3dee3bf..fdb3cf3 100644
--- a/pkg/analyzer/test/src/summary/linker_test.dart
+++ b/pkg/analyzer/test/src/summary/linker_test.dart
@@ -4,13 +4,12 @@
 
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/link.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'summarize_ast_test.dart';
+import 'test_strategies.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -19,29 +18,17 @@
 }
 
 @reflectiveTest
-class LinkerUnitTest extends SummaryLinkerTest {
-  Linker linker;
+class LinkerUnitTest extends SummaryLinkerTestStrategyTwoPhase
+    with LinkerUnitTestCases {}
 
-  LinkerInputs linkerInputs;
-  LibraryElementInBuildUnit _testLibrary;
-  @override
-  bool get allowMissingFiles => false;
-
+/// Test cases that exercise the summary linker in a white-box fashion.
+///
+/// These test cases may be mixed into any class derived from
+/// [SummaryLinkerTestStrategy], allowing the linker to be unit-tested in a
+/// variety of ways.
+abstract class LinkerUnitTestCases implements SummaryLinkerTestStrategy {
   Matcher get isUndefined => const TypeMatcher<UndefinedElementForLink>();
 
-  LibraryElementInBuildUnit get testLibrary => _testLibrary ??=
-      linker.getLibrary(linkerInputs.testDartUri) as LibraryElementInBuildUnit;
-
-  void createLinker(String text, {String path: '/test.dart'}) {
-    linkerInputs = createLinkerInputs(text, path: path);
-    Map<String, LinkedLibraryBuilder> linkedLibraries = setupForLink(
-        linkerInputs.linkedLibraries,
-        linkerInputs.getUnit,
-        linkerInputs.getDeclaredVariable);
-    linker = new Linker(
-        linkedLibraries, linkerInputs.getDependency, linkerInputs.getUnit);
-  }
-
   LibraryElementForLink getLibrary(String uri) {
     return linker.getLibrary(Uri.parse(uri));
   }
diff --git a/pkg/analyzer/test/src/summary/prelinker_test.dart b/pkg/analyzer/test/src/summary/prelinker_test.dart
index abc11be..6ac254a 100644
--- a/pkg/analyzer/test/src/summary/prelinker_test.dart
+++ b/pkg/analyzer/test/src/summary/prelinker_test.dart
@@ -2,12 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/prelink.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'summarize_ast_test.dart';
 import 'summary_common.dart';
+import 'test_strategies.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -15,34 +13,11 @@
   });
 }
 
-/**
- * Override of [SummaryTest] which verifies the correctness of the prelinker by
- * creating summaries from the element model, discarding their prelinked
- * information, and then recreating it using the prelinker.
- */
+/// Tests for the pre-linker which exercise it using the old (two-phase) summary
+/// generation strategy.
+///
+/// TODO(paulberry): eliminate these tests once we have transitioned over to
+/// one-step summary generation.
 @reflectiveTest
-class PrelinkerTest extends LinkedSummarizeAstTest {
-  @override
-  bool get skipFullyLinkedData => true;
-
-  @override
-  void serializeLibraryText(String text, {bool allowErrors: false}) {
-    super.serializeLibraryText(text, allowErrors: allowErrors);
-
-    UnlinkedUnit getPart(String absoluteUri) {
-      return linkerInputs.getUnit(absoluteUri);
-    }
-
-    UnlinkedPublicNamespace getImport(String absoluteUri) {
-      return getPart(absoluteUri)?.publicNamespace;
-    }
-
-    linked = new LinkedLibrary.fromBuffer(prelink(
-        linkerInputs.testDartUri.toString(),
-        linkerInputs.unlinkedDefiningUnit,
-        getPart,
-        getImport,
-        (String declaredVariable) => null).toBuffer());
-    validateLinkedLibrary(linked);
-  }
-}
+class PrelinkerTest extends SummaryBlackBoxTestStrategyPrelink
+    with SummaryTestCases {}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index 77cafe4..c103ef5 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -28,7 +28,7 @@
 import '../context/abstract_context.dart';
 import 'element_text.dart';
 import 'resynthesize_common.dart';
-import 'summary_common.dart';
+import 'test_strategies.dart';
 
 main() {
   defineReflectiveSuite(() {
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
index a6f9de1..6c2d84c 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
@@ -4,7 +4,8 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'summarize_ast_test.dart';
+import 'summary_common.dart';
+import 'test_strategies.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -12,11 +13,9 @@
   });
 }
 
-/**
- * Override of [LinkedSummarizeAstTest] which uses strong mode.
- */
 @reflectiveTest
-class LinkedSummarizeAstStrongTest extends LinkedSummarizeAstTest {
+class LinkedSummarizeAstStrongTest extends SummaryBlackBoxTestStrategyTwoPhase
+    with SummaryTestCases {
   @override
   @failingTest
   test_bottom_reference_shared() {
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
deleted file mode 100644
index 8a0ca98..0000000
--- a/pkg/analyzer/test/src/summary/summarize_ast_test.dart
+++ /dev/null
@@ -1,251 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/scanner/reader.dart';
-import 'package:analyzer/src/dart/scanner/scanner.dart';
-import 'package:analyzer/src/generated/parser.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/link.dart';
-import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/summary/summarize_ast.dart';
-import 'package:analyzer/src/summary/summarize_elements.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'summary_common.dart';
-
-main() {}
-
-/**
- * Override of [SummaryTest] which creates linked summaries directly from the
- * AST.
- */
-@reflectiveTest
-abstract class LinkedSummarizeAstTest extends SummaryLinkerTest
-    with SummaryTest {
-  @override
-  LinkedLibrary linked;
-
-  @override
-  List<UnlinkedUnit> unlinkedUnits;
-
-  LinkerInputs linkerInputs;
-
-  @override
-  bool get skipFullyLinkedData => false;
-
-  @override
-  void serializeLibraryText(String text, {bool allowErrors: false}) {
-    Map<String, UnlinkedUnitBuilder> uriToUnit = this._filesToLink.uriToUnit;
-    linkerInputs = createLinkerInputs(text);
-    linked = link(
-        linkerInputs.linkedLibraries,
-        linkerInputs.getDependency,
-        linkerInputs.getUnit,
-        (name) => null)[linkerInputs.testDartUri.toString()];
-    expect(linked, isNotNull);
-    validateLinkedLibrary(linked);
-    unlinkedUnits = <UnlinkedUnit>[linkerInputs.unlinkedDefiningUnit];
-    for (String relativeUriStr
-        in linkerInputs.unlinkedDefiningUnit.publicNamespace.parts) {
-      Uri relativeUri;
-      try {
-        relativeUri = Uri.parse(relativeUriStr);
-      } on FormatException {
-        unlinkedUnits.add(new UnlinkedUnitBuilder());
-        continue;
-      }
-
-      UnlinkedUnit unit = uriToUnit[
-          resolveRelativeUri(linkerInputs.testDartUri, relativeUri).toString()];
-      if (unit == null) {
-        if (!allowMissingFiles) {
-          fail('Test referred to unknown unit $relativeUriStr');
-        }
-      } else {
-        unlinkedUnits.add(unit);
-      }
-    }
-  }
-
-  test_class_no_superclass() {
-    UnlinkedClass cls = serializeClassText('part of dart.core; class Object {}',
-        className: 'Object');
-    expect(cls.supertype, isNull);
-    expect(cls.hasNoSupertype, isTrue);
-  }
-}
-
-/**
- * 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;
-  }
-}
-
-/**
- * Base class providing the ability to run the summary linker using summaries
- * build from ASTs.
- */
-abstract class SummaryLinkerTest {
-  /**
-   * Information about the files to be linked.
-   */
-  _FilesToLink _filesToLink = new _FilesToLink();
-
-  /**
-   * A test will set this to `true` if it contains `import`, `export`, or
-   * `part` declarations that deliberately refer to non-existent files.
-   */
-  bool get allowMissingFiles;
-
-  /**
-   * Add the given package bundle as a dependency so that it may be referenced
-   * by the files under test.
-   */
-  void addBundle(String path, PackageBundle bundle) {
-    _filesToLink.summaryDataStore.addBundle(path, bundle);
-  }
-
-  /**
-   * Add the given source file so that it may be referenced by the file under
-   * test.
-   */
-  Source 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,
-      {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(
-        allowMissingFiles,
-        _filesToLink.uriToUnit,
-        testDartUri,
-        unlinkedDefiningUnit,
-        _filesToLink.summaryDataStore.linkedMap,
-        _filesToLink.summaryDataStore.unlinkedMap);
-    // Reset _filesToLink in case the test needs to start a new package bundle.
-    _filesToLink = new _FilesToLink();
-    return linkerInputs;
-  }
-
-  /**
-   * Link together the given file, along with any other files passed to
-   * [addNamedSource], to form a package bundle.  Reset the state of the buffers
-   * accumulated by [addNamedSource] and [addBundle] so that further bundles
-   * can be created.
-   */
-  PackageBundleBuilder createPackageBundle(String text,
-      {String path: '/test.dart', String uri}) {
-    PackageBundleAssembler assembler = new PackageBundleAssembler();
-    LinkerInputs linkerInputs = createLinkerInputs(text, path: path, uri: uri);
-    Map<String, LinkedLibraryBuilder> linkedLibraries = link(
-        linkerInputs.linkedLibraries,
-        linkerInputs.getDependency,
-        linkerInputs.getUnit,
-        linkerInputs.getDeclaredVariable);
-    linkedLibraries.forEach(assembler.addLinkedLibrary);
-    linkerInputs._uriToUnit.forEach((String uri, UnlinkedUnit unit) {
-      assembler.addUnlinkedUnitViaUri(uri, unit);
-    });
-    return assembler.assemble();
-  }
-
-  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;
-  }
-}
-
-/**
- * [_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
- * [SummaryLinkerTest.createLinkerInputs] is called.
- */
-class _FilesToLink {
-  /**
-   * Map from absolute URI to the [UnlinkedUnit] for each compilation unit
-   * passed to [addNamedSource].
-   */
-  Map<String, UnlinkedUnitBuilder> uriToUnit = <String, UnlinkedUnitBuilder>{};
-
-  /**
-   * Information about summaries to be included in the link process.
-   */
-  SummaryDataStore summaryDataStore = new SummaryDataStore([]);
-}
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 539eb5e..22eb0d3 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -14,18 +14,9 @@
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/public_namespace_computer.dart'
     as public_namespace;
-import 'package:path/path.dart' show posix;
 import 'package:test/test.dart';
 
-import '../context/mock_sdk.dart';
-
-/**
- * Convert the given Posix style file [path] to the corresponding absolute URI.
- */
-String absUri(String path) {
-  String absolutePath = posix.absolute(path);
-  return posix.toUri(absolutePath).toString();
-}
+import 'test_strategies.dart';
 
 /**
  * Convert a summary object (or a portion of one) into a canonical form that
@@ -83,85 +74,18 @@
  */
 typedef void _EntityRefValidator(EntityRef entityRef);
 
-/**
- * [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.
- *
- * Note: should an exception occur during computation of [instance], it will
- * silently be set to null to allow other tests to complete quickly.
- */
-class SerializedMockSdk {
-  static final SerializedMockSdk instance = _serializeMockSdk();
-
-  final Map<String, UnlinkedUnit> uriToUnlinkedUnit;
-
-  final Map<String, LinkedLibrary> uriToLinkedLibrary;
-  SerializedMockSdk._(this.uriToUnlinkedUnit, this.uriToLinkedLibrary);
-
-  static SerializedMockSdk _serializeMockSdk() {
-    try {
-      Map<String, UnlinkedUnit> uriToUnlinkedUnit = <String, UnlinkedUnit>{};
-      Map<String, LinkedLibrary> uriToLinkedLibrary = <String, LinkedLibrary>{};
-      PackageBundle bundle = new MockSdk().getLinkedBundle();
-      for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
-        String uri = bundle.unlinkedUnitUris[i];
-        uriToUnlinkedUnit[uri] = bundle.unlinkedUnits[i];
-      }
-      for (int i = 0; i < bundle.linkedLibraryUris.length; i++) {
-        String uri = bundle.linkedLibraryUris[i];
-        uriToLinkedLibrary[uri] = bundle.linkedLibraries[i];
-      }
-      return new SerializedMockSdk._(uriToUnlinkedUnit, uriToLinkedLibrary);
-    } catch (_) {
-      return null;
-    }
-  }
-}
-
-/**
- * Base class containing most summary tests.  This allows summary tests to be
- * re-used to exercise all the different ways in which summaries can be
- * generated (e.g. direct from the AST, from the element model, from a
- * "relinking" process, etc.)
- */
-abstract class SummaryTest {
-  /**
-   * A test will set this to `true` if it contains `import`, `export`, or
-   * `part` declarations that deliberately refer to non-existent files.
-   */
-  bool allowMissingFiles = false;
-
+/// Test cases that exercise summary generation in a black-box fashion.
+///
+/// These test cases may be mixed into any class derived from
+/// [SummaryBlackBoxTestStrategy], allowing summary generation to be unit-tested
+/// in a variety of ways.
+abstract class SummaryTestCases implements SummaryBlackBoxTestStrategy {
   /**
    * Get access to the linked defining compilation unit.
    */
   LinkedUnit get definingUnit => linked.units[0];
 
   /**
-   * Get access to the linked summary that results from serializing and
-   * then deserializing the library under test.
-   */
-  LinkedLibrary get linked;
-
-  /**
-   * `true` if the linked portion of the summary only contains prelinked data.
-   * This happens because we don't yet have a full linker; only a prelinker.
-   */
-  bool get skipFullyLinkedData;
-
-  /**
-   * Get access to the unlinked compilation unit summaries that result from
-   * serializing and deserializing the library under test.
-   */
-  List<UnlinkedUnit> get unlinkedUnits;
-
-  /**
-   * Add the given source file so that it may be referenced by the file under
-   * test.
-   */
-  Source addNamedSource(String filePath, String contents);
-
-  /**
    * TODO(scheglov) rename "Const" to "Expr" everywhere
    */
   void assertUnlinkedConst(UnlinkedExpr constExpr,
@@ -818,12 +742,6 @@
   }
 
   /**
-   * Serialize the given library [text], then deserialize it and store its
-   * summary in [lib].
-   */
-  void serializeLibraryText(String text, {bool allowErrors: false});
-
-  /**
    * Serialize the given method [text] and return the summary of the executable
    * with the given [executableName].
    */
@@ -1419,6 +1337,13 @@
     expect(cls.mixins, isEmpty);
   }
 
+  test_class_no_superclass() {
+    UnlinkedClass cls = serializeClassText('part of dart.core; class Object {}',
+        className: 'Object');
+    expect(cls.supertype, isNull);
+    expect(cls.hasNoSupertype, isTrue);
+  }
+
   test_class_no_type_param() {
     UnlinkedClass cls = serializeClassText('class C {}');
     expect(cls.typeParameters, isEmpty);
@@ -9979,42 +9904,6 @@
   }
 
   /**
-   * Verify invariants of the given [linkedLibrary].
-   */
-  void validateLinkedLibrary(LinkedLibrary linkedLibrary) {
-    for (LinkedUnit unit in linkedLibrary.units) {
-      for (LinkedReference reference in unit.references) {
-        switch (reference.kind) {
-          case ReferenceKind.classOrEnum:
-          case ReferenceKind.topLevelPropertyAccessor:
-          case ReferenceKind.topLevelFunction:
-          case ReferenceKind.typedef:
-            // This reference can have either a zero or a nonzero dependency,
-            // since it refers to top level element which might or might not be
-            // imported from another library.
-            break;
-          case ReferenceKind.prefix:
-            // Prefixes should have a dependency of 0, since they come from the
-            // current library.
-            expect(reference.dependency, 0,
-                reason: 'Nonzero dependency for prefix');
-            break;
-          case ReferenceKind.unresolved:
-            // Unresolved references always have a dependency of 0.
-            expect(reference.dependency, 0,
-                reason: 'Nonzero dependency for undefined');
-            break;
-          default:
-            // This reference should have a dependency of 0, since it refers to
-            // an element that is contained within some other element.
-            expect(reference.dependency, 0,
-                reason: 'Nonzero dependency for ${reference.kind}');
-        }
-      }
-    }
-  }
-
-  /**
    * Assert that serializing the given [expr] of form `(a op= 1 + 2) + 3`
    * uses the given [expectedAssignOperator].
    */
diff --git a/pkg/analyzer/test/src/summary/test_all.dart b/pkg/analyzer/test/src/summary/test_all.dart
index 27c4030..1ffc606 100644
--- a/pkg/analyzer/test/src/summary/test_all.dart
+++ b/pkg/analyzer/test/src/summary/test_all.dart
@@ -12,7 +12,6 @@
 import 'prelinker_test.dart' as prelinker_test;
 import 'resynthesize_ast_test.dart' as resynthesize_ast_test;
 import 'summarize_ast_strong_test.dart' as summarize_ast_strong_test;
-import 'summarize_ast_test.dart' as summarize_ast_test;
 import 'top_level_inference_test.dart' as top_level_inference_test;
 
 main() {
@@ -25,7 +24,6 @@
     prelinker_test.main();
     resynthesize_ast_test.main();
     summarize_ast_strong_test.main();
-    summarize_ast_test.main();
     top_level_inference_test.main();
   }, name: 'summary');
 }
diff --git a/pkg/analyzer/test/src/summary/test_strategies.dart b/pkg/analyzer/test/src/summary/test_strategies.dart
new file mode 100644
index 0000000..033b824
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/test_strategies.dart
@@ -0,0 +1,465 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/scanner/reader.dart';
+import 'package:analyzer/src/dart/scanner/scanner.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/link.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/summary/prelink.dart';
+import 'package:analyzer/src/summary/summarize_ast.dart';
+import 'package:analyzer/src/summary/summarize_elements.dart';
+import 'package:path/path.dart' show posix;
+import 'package:test/test.dart';
+
+import '../context/mock_sdk.dart';
+
+/**
+ * Convert the given Posix style file [path] to the corresponding absolute URI.
+ */
+String absUri(String path) {
+  String absolutePath = posix.absolute(path);
+  return posix.toUri(absolutePath).toString();
+}
+
+/**
+ * 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.
+ *
+ * Note: should an exception occur during computation of [instance], it will
+ * silently be set to null to allow other tests to complete quickly.
+ */
+class SerializedMockSdk {
+  static final SerializedMockSdk instance = _serializeMockSdk();
+
+  final Map<String, UnlinkedUnit> uriToUnlinkedUnit;
+
+  final Map<String, LinkedLibrary> uriToLinkedLibrary;
+  SerializedMockSdk._(this.uriToUnlinkedUnit, this.uriToLinkedLibrary);
+
+  static SerializedMockSdk _serializeMockSdk() {
+    try {
+      Map<String, UnlinkedUnit> uriToUnlinkedUnit = <String, UnlinkedUnit>{};
+      Map<String, LinkedLibrary> uriToLinkedLibrary = <String, LinkedLibrary>{};
+      PackageBundle bundle = new MockSdk().getLinkedBundle();
+      for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
+        String uri = bundle.unlinkedUnitUris[i];
+        uriToUnlinkedUnit[uri] = bundle.unlinkedUnits[i];
+      }
+      for (int i = 0; i < bundle.linkedLibraryUris.length; i++) {
+        String uri = bundle.linkedLibraryUris[i];
+        uriToLinkedLibrary[uri] = bundle.linkedLibraries[i];
+      }
+      return new SerializedMockSdk._(uriToUnlinkedUnit, uriToLinkedLibrary);
+    } catch (_) {
+      return null;
+    }
+  }
+}
+
+/// Abstract base class for tests involving summaries.
+///
+/// Test classes should not extend this class directly; they should extend a
+/// class that implements this class with methods that drive summary generation.
+/// 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);
+}
+
+/// Abstract base class for black-box tests of summaries.
+///
+/// Test classes should not extend this class directly; they should extend a
+/// class that implements this class with methods that drive summary generation.
+/// The tests themselves can then be provided via mixin, allowing summaries to
+/// be tested in a variety of ways.
+abstract class SummaryBlackBoxTestStrategy extends SummaryBaseTestStrategy {
+  /**
+   * A test will set this to `true` if it contains `import`, `export`, or
+   * `part` declarations that deliberately refer to non-existent files.
+   */
+  void set allowMissingFiles(bool value);
+
+  /**
+   * Get access to the linked summary that results from serializing and
+   * then deserializing the library under test.
+   */
+  LinkedLibrary get linked;
+
+  /**
+   * `true` if the linked portion of the summary only contains prelinked data.
+   * This happens because we don't yet have a full linker; only a prelinker.
+   */
+  bool get skipFullyLinkedData;
+
+  /**
+   * Get access to the unlinked compilation unit summaries that result from
+   * serializing and deserializing the library under test.
+   */
+  List<UnlinkedUnit> get unlinkedUnits;
+
+  /**
+   * Serialize the given library [text], then deserialize it and store its
+   * summary in [lib].
+   */
+  void serializeLibraryText(String text, {bool allowErrors: false});
+}
+
+/// Implementation of [SummaryBlackBoxTestStrategy] that drives summary
+/// generation using the old two-phase API, and exercises the pre-linker only.
+class SummaryBlackBoxTestStrategyPrelink
+    extends _SummaryBlackBoxTestStrategyTwoPhase
+    implements SummaryBlackBoxTestStrategy {
+  @override
+  bool get skipFullyLinkedData => true;
+
+  @override
+  void serializeLibraryText(String text, {bool allowErrors: false}) {
+    super.serializeLibraryText(text, allowErrors: allowErrors);
+
+    UnlinkedUnit getPart(String absoluteUri) {
+      return linkerInputs.getUnit(absoluteUri);
+    }
+
+    UnlinkedPublicNamespace getImport(String absoluteUri) {
+      return getPart(absoluteUri)?.publicNamespace;
+    }
+
+    linked = new LinkedLibrary.fromBuffer(prelink(
+        linkerInputs.testDartUri.toString(),
+        linkerInputs.unlinkedDefiningUnit,
+        getPart,
+        getImport,
+        (String declaredVariable) => null).toBuffer());
+    _validateLinkedLibrary(linked);
+  }
+}
+
+/// Implementation of [SummaryBlackBoxTestStrategy] that drives summary
+/// generation using the old two-phase API, and exercises full summary
+/// generation.
+class SummaryBlackBoxTestStrategyTwoPhase
+    extends _SummaryBlackBoxTestStrategyTwoPhase
+    implements SummaryBlackBoxTestStrategy {
+  @override
+  bool get skipFullyLinkedData => false;
+}
+
+/// Abstract base class for unit tests of the summary linker.
+///
+/// Test classes should not extend this class directly; they should extend a
+/// class that implements this class with methods that drive summary generation.
+/// The tests themselves can then be provided via mixin, allowing summaries to
+/// be tested in a variety of ways.
+abstract class SummaryLinkerTestStrategy extends SummaryBaseTestStrategy {
+  Linker get linker;
+
+  LibraryElementInBuildUnit get testLibrary;
+
+  /**
+   * Add the given package bundle as a dependency so that it may be referenced
+   * by the files under test.
+   */
+  void addBundle(String path, PackageBundle bundle);
+
+  void createLinker(String text, {String path: '/test.dart'});
+
+  /**
+   * Link together the given file, along with any other files passed to
+   * [addNamedSource], to form a package bundle.  Reset the state of the buffers
+   * accumulated by [addNamedSource] and [addBundle] so that further bundles
+   * can be created.
+   */
+  PackageBundleBuilder createPackageBundle(String text,
+      {String path: '/test.dart', String uri});
+}
+
+/// Implementation of [SummaryLinkerTestStrategy] that drives summary generation
+/// using the old two-phase API.
+class SummaryLinkerTestStrategyTwoPhase extends _SummaryBaseTestStrategyTwoPhase
+    implements SummaryLinkerTestStrategy {
+  LibraryElementInBuildUnit _testLibrary;
+
+  @override
+  Linker linker;
+
+  @override
+  LibraryElementInBuildUnit get testLibrary => _testLibrary ??=
+      linker.getLibrary(linkerInputs.testDartUri) as LibraryElementInBuildUnit;
+
+  @override
+  bool get _allowMissingFiles => false;
+
+  @override
+  void addBundle(String path, PackageBundle bundle) {
+    _filesToLink.summaryDataStore.addBundle(path, bundle);
+  }
+
+  @override
+  void createLinker(String text, {String path: '/test.dart'}) {
+    linkerInputs = createLinkerInputs(text, path: path);
+    Map<String, LinkedLibraryBuilder> linkedLibraries = setupForLink(
+        linkerInputs.linkedLibraries,
+        linkerInputs.getUnit,
+        linkerInputs.getDeclaredVariable);
+    linker = new Linker(
+        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);
+    Map<String, LinkedLibraryBuilder> linkedLibraries = link(
+        linkerInputs.linkedLibraries,
+        linkerInputs.getDependency,
+        linkerInputs.getUnit,
+        linkerInputs.getDeclaredVariable);
+    linkedLibraries.forEach(assembler.addLinkedLibrary);
+    linkerInputs._uriToUnit.forEach((String uri, UnlinkedUnit unit) {
+      assembler.addUnlinkedUnitViaUri(uri, unit);
+    });
+    return assembler.assemble();
+  }
+}
+
+/**
+ * [_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.
+ */
+class _FilesToLink {
+  /**
+   * Map from absolute URI to the [UnlinkedUnit] for each compilation unit
+   * passed to [addNamedSource].
+   */
+  Map<String, UnlinkedUnitBuilder> uriToUnit = <String, UnlinkedUnitBuilder>{};
+
+  /**
+   * Information about summaries to be included in the link process.
+   */
+  SummaryDataStore summaryDataStore = new SummaryDataStore([]);
+}
+
+/// Implementation of [SummaryBaseTestStrategy] that drives summary generation
+/// using the old two-phase API.
+abstract class _SummaryBaseTestStrategyTwoPhase
+    implements SummaryBaseTestStrategy {
+  /**
+   * Information about the files to be linked.
+   */
+  _FilesToLink _filesToLink = new _FilesToLink();
+
+  @override
+  LinkerInputs linkerInputs;
+
+  bool get _allowMissingFiles;
+
+  @override
+  Source 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,
+      {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(
+        _allowMissingFiles,
+        _filesToLink.uriToUnit,
+        testDartUri,
+        unlinkedDefiningUnit,
+        _filesToLink.summaryDataStore.linkedMap,
+        _filesToLink.summaryDataStore.unlinkedMap);
+    // Reset _filesToLink in case the test needs to start a new package bundle.
+    _filesToLink = new _FilesToLink();
+    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;
+  }
+}
+
+/// Implementation of [SummaryBlackBoxTestStrategy] that drives summary
+/// generation using the old two-phase API.
+///
+/// Not intended to be used directly; instead use a derived class that either
+/// exercises the full summary algorithmm or just pre-linking.
+abstract class _SummaryBlackBoxTestStrategyTwoPhase
+    extends _SummaryBaseTestStrategyTwoPhase
+    implements SummaryBlackBoxTestStrategy {
+  @override
+  List<UnlinkedUnit> unlinkedUnits;
+
+  @override
+  LinkedLibrary linked;
+
+  @override
+  bool _allowMissingFiles = false;
+
+  @override
+  void set allowMissingFiles(bool value) {
+    _allowMissingFiles = value;
+  }
+
+  @override
+  void serializeLibraryText(String text, {bool allowErrors: false}) {
+    Map<String, UnlinkedUnitBuilder> uriToUnit = this._filesToLink.uriToUnit;
+    linkerInputs = createLinkerInputs(text);
+    linked = link(
+        linkerInputs.linkedLibraries,
+        linkerInputs.getDependency,
+        linkerInputs.getUnit,
+        (name) => null)[linkerInputs.testDartUri.toString()];
+    expect(linked, isNotNull);
+    _validateLinkedLibrary(linked);
+    unlinkedUnits = <UnlinkedUnit>[linkerInputs.unlinkedDefiningUnit];
+    for (String relativeUriStr
+        in linkerInputs.unlinkedDefiningUnit.publicNamespace.parts) {
+      Uri relativeUri;
+      try {
+        relativeUri = Uri.parse(relativeUriStr);
+      } on FormatException {
+        unlinkedUnits.add(new UnlinkedUnitBuilder());
+        continue;
+      }
+
+      UnlinkedUnit unit = uriToUnit[
+          resolveRelativeUri(linkerInputs.testDartUri, relativeUri).toString()];
+      if (unit == null) {
+        if (!_allowMissingFiles) {
+          fail('Test referred to unknown unit $relativeUriStr');
+        }
+      } else {
+        unlinkedUnits.add(unit);
+      }
+    }
+  }
+
+  /**
+   * Verify invariants of the given [linkedLibrary].
+   */
+  void _validateLinkedLibrary(LinkedLibrary linkedLibrary) {
+    for (LinkedUnit unit in linkedLibrary.units) {
+      for (LinkedReference reference in unit.references) {
+        switch (reference.kind) {
+          case ReferenceKind.classOrEnum:
+          case ReferenceKind.topLevelPropertyAccessor:
+          case ReferenceKind.topLevelFunction:
+          case ReferenceKind.typedef:
+            // This reference can have either a zero or a nonzero dependency,
+            // since it refers to top level element which might or might not be
+            // imported from another library.
+            break;
+          case ReferenceKind.prefix:
+            // Prefixes should have a dependency of 0, since they come from the
+            // current library.
+            expect(reference.dependency, 0,
+                reason: 'Nonzero dependency for prefix');
+            break;
+          case ReferenceKind.unresolved:
+            // Unresolved references always have a dependency of 0.
+            expect(reference.dependency, 0,
+                reason: 'Nonzero dependency for undefined');
+            break;
+          default:
+            // This reference should have a dependency of 0, since it refers to
+            // an element that is contained within some other element.
+            expect(reference.dependency, 0,
+                reason: 'Nonzero dependency for ${reference.kind}');
+        }
+      }
+    }
+  }
+}
