Support for implemented classes/members in package files.

Note, that we remove getResolvedUnitObject() and replace it with
normal getIndex(). I think it was done initially this way because we
initiate sending implemented notification when analysis is finished
in analysis server. So, to avoid analysis-fisnished, send-implemented,
do-analysis, analysis-finished, send-implemented infinite sequence.

But getIndex() does not mark AnalysisDriver as requiring analysis.
So, we don't get infinite sequence of events.

R=brianwilkerson@google.com

Change-Id: Ibaf5be5c7a33edb938bd1a4670811dc200dee522
Reviewed-on: https://dart-review.googlesource.com/59500
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 1e10635..df71b24 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -748,23 +748,6 @@
   }
 
   /**
-   * Return the cached [AnalysisDriverResolvedUnit] for the file with the given
-   * [file], or `null` if the cache does not contain this information.
-   */
-  AnalysisDriverResolvedUnit getResolvedUnitObject(FileState file) {
-    FileState library = file.isPart ? file.library : file;
-    if (library != null) {
-      String signature = _getResolvedUnitSignature(library, file);
-      String key = _getResolvedUnitKey(signature);
-      List<int> bytes = _byteStore.get(key);
-      if (bytes != null) {
-        return new AnalysisDriverResolvedUnit.fromBuffer(bytes);
-      }
-    }
-    return null;
-  }
-
-  /**
    * Return a [Future] that completes with a [AnalysisResult] for the Dart
    * file with the given [path]. If the file is not a Dart file or cannot
    * be analyzed, the [Future] completes with `null`.
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index 9ab0b67..d308de5 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -377,13 +377,15 @@
       id = subtype.id;
     }
 
+    await _driver.discoverAvailableFiles();
+
     List<SubtypeResult> results = [];
-    for (String path in _driver.addedFiles) {
+    for (String path in _driver.knownFiles) {
       FileState file = _driver.fsState.getFileForPath(path);
       if (file.subtypedNames.contains(name)) {
-        AnalysisDriverResolvedUnit unit = _driver.getResolvedUnitObject(file);
-        if (unit != null) {
-          for (AnalysisDriverSubtype subtype in unit.index.subtypes) {
+        AnalysisDriverUnitIndex index = await _driver.getIndex(path);
+        if (index != null) {
+          for (AnalysisDriverSubtype subtype in index.subtypes) {
             if (subtype.supertypes.contains(id)) {
               FileState library = file.isPart ? file.library : file;
               results.add(new SubtypeResult(
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index 82570b6..d667f0e 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -1646,6 +1646,68 @@
     }
   }
 
+  test_subtypes_discover() async {
+    var pathT = _p('/test/lib/t.dart');
+    var pathA = _p('/aaa/lib/a.dart');
+    var pathB = _p('/bbb/lib/b.dart');
+
+    var tUri = 'package:test/t.dart';
+    var aUri = 'package:aaa/a.dart';
+    var bUri = 'package:bbb/b.dart';
+
+    provider.newFile(pathT, r'''
+import 'package:aaa/a.dart';
+
+class T1 extends A {
+  void method1() {}
+}
+
+class T2 extends A {
+  void method2() {}
+}
+''');
+
+    provider.newFile(pathB, r'''
+import 'package:aaa/a.dart';
+
+class B extends A {
+  void method1() {}
+}
+''');
+
+    provider.newFile(pathA, r'''
+class A {
+  void method1() {}
+  void method2() {}
+}
+''');
+
+    driver.addFile(pathT);
+
+    var aLibrary = await driver.getLibraryByUri(aUri);
+    ClassElement aClass = aLibrary.getType('A');
+
+    // Search by 'type'.
+    List<SubtypeResult> subtypes = await driver.search.subtypes(type: aClass);
+    expect(subtypes, hasLength(3));
+
+    SubtypeResult t1 = subtypes.singleWhere((r) => r.name == 'T1');
+    SubtypeResult t2 = subtypes.singleWhere((r) => r.name == 'T2');
+    SubtypeResult b = subtypes.singleWhere((r) => r.name == 'B');
+
+    expect(t1.libraryUri, tUri);
+    expect(t1.id, '$tUri;$tUri;T1');
+    expect(t1.members, ['method1']);
+
+    expect(t2.libraryUri, tUri);
+    expect(t2.id, '$tUri;$tUri;T2');
+    expect(t2.members, ['method2']);
+
+    expect(b.libraryUri, bUri);
+    expect(b.id, '$bUri;$bUri;B');
+    expect(b.members, ['method1']);
+  }
+
   test_subTypes_discover() async {
     var t = _p('/test/lib/t.dart');
     var a = _p('/aaa/lib/a.dart');