Migration: handle simple assignment expressions (x = y).

Change-Id: I580b902e83325a7a0a85686ebf7393993e531446
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/104803
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/analysis_server/lib/src/nullability/graph_builder.dart b/pkg/analysis_server/lib/src/nullability/graph_builder.dart
index 0c3cf07..3e3f7c2 100644
--- a/pkg/analysis_server/lib/src/nullability/graph_builder.dart
+++ b/pkg/analysis_server/lib/src/nullability/graph_builder.dart
@@ -139,6 +139,15 @@
   }
 
   @override
+  DecoratedType visitAssignmentExpression(AssignmentExpression node) {
+    if (node.operator.type != TokenType.EQ) {
+      throw UnimplementedError('TODO(paulberry)');
+    }
+    var leftType = node.leftHandSide.accept(this);
+    return _handleAssignment(leftType, node.rightHandSide);
+  }
+
+  @override
   DecoratedType visitBinaryExpression(BinaryExpression node) {
     switch (node.operator.type) {
       case TokenType.EQ_EQ:
diff --git a/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart b/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
index f83303d..e5e2877 100644
--- a/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
+++ b/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
@@ -109,6 +109,29 @@
     assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
   }
 
+  test_assignmentExpression_operands() async {
+    await analyze('''
+void f(int i, int j) {
+  i = j;
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int j').node,
+        decoratedTypeAnnotation('int i').node,
+        hard: true);
+  }
+
+  test_assignmentExpression_value() async {
+    await analyze('''
+void f(int i, int j) {
+  g(i = j);
+}
+void g(int k) {}
+''');
+    assertEdge(decoratedTypeAnnotation('int j').node,
+        decoratedTypeAnnotation('int k').node,
+        hard: false);
+  }
+
   test_binaryExpression_add_left_check() async {
     await analyze('''
 int f(int i, int j) => i + j;
diff --git a/pkg/analysis_server/test/src/nullability/provisional_api_test.dart b/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
index 0a6f48d..eb0d189 100644
--- a/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
+++ b/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
@@ -210,6 +210,22 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  test_data_flow_assignment() async {
+    var content = '''
+void main() {
+  int i = 0;
+  i = null;
+}
+''';
+    var expected = '''
+void main() {
+  int? i = 0;
+  i = null;
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_data_flow_generic_inward() async {
     var content = '''
 class C<T> {