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