Migration: Separate the implementation from the NNBD migration engine's public API.

Change-Id: I0ea000b9068661d4e9122414320202ebd4f8563b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/105413
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/nnbd_migration/lib/nnbd_migration.dart b/pkg/nnbd_migration/lib/nnbd_migration.dart
index eebd31a..33afb82 100644
--- a/pkg/nnbd_migration/lib/nnbd_migration.dart
+++ b/pkg/nnbd_migration/lib/nnbd_migration.dart
@@ -6,13 +6,7 @@
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:meta/meta.dart';
-import 'package:nnbd_migration/src/decorated_type.dart' as analyzer;
-import 'package:nnbd_migration/src/expression_checks.dart' as analyzer;
-import 'package:nnbd_migration/src/graph_builder.dart';
-import 'package:nnbd_migration/src/node_builder.dart';
-import 'package:nnbd_migration/src/nullability_node.dart';
-import 'package:nnbd_migration/src/potential_modification.dart' as analyzer;
-import 'package:nnbd_migration/src/variables.dart';
+import 'package:nnbd_migration/src/nullability_migration_impl.dart';
 
 /// Kinds of fixes that might be performed by nullability migration.
 class NullabilityFixKind {
@@ -58,49 +52,21 @@
 /// Usage: pass each input source file to [prepareInput].  Then pass each input
 /// source file to [processInput].  Then call [finish] to obtain the
 /// modifications that need to be made to each source file.
-class NullabilityMigration {
-  final NullabilityMigrationListener listener;
-
-  final _variables = Variables();
-
-  final _graph = NullabilityGraph();
-
-  final bool _permissive;
-
+abstract class NullabilityMigration {
   /// Prepares to perform nullability migration.
   ///
   /// If [permissive] is `true`, exception handling logic will try to proceed
   /// as far as possible even though the migration algorithm is not yet
   /// complete.  TODO(paulberry): remove this mode once the migration algorithm
   /// is fully implemented.
-  NullabilityMigration(this.listener, {bool permissive: false})
-      : _permissive = permissive;
+  factory NullabilityMigration(NullabilityMigrationListener listener,
+      {bool permissive}) = NullabilityMigrationImpl;
 
-  void finish() {
-    _graph.propagate();
-    for (var entry in _variables.getPotentialModifications().entries) {
-      var source = entry.key;
-      for (var potentialModification in entry.value) {
-        var fix = _SingleNullabilityFix(source, potentialModification);
-        listener.addFix(fix);
-        for (var edit in potentialModification.modifications) {
-          listener.addEdit(fix, edit);
-        }
-      }
-    }
-  }
+  void finish();
 
-  void prepareInput(ResolvedUnitResult result) {
-    var unit = result.unit;
-    unit.accept(NodeBuilder(_variables, unit.declaredElement.source,
-        _permissive ? listener : null, _graph, result.typeProvider));
-  }
+  void prepareInput(ResolvedUnitResult result);
 
-  void processInput(ResolvedUnitResult result) {
-    var unit = result.unit;
-    unit.accept(GraphBuilder(result.typeProvider, _variables, _graph,
-        unit.declaredElement.source, _permissive ? listener : null));
-  }
+  void processInput(ResolvedUnitResult result);
 }
 
 /// [NullabilityMigrationListener] is used by [NullabilityMigration]
@@ -131,43 +97,3 @@
   /// File to change.
   Source get source;
 }
-
-/// Implementation of [SingleNullabilityFix] used internally by
-/// [NullabilityMigration].
-class _SingleNullabilityFix extends SingleNullabilityFix {
-  @override
-  final Source source;
-
-  @override
-  final NullabilityFixKind kind;
-
-  factory _SingleNullabilityFix(
-      Source source, analyzer.PotentialModification potentialModification) {
-    // TODO(paulberry): once everything is migrated into the analysis server,
-    // the migration engine can just create SingleNullabilityFix objects
-    // directly and set their kind appropriately; we won't need to translate the
-    // kinds using a bunch of `is` checks.
-    NullabilityFixKind kind;
-    if (potentialModification is analyzer.ExpressionChecks) {
-      kind = NullabilityFixKind.checkExpression;
-    } else if (potentialModification is analyzer.DecoratedTypeAnnotation) {
-      kind = NullabilityFixKind.makeTypeNullable;
-    } else if (potentialModification is analyzer.ConditionalModification) {
-      kind = potentialModification.discard.keepFalse
-          ? NullabilityFixKind.discardThen
-          : NullabilityFixKind.discardElse;
-    } else if (potentialModification is analyzer.PotentiallyAddImport) {
-      kind = NullabilityFixKind.addImport;
-    } else if (potentialModification is analyzer.PotentiallyAddRequired) {
-      kind = NullabilityFixKind.addRequired;
-    } else {
-      throw new UnimplementedError('TODO(paulberry)');
-    }
-    return _SingleNullabilityFix._(source, kind);
-  }
-
-  _SingleNullabilityFix._(this.source, this.kind);
-
-  /// TODO(paulberry): do something better
-  Location get location => null;
-}
diff --git a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
new file mode 100644
index 0000000..a94f87b
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2019, 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:analysis_server/src/protocol_server.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/expression_checks.dart';
+import 'package:nnbd_migration/src/graph_builder.dart';
+import 'package:nnbd_migration/src/node_builder.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
+import 'package:nnbd_migration/src/potential_modification.dart';
+import 'package:nnbd_migration/src/variables.dart';
+
+/// Implementation of the [NullabilityMigration] public API.
+class NullabilityMigrationImpl implements NullabilityMigration {
+  final NullabilityMigrationListener listener;
+
+  final _variables = Variables();
+
+  final _graph = NullabilityGraph();
+
+  final bool _permissive;
+
+  /// Prepares to perform nullability migration.
+  ///
+  /// If [permissive] is `true`, exception handling logic will try to proceed
+  /// as far as possible even though the migration algorithm is not yet
+  /// complete.  TODO(paulberry): remove this mode once the migration algorithm
+  /// is fully implemented.
+  NullabilityMigrationImpl(this.listener, {bool permissive: false})
+      : _permissive = permissive;
+
+  void finish() {
+    _graph.propagate();
+    for (var entry in _variables.getPotentialModifications().entries) {
+      var source = entry.key;
+      for (var potentialModification in entry.value) {
+        var fix = _SingleNullabilityFix(source, potentialModification);
+        listener.addFix(fix);
+        for (var edit in potentialModification.modifications) {
+          listener.addEdit(fix, edit);
+        }
+      }
+    }
+  }
+
+  void prepareInput(ResolvedUnitResult result) {
+    var unit = result.unit;
+    unit.accept(NodeBuilder(_variables, unit.declaredElement.source,
+        _permissive ? listener : null, _graph, result.typeProvider));
+  }
+
+  void processInput(ResolvedUnitResult result) {
+    var unit = result.unit;
+    unit.accept(GraphBuilder(result.typeProvider, _variables, _graph,
+        unit.declaredElement.source, _permissive ? listener : null));
+  }
+}
+
+/// Implementation of [SingleNullabilityFix] used internally by
+/// [NullabilityMigration].
+class _SingleNullabilityFix extends SingleNullabilityFix {
+  @override
+  final Source source;
+
+  @override
+  final NullabilityFixKind kind;
+
+  factory _SingleNullabilityFix(
+      Source source, PotentialModification potentialModification) {
+    // TODO(paulberry): once everything is migrated into the analysis server,
+    // the migration engine can just create SingleNullabilityFix objects
+    // directly and set their kind appropriately; we won't need to translate the
+    // kinds using a bunch of `is` checks.
+    NullabilityFixKind kind;
+    if (potentialModification is ExpressionChecks) {
+      kind = NullabilityFixKind.checkExpression;
+    } else if (potentialModification is DecoratedTypeAnnotation) {
+      kind = NullabilityFixKind.makeTypeNullable;
+    } else if (potentialModification is ConditionalModification) {
+      kind = potentialModification.discard.keepFalse
+          ? NullabilityFixKind.discardThen
+          : NullabilityFixKind.discardElse;
+    } else if (potentialModification is PotentiallyAddImport) {
+      kind = NullabilityFixKind.addImport;
+    } else if (potentialModification is PotentiallyAddRequired) {
+      kind = NullabilityFixKind.addRequired;
+    } else {
+      throw new UnimplementedError('TODO(paulberry)');
+    }
+    return _SingleNullabilityFix._(source, kind);
+  }
+
+  _SingleNullabilityFix._(this.source, this.kind);
+
+  /// TODO(paulberry): do something better
+  Location get location => null;
+}