Migration: add support for metadata on library/import/export/part/part-of directives.

Part-of support needed to be added.

Should address ~12 exceptions whose stack trace contains the line:

AnnotationTracker.visitCompilationUnit.<anonymous closure> (package:nnbd_migration/src/utilities/annotation_tracker.dart:39:16)

Change-Id: Ib25d6dc123ac6134b6b5d25081ad5cebe02fd951
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/116441
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index a2400b2..5a73336 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -838,7 +838,8 @@
 
   @override
   DecoratedType visitLibraryDirective(LibraryDirective node) {
-    // skip directives
+    // skip directives, but not their metadata
+    node.metadata.accept(this);
     return null;
   }
 
@@ -924,7 +925,8 @@
 
   @override
   DecoratedType visitNamespaceDirective(NamespaceDirective node) {
-    // skip directives
+    // skip directives, but not their metadata
+    node.metadata.accept(this);
     return null;
   }
 
@@ -939,6 +941,13 @@
   }
 
   @override
+  DecoratedType visitPartOfDirective(PartOfDirective node) {
+    // skip directives, but not their metadata
+    node.metadata.accept(this);
+    return null;
+  }
+
+  @override
   DecoratedType visitPostfixExpression(PostfixExpression node) {
     var operatorType = node.operator.type;
     if (operatorType == TokenType.PLUS_PLUS ||
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index 8cce491a..079cf85 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -1573,6 +1573,15 @@
     assertNoUpstreamNullability(decoratedTypeAnnotation('double').node);
   }
 
+  test_export_metadata() async {
+    await analyze('''
+@deprecated
+export 'dart:async';
+''');
+    // No assertions needed; the AnnotationTracker mixin verifies that the
+    // metadata was visited.
+  }
+
   test_field_metadata() async {
     await analyze('''
 class A {
@@ -2250,6 +2259,15 @@
         assertEdge(nullable_i, nullable_return, hard: false));
   }
 
+  test_import_metadata() async {
+    await analyze('''
+@deprecated
+import 'dart:async';
+''');
+    // No assertions needed; the AnnotationTracker mixin verifies that the
+    // metadata was visited.
+  }
+
   test_indexExpression_dynamic() async {
     await analyze('''
 int f(dynamic d, int i) {
@@ -2491,6 +2509,15 @@
     assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
   }
 
+  test_library_metadata() async {
+    await analyze('''
+@deprecated
+library foo;
+''');
+    // No assertions needed; the AnnotationTracker mixin verifies that the
+    // metadata was visited.
+  }
+
   test_libraryDirective() async {
     await analyze('''
 library foo;
@@ -3187,6 +3214,62 @@
         assertEdge(always, decoratedTypeAnnotation('int').node, hard: false));
   }
 
+  test_part_metadata() async {
+    var pathContext = resourceProvider.pathContext;
+    addSource(pathContext.join(pathContext.dirname(testFile), 'part.dart'), '''
+part of test;
+''');
+    await analyze('''
+library test;
+@deprecated
+part 'part.dart';
+''');
+    // No assertions needed; the AnnotationTracker mixin verifies that the
+    // metadata was visited.
+  }
+
+  test_part_of_identifier() async {
+    var pathContext = resourceProvider.pathContext;
+    var testFileName = pathContext.basename(testFile);
+    addSource(pathContext.join(pathContext.dirname(testFile), 'lib.dart'), '''
+library test;
+part '$testFileName';
+''');
+    await analyze('''
+part of test;
+''');
+    // No assertions needed; the AnnotationTracker mixin verifies that the
+    // metadata was visited.
+  }
+
+  test_part_of_metadata() async {
+    var pathContext = resourceProvider.pathContext;
+    var testFileName = pathContext.basename(testFile);
+    addSource(pathContext.join(pathContext.dirname(testFile), 'lib.dart'), '''
+library test;
+part '$testFileName';
+''');
+    await analyze('''
+@deprecated
+part of test;
+''');
+    // No assertions needed; the AnnotationTracker mixin verifies that the
+    // metadata was visited.
+  }
+
+  test_part_of_path() async {
+    var pathContext = resourceProvider.pathContext;
+    var testFileName = pathContext.basename(testFile);
+    addSource(pathContext.join(pathContext.dirname(testFile), 'lib.dart'), '''
+part '$testFileName';
+''');
+    await analyze('''
+part of 'lib.dart';
+''');
+    // No assertions needed; the AnnotationTracker mixin verifies that the
+    // metadata was visited.
+  }
+
   test_postDominators_assert() async {
     await analyze('''
 void test(bool b1, bool b2, bool b3, bool _b) {