Improve 'Import Library' code generation when has 'part' directive.

R=brianwilkerson@google.com

Change-Id: Idb3370dcbb67a935939a8ee2c072b897b866f7b0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/96826
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index e504aac..785a0f3 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -1266,11 +1266,14 @@
     // Prepare information about existing imports.
     LibraryDirective libraryDirective;
     List<ImportDirective> importDirectives = <ImportDirective>[];
+    PartDirective partDirective;
     for (Directive directive in unit.directives) {
       if (directive is LibraryDirective) {
         libraryDirective = directive;
       } else if (directive is ImportDirective) {
         importDirectives.add(directive);
+      } else if (directive is PartDirective) {
+        partDirective = directive;
       }
     }
 
@@ -1396,15 +1399,28 @@
     // Insert imports: after the library directive.
     if (libraryDirective != null) {
       addInsertion(libraryDirective.end, (EditBuilder builder) {
+        builder.writeln();
+        builder.writeln();
         for (int i = 0; i < importList.length; i++) {
           var import = importList[i];
-          if (i == 0) {
+          writeImport(builder, import);
+          if (i != importList.length - 1) {
             builder.writeln();
           }
-          builder.writeln();
+        }
+      });
+      return;
+    }
+
+    // Insert imports: before a part directive.
+    if (partDirective != null) {
+      addInsertion(partDirective.offset, (EditBuilder builder) {
+        for (int i = 0; i < importList.length; i++) {
+          var import = importList[i];
           writeImport(builder, import);
           builder.writeln();
         }
+        builder.writeln();
       });
       return;
     }
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index a3be8b8..5aae60f 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -1604,25 +1604,6 @@
 @reflectiveTest
 class ImportLibraryTest extends AbstractContextTest
     with DartChangeBuilderMixin {
-  test_afterLibraryDirective_dart() async {
-    await _assertImportLibrary(
-      initialCode: '''
-library test;
-
-class A {}
-''',
-      uriList: ['dart:async'],
-      expectedCode: '''
-library test;
-
-import 'dart:async';
-
-
-class A {}
-''',
-    );
-  }
-
   test_dart_beforeDart() async {
     await _assertImportLibrary(
       initialCode: '''
@@ -1765,6 +1746,58 @@
     );
   }
 
+  test_noImports_afterLibrary_hasDeclaration() async {
+    await _assertImportLibrary(
+      initialCode: '''
+library test;
+
+class A {}
+''',
+      uriList: ['dart:async'],
+      expectedCode: '''
+library test;
+
+import 'dart:async';
+
+class A {}
+''',
+    );
+  }
+
+  test_noImports_afterLibrary_hasPart() async {
+    await _assertImportLibrary(
+      initialCode: '''
+library test;
+
+part 'a.dart';
+''',
+      uriList: ['dart:aaa', 'dart:bbb'],
+      expectedCode: '''
+library test;
+
+import 'dart:aaa';
+import 'dart:bbb';
+
+part 'a.dart';
+''',
+    );
+  }
+
+  test_noImports_beforePart() async {
+    await _assertImportLibrary(
+      initialCode: '''
+part 'a.dart';
+''',
+      uriList: ['dart:aaa', 'dart:bbb'],
+      expectedCode: '''
+import 'dart:aaa';
+import 'dart:bbb';
+
+part 'a.dart';
+''',
+    );
+  }
+
   test_package_afterDart() async {
     await _assertImportLibrary(
       initialCode: '''
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
index 02e19d1..51cc21e 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
@@ -468,11 +468,9 @@
     );
   }
 
-  @failingTest
   test_shadowed_class_inPart() async {
     newFile('/home/test/lib/a.dart', content: 'class C {}');
     newFile('/home/test/lib/p.dart', content: 'class C {}');
-    // TODO(scheglov) "import" must be before "part"
     await _assertImportLibraryElement(
       initialCode: r'''
 part 'p.dart';