Index: pkg/analysis_server/lib/src/search/search_domain.dart |
diff --git a/pkg/analysis_server/lib/src/search/search_domain.dart b/pkg/analysis_server/lib/src/search/search_domain.dart |
index 804602a7aa8ae7534d77f84ef5020d0609b4ffd9..b23ef081d3ce10e801c536c9ccde846376c38803 100644 |
--- a/pkg/analysis_server/lib/src/search/search_domain.dart |
+++ b/pkg/analysis_server/lib/src/search/search_domain.dart |
@@ -6,12 +6,16 @@ library search.domain; |
import 'dart:async'; |
+import 'package:analysis_server/plugin/index/index_core.dart'; |
import 'package:analysis_server/src/analysis_server.dart'; |
import 'package:analysis_server/src/constants.dart'; |
import 'package:analysis_server/src/protocol_server.dart' as protocol; |
import 'package:analysis_server/src/search/element_references.dart'; |
import 'package:analysis_server/src/search/type_hierarchy.dart'; |
+import 'package:analysis_server/src/services/index/index.dart'; |
+import 'package:analysis_server/src/services/index/indexable_file.dart'; |
import 'package:analysis_server/src/services/search/search_engine.dart'; |
+import 'package:analyzer/src/generated/ast.dart'; |
import 'package:analyzer/src/generated/element.dart'; |
/** |
@@ -25,9 +29,14 @@ class SearchDomainHandler implements protocol.RequestHandler { |
final AnalysisServer server; |
/** |
+ * The [Index] for this server. |
+ */ |
+ final Index index; |
+ |
+ /** |
* The [SearchEngine] for this server. |
*/ |
- SearchEngine searchEngine; |
+ final SearchEngine searchEngine; |
/** |
* The next search response id. |
@@ -37,9 +46,10 @@ class SearchDomainHandler implements protocol.RequestHandler { |
/** |
* Initialize a newly created handler to handle requests for the given [server]. |
*/ |
- SearchDomainHandler(this.server) { |
- searchEngine = server.searchEngine; |
- } |
+ SearchDomainHandler(AnalysisServer server) |
+ : server = server, |
+ index = server.index, |
+ searchEngine = server.searchEngine; |
Future findElementReferences(protocol.Request request) async { |
var params = |
@@ -62,8 +72,40 @@ class SearchDomainHandler implements protocol.RequestHandler { |
}).where((Element element) { |
return element != null; |
}).toList(); |
- // search |
+ // prepare referenced file |
+ String referencedFile = _getFileReferencedAt(params.file, params.offset); |
+ if (referencedFile != null) { |
+ elements.removeWhere((e) => e is CompilationUnitElement); |
+ } |
+ // respond |
String searchId = (_nextSearchId++).toString(); |
+ var result = new protocol.SearchFindElementReferencesResult(); |
+ if (elements.isNotEmpty) { |
+ result.id = searchId; |
+ result.element = protocol.convertElement(elements.first); |
+ } else if (referencedFile != null) { |
+ result.id = searchId; |
+ result.element = |
+ new protocol.Element(protocol.ElementKind.FILE, referencedFile, 0); |
+ } |
+ _sendSearchResult(request, result); |
+ // search for file |
+ if (referencedFile != null) { |
+ List<Location> locations = await index.getRelationships( |
+ new IndexableFile(referencedFile), IndexConstants.IS_REFERENCED_BY); |
+ List<protocol.SearchResult> results = <protocol.SearchResult>[]; |
+ for (Location location in locations) { |
+ IndexableFile locationFile = location.indexable; |
+ results.add(new protocol.SearchResult( |
+ new protocol.Location( |
+ locationFile.path, location.offset, location.length, -1, -1), |
+ protocol.SearchResultKind.REFERENCE, |
+ false, |
+ [])); |
+ } |
+ _sendSearchNotification(searchId, elements.isEmpty, results); |
+ } |
+ // search elements |
elements.forEach((Element element) async { |
var computer = new ElementReferencesComputer(searchEngine); |
List<protocol.SearchResult> results = |
@@ -71,13 +113,6 @@ class SearchDomainHandler implements protocol.RequestHandler { |
bool isLast = identical(element, elements.last); |
_sendSearchNotification(searchId, isLast, results); |
}); |
- // respond |
- var result = new protocol.SearchFindElementReferencesResult(); |
- if (elements.isNotEmpty) { |
- result.id = searchId; |
- result.element = protocol.convertElement(elements[0]); |
- } |
- _sendSearchResult(request, result); |
} |
Future findMemberDeclarations(protocol.Request request) async { |
@@ -189,6 +224,31 @@ class SearchDomainHandler implements protocol.RequestHandler { |
return null; |
} |
+ /** |
+ * The the full path of the file referenced in the given [file] at the |
Brian Wilkerson
2015/10/20 14:57:15
"The the" --> "The"
|
+ * given [offset], maybe `null`. |
+ */ |
+ String _getFileReferencedAt(String file, int offset) { |
+ List<AstNode> nodes = server.getNodesAtOffset(file, offset); |
+ if (nodes.length == 1) { |
+ AstNode node = nodes.single; |
+ if (node is SimpleIdentifier && |
+ node.parent is LibraryIdentifier && |
+ node.parent.parent is LibraryDirective) { |
+ LibraryDirective libraryDirective = node.parent.parent; |
+ return libraryDirective?.element?.source?.fullName; |
+ } |
+ if (node is StringLiteral && node.parent is UriBasedDirective) { |
+ UriBasedDirective uriBasedDirective = node.parent; |
+ return uriBasedDirective.source?.fullName; |
+ } |
+ if (node is UriBasedDirective) { |
+ return node.source?.fullName; |
+ } |
+ } |
+ return null; |
+ } |
+ |
void _sendSearchNotification( |
String searchId, bool isLast, Iterable<protocol.SearchResult> results) { |
server.sendNotification( |