OLD | NEW |
---|---|
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library search.domain; | 5 library search.domain; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 | 8 |
9 import 'package:analysis_server/plugin/index/index_core.dart'; | |
9 import 'package:analysis_server/src/analysis_server.dart'; | 10 import 'package:analysis_server/src/analysis_server.dart'; |
10 import 'package:analysis_server/src/constants.dart'; | 11 import 'package:analysis_server/src/constants.dart'; |
11 import 'package:analysis_server/src/protocol_server.dart' as protocol; | 12 import 'package:analysis_server/src/protocol_server.dart' as protocol; |
12 import 'package:analysis_server/src/search/element_references.dart'; | 13 import 'package:analysis_server/src/search/element_references.dart'; |
13 import 'package:analysis_server/src/search/type_hierarchy.dart'; | 14 import 'package:analysis_server/src/search/type_hierarchy.dart'; |
15 import 'package:analysis_server/src/services/index/index.dart'; | |
16 import 'package:analysis_server/src/services/index/indexable_file.dart'; | |
14 import 'package:analysis_server/src/services/search/search_engine.dart'; | 17 import 'package:analysis_server/src/services/search/search_engine.dart'; |
18 import 'package:analyzer/src/generated/ast.dart'; | |
15 import 'package:analyzer/src/generated/element.dart'; | 19 import 'package:analyzer/src/generated/element.dart'; |
16 | 20 |
17 /** | 21 /** |
18 * Instances of the class [SearchDomainHandler] implement a [RequestHandler] | 22 * Instances of the class [SearchDomainHandler] implement a [RequestHandler] |
19 * that handles requests in the search domain. | 23 * that handles requests in the search domain. |
20 */ | 24 */ |
21 class SearchDomainHandler implements protocol.RequestHandler { | 25 class SearchDomainHandler implements protocol.RequestHandler { |
22 /** | 26 /** |
23 * The analysis server that is using this handler to process requests. | 27 * The analysis server that is using this handler to process requests. |
24 */ | 28 */ |
25 final AnalysisServer server; | 29 final AnalysisServer server; |
26 | 30 |
27 /** | 31 /** |
32 * The [Index] for this server. | |
33 */ | |
34 final Index index; | |
35 | |
36 /** | |
28 * The [SearchEngine] for this server. | 37 * The [SearchEngine] for this server. |
29 */ | 38 */ |
30 SearchEngine searchEngine; | 39 final SearchEngine searchEngine; |
31 | 40 |
32 /** | 41 /** |
33 * The next search response id. | 42 * The next search response id. |
34 */ | 43 */ |
35 int _nextSearchId = 0; | 44 int _nextSearchId = 0; |
36 | 45 |
37 /** | 46 /** |
38 * Initialize a newly created handler to handle requests for the given [server ]. | 47 * Initialize a newly created handler to handle requests for the given [server ]. |
39 */ | 48 */ |
40 SearchDomainHandler(this.server) { | 49 SearchDomainHandler(AnalysisServer server) |
41 searchEngine = server.searchEngine; | 50 : server = server, |
42 } | 51 index = server.index, |
52 searchEngine = server.searchEngine; | |
43 | 53 |
44 Future findElementReferences(protocol.Request request) async { | 54 Future findElementReferences(protocol.Request request) async { |
45 var params = | 55 var params = |
46 new protocol.SearchFindElementReferencesParams.fromRequest(request); | 56 new protocol.SearchFindElementReferencesParams.fromRequest(request); |
47 await server.onAnalysisComplete; | 57 await server.onAnalysisComplete; |
48 // prepare elements | 58 // prepare elements |
49 List<Element> elements = | 59 List<Element> elements = |
50 server.getElementsAtOffset(params.file, params.offset); | 60 server.getElementsAtOffset(params.file, params.offset); |
51 elements = elements.map((Element element) { | 61 elements = elements.map((Element element) { |
52 if (element is ImportElement) { | 62 if (element is ImportElement) { |
53 return element.prefix; | 63 return element.prefix; |
54 } | 64 } |
55 if (element is FieldFormalParameterElement) { | 65 if (element is FieldFormalParameterElement) { |
56 return element.field; | 66 return element.field; |
57 } | 67 } |
58 if (element is PropertyAccessorElement) { | 68 if (element is PropertyAccessorElement) { |
59 return element.variable; | 69 return element.variable; |
60 } | 70 } |
61 return element; | 71 return element; |
62 }).where((Element element) { | 72 }).where((Element element) { |
63 return element != null; | 73 return element != null; |
64 }).toList(); | 74 }).toList(); |
65 // search | 75 // prepare referenced file |
76 String referencedFile = _getFileReferencedAt(params.file, params.offset); | |
77 if (referencedFile != null) { | |
78 elements.removeWhere((e) => e is CompilationUnitElement); | |
79 } | |
80 // respond | |
66 String searchId = (_nextSearchId++).toString(); | 81 String searchId = (_nextSearchId++).toString(); |
82 var result = new protocol.SearchFindElementReferencesResult(); | |
83 if (elements.isNotEmpty) { | |
84 result.id = searchId; | |
85 result.element = protocol.convertElement(elements.first); | |
86 } else if (referencedFile != null) { | |
87 result.id = searchId; | |
88 result.element = | |
89 new protocol.Element(protocol.ElementKind.FILE, referencedFile, 0); | |
90 } | |
91 _sendSearchResult(request, result); | |
92 // search for file | |
93 if (referencedFile != null) { | |
94 List<Location> locations = await index.getRelationships( | |
95 new IndexableFile(referencedFile), IndexConstants.IS_REFERENCED_BY); | |
96 List<protocol.SearchResult> results = <protocol.SearchResult>[]; | |
97 for (Location location in locations) { | |
98 IndexableFile locationFile = location.indexable; | |
99 results.add(new protocol.SearchResult( | |
100 new protocol.Location( | |
101 locationFile.path, location.offset, location.length, -1, -1), | |
102 protocol.SearchResultKind.REFERENCE, | |
103 false, | |
104 [])); | |
105 } | |
106 _sendSearchNotification(searchId, elements.isEmpty, results); | |
107 } | |
108 // search elements | |
67 elements.forEach((Element element) async { | 109 elements.forEach((Element element) async { |
68 var computer = new ElementReferencesComputer(searchEngine); | 110 var computer = new ElementReferencesComputer(searchEngine); |
69 List<protocol.SearchResult> results = | 111 List<protocol.SearchResult> results = |
70 await computer.compute(element, params.includePotential); | 112 await computer.compute(element, params.includePotential); |
71 bool isLast = identical(element, elements.last); | 113 bool isLast = identical(element, elements.last); |
72 _sendSearchNotification(searchId, isLast, results); | 114 _sendSearchNotification(searchId, isLast, results); |
73 }); | 115 }); |
74 // respond | |
75 var result = new protocol.SearchFindElementReferencesResult(); | |
76 if (elements.isNotEmpty) { | |
77 result.id = searchId; | |
78 result.element = protocol.convertElement(elements[0]); | |
79 } | |
80 _sendSearchResult(request, result); | |
81 } | 116 } |
82 | 117 |
83 Future findMemberDeclarations(protocol.Request request) async { | 118 Future findMemberDeclarations(protocol.Request request) async { |
84 var params = | 119 var params = |
85 new protocol.SearchFindMemberDeclarationsParams.fromRequest(request); | 120 new protocol.SearchFindMemberDeclarationsParams.fromRequest(request); |
86 await server.onAnalysisComplete; | 121 await server.onAnalysisComplete; |
87 // respond | 122 // respond |
88 String searchId = (_nextSearchId++).toString(); | 123 String searchId = (_nextSearchId++).toString(); |
89 _sendSearchResult( | 124 _sendSearchResult( |
90 request, new protocol.SearchFindMemberDeclarationsResult(searchId)); | 125 request, new protocol.SearchFindMemberDeclarationsResult(searchId)); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
182 } else if (requestName == SEARCH_GET_TYPE_HIERARCHY) { | 217 } else if (requestName == SEARCH_GET_TYPE_HIERARCHY) { |
183 getTypeHierarchy(request); | 218 getTypeHierarchy(request); |
184 return protocol.Response.DELAYED_RESPONSE; | 219 return protocol.Response.DELAYED_RESPONSE; |
185 } | 220 } |
186 } on protocol.RequestFailure catch (exception) { | 221 } on protocol.RequestFailure catch (exception) { |
187 return exception.response; | 222 return exception.response; |
188 } | 223 } |
189 return null; | 224 return null; |
190 } | 225 } |
191 | 226 |
227 /** | |
228 * 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"
| |
229 * given [offset], maybe `null`. | |
230 */ | |
231 String _getFileReferencedAt(String file, int offset) { | |
232 List<AstNode> nodes = server.getNodesAtOffset(file, offset); | |
233 if (nodes.length == 1) { | |
234 AstNode node = nodes.single; | |
235 if (node is SimpleIdentifier && | |
236 node.parent is LibraryIdentifier && | |
237 node.parent.parent is LibraryDirective) { | |
238 LibraryDirective libraryDirective = node.parent.parent; | |
239 return libraryDirective?.element?.source?.fullName; | |
240 } | |
241 if (node is StringLiteral && node.parent is UriBasedDirective) { | |
242 UriBasedDirective uriBasedDirective = node.parent; | |
243 return uriBasedDirective.source?.fullName; | |
244 } | |
245 if (node is UriBasedDirective) { | |
246 return node.source?.fullName; | |
247 } | |
248 } | |
249 return null; | |
250 } | |
251 | |
192 void _sendSearchNotification( | 252 void _sendSearchNotification( |
193 String searchId, bool isLast, Iterable<protocol.SearchResult> results) { | 253 String searchId, bool isLast, Iterable<protocol.SearchResult> results) { |
194 server.sendNotification( | 254 server.sendNotification( |
195 new protocol.SearchResultsParams(searchId, results.toList(), isLast) | 255 new protocol.SearchResultsParams(searchId, results.toList(), isLast) |
196 .toNotification()); | 256 .toNotification()); |
197 } | 257 } |
198 | 258 |
199 /** | 259 /** |
200 * Send a search response with the given [result] to the given [request]. | 260 * Send a search response with the given [result] to the given [request]. |
201 */ | 261 */ |
202 void _sendSearchResult(protocol.Request request, result) { | 262 void _sendSearchResult(protocol.Request request, result) { |
203 protocol.Response response = result.toResponse(request.id); | 263 protocol.Response response = result.toResponse(request.id); |
204 server.sendResponse(response); | 264 server.sendResponse(response); |
205 } | 265 } |
206 | 266 |
207 void _sendTypeHierarchyNull(protocol.Request request) { | 267 void _sendTypeHierarchyNull(protocol.Request request) { |
208 protocol.Response response = | 268 protocol.Response response = |
209 new protocol.SearchGetTypeHierarchyResult().toResponse(request.id); | 269 new protocol.SearchGetTypeHierarchyResult().toResponse(request.id); |
210 server.sendResponse(response); | 270 server.sendResponse(response); |
211 } | 271 } |
212 | 272 |
213 static protocol.SearchResult toResult(SearchMatch match) { | 273 static protocol.SearchResult toResult(SearchMatch match) { |
214 return protocol.newSearchResult_fromMatch(match); | 274 return protocol.newSearchResult_fromMatch(match); |
215 } | 275 } |
216 } | 276 } |
OLD | NEW |