[analysis_server] Handle navigation for "part of"s using URIs

Fixes https://github.com/Dart-Code/Dart-Code/issues/3970.

Change-Id: I972f8811f0819d3018f36cb36ed796b8dafc1b3b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/245701
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/test/analysis/get_navigation_test.dart b/pkg/analysis_server/test/analysis/get_navigation_test.dart
index e0c55b0..e12cbc1 100644
--- a/pkg/analysis_server/test/analysis/get_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/get_navigation_test.dart
@@ -314,6 +314,64 @@
     }
   }
 
+  Future<void> test_partDirective() async {
+    final partFile = newFile(
+      '$testPackageLibPath/a.dart',
+      '''
+part of 'test.dart';
+''',
+    );
+    addTestFile('''
+part 'a.dart';
+''');
+    await waitForTasksFinished();
+    await _getNavigation(offset: 8, length: 0);
+    expect(regions, hasLength(1));
+    assertHasRegionString("'a.dart'");
+    expect(testTargets, hasLength(1));
+    expect(testTargets[0].kind, ElementKind.COMPILATION_UNIT);
+    assertHasFileTarget(partFile.path, 0, 0);
+  }
+
+  Future<void> test_partOfDirective_named() async {
+    final partOfFile = newFile(
+      '$testPackageLibPath/a.dart',
+      '''
+library foo;
+part 'test.dart';
+''',
+    );
+    addTestFile('''
+part of foo;
+''');
+    await waitForTasksFinished();
+    await _getNavigation(offset: 10, length: 0);
+    expect(regions, hasLength(1));
+    assertHasRegionString("foo");
+    expect(testTargets, hasLength(1));
+    expect(testTargets[0].kind, ElementKind.LIBRARY);
+    assertHasFileTarget(partOfFile.path, 8, 3); // library [[foo]]
+  }
+
+  Future<void> test_partOfDirective_uri() async {
+    final partOfFile = newFile(
+      '$testPackageLibPath/a.dart',
+      '''
+part 'test.dart';
+''',
+    );
+    addTestFile('''
+part of 'a.dart';
+''');
+    await waitForTasksFinished();
+    await _getNavigation(offset: 11, length: 0);
+    expect(regions, hasLength(1));
+    assertHasRegionString("'a.dart'");
+    expect(testTargets, hasLength(1));
+    expect(testTargets[0].kind, ElementKind.LIBRARY);
+    assertHasFileTarget(partOfFile.path, 0, 0);
+  }
+
   Future<void> test_zeroLength_end() async {
     addTestFile('''
 void f() {
diff --git a/pkg/analysis_server/test/lsp/definition_test.dart b/pkg/analysis_server/test/lsp/definition_test.dart
index 6f574ca..aa59e35 100644
--- a/pkg/analysis_server/test/lsp/definition_test.dart
+++ b/pkg/analysis_server/test/lsp/definition_test.dart
@@ -284,6 +284,46 @@
     );
   }
 
+  Future<void> test_partFilename() async {
+    final mainContents = '''
+part 'pa^rt.dart';
+    ''';
+
+    final partContents = '''
+part of 'main.dart';
+    ''';
+
+    final partFileUri = Uri.file(join(projectFolderPath, 'lib', 'part.dart'));
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(mainContents));
+    await openFile(partFileUri, withoutMarkers(partContents));
+    final res = await getDefinitionAsLocation(
+        mainFileUri, positionFromMarker(mainContents));
+
+    expect(res.single.uri, equals(partFileUri.toString()));
+  }
+
+  Future<void> test_partOfFilename() async {
+    final mainContents = '''
+part 'part.dart';
+    ''';
+
+    final partContents = '''
+part of 'ma^in.dart';
+    ''';
+
+    final partFileUri = Uri.file(join(projectFolderPath, 'lib', 'part.dart'));
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(mainContents));
+    await openFile(partFileUri, withoutMarkers(partContents));
+    final res = await getDefinitionAsLocation(
+        partFileUri, positionFromMarker(partContents));
+
+    expect(res.single.uri, equals(mainFileUri.toString()));
+  }
+
   Future<void> test_sameLine() async {
     final contents = '''
 int plusOne(int [[value]]) => 1 + val^ue;
diff --git a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
index 38053a2..38b8304 100644
--- a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
@@ -386,7 +386,7 @@
 
   @override
   void visitPartOfDirective(PartOfDirective node) {
-    computer._addRegionForNode(node.libraryName, node.element);
+    computer._addRegionForNode(node.libraryName ?? node.uri, node.element);
     super.visitPartOfDirective(node);
   }