Chromium Code Reviews| 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( |