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'; | |
| 8 | |
| 7 import 'package:analysis_server/src/analysis_server.dart'; | 9 import 'package:analysis_server/src/analysis_server.dart'; |
| 8 import 'package:analysis_server/src/constants.dart'; | 10 import 'package:analysis_server/src/constants.dart'; |
| 9 import 'package:analysis_server/src/protocol_server.dart' as protocol; | 11 import 'package:analysis_server/src/protocol_server.dart' as protocol; |
| 10 import 'package:analysis_server/src/search/element_references.dart'; | 12 import 'package:analysis_server/src/search/element_references.dart'; |
| 11 import 'package:analysis_server/src/search/type_hierarchy.dart'; | 13 import 'package:analysis_server/src/search/type_hierarchy.dart'; |
| 12 import 'package:analysis_server/src/services/search/search_engine.dart'; | 14 import 'package:analysis_server/src/services/search/search_engine.dart'; |
| 13 import 'package:analyzer/src/generated/element.dart'; | 15 import 'package:analyzer/src/generated/element.dart'; |
| 14 | 16 |
| 15 /** | 17 /** |
| 16 * Instances of the class [SearchDomainHandler] implement a [RequestHandler] | 18 * Instances of the class [SearchDomainHandler] implement a [RequestHandler] |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 32 */ | 34 */ |
| 33 int _nextSearchId = 0; | 35 int _nextSearchId = 0; |
| 34 | 36 |
| 35 /** | 37 /** |
| 36 * Initialize a newly created handler to handle requests for the given [server ]. | 38 * Initialize a newly created handler to handle requests for the given [server ]. |
| 37 */ | 39 */ |
| 38 SearchDomainHandler(this.server) { | 40 SearchDomainHandler(this.server) { |
| 39 searchEngine = server.searchEngine; | 41 searchEngine = server.searchEngine; |
| 40 } | 42 } |
| 41 | 43 |
| 42 protocol.Response findElementReferences(protocol.Request request) { | 44 Future findElementReferences(protocol.Request request) async { |
| 43 var params = | 45 var params = |
| 44 new protocol.SearchFindElementReferencesParams.fromRequest(request); | 46 new protocol.SearchFindElementReferencesParams.fromRequest(request); |
| 47 await server.onAnalysisComplete; | |
|
Brian Wilkerson
2015/02/03 21:49:20
Do we also need to wait for indexing to be complet
scheglov
2015/02/03 21:51:19
We wait for all analysis operations, including ana
| |
| 45 // prepare elements | 48 // prepare elements |
| 46 List<Element> elements = | 49 List<Element> elements = |
| 47 server.getElementsAtOffset(params.file, params.offset); | 50 server.getElementsAtOffset(params.file, params.offset); |
| 48 elements = elements.map((Element element) { | 51 elements = elements.map((Element element) { |
| 49 if (element is ImportElement) { | 52 if (element is ImportElement) { |
| 50 return element.prefix; | 53 return element.prefix; |
| 51 } | 54 } |
| 52 if (element is FieldFormalParameterElement) { | 55 if (element is FieldFormalParameterElement) { |
| 53 return element.field; | 56 return element.field; |
| 54 } | 57 } |
| 55 if (element is PropertyAccessorElement) { | 58 if (element is PropertyAccessorElement) { |
| 56 return element.variable; | 59 return element.variable; |
| 57 } | 60 } |
| 58 return element; | 61 return element; |
| 59 }).where((Element element) { | 62 }).where((Element element) { |
| 60 return element != null; | 63 return element != null; |
| 61 }).toList(); | 64 }).toList(); |
| 62 // schedule search | 65 // search |
| 63 String searchId = (_nextSearchId++).toString(); | 66 String searchId = (_nextSearchId++).toString(); |
| 64 elements.forEach((Element element) { | 67 elements.forEach((Element element) async { |
| 65 var computer = new ElementReferencesComputer(searchEngine); | 68 var computer = new ElementReferencesComputer(searchEngine); |
| 66 var future = computer.compute(element, params.includePotential); | 69 List<protocol.SearchResult> results = |
| 67 future.then((List<protocol.SearchResult> results) { | 70 await computer.compute(element, params.includePotential); |
| 68 bool isLast = identical(element, elements.last); | 71 bool isLast = identical(element, elements.last); |
| 69 _sendSearchNotification(searchId, isLast, results); | 72 _sendSearchNotification(searchId, isLast, results); |
| 70 }); | |
| 71 }); | 73 }); |
| 72 // respond | 74 // respond |
| 73 var result = new protocol.SearchFindElementReferencesResult(); | 75 var result = new protocol.SearchFindElementReferencesResult(); |
| 74 if (elements.isNotEmpty) { | 76 if (elements.isNotEmpty) { |
| 75 result.id = searchId; | 77 result.id = searchId; |
| 76 result.element = protocol.newElement_fromEngine(elements[0]); | 78 result.element = protocol.newElement_fromEngine(elements[0]); |
| 77 } | 79 } |
| 78 return result.toResponse(request.id); | 80 _sendSearchResult(request, result); |
| 79 } | 81 } |
| 80 | 82 |
| 81 protocol.Response findMemberDeclarations(protocol.Request request) { | 83 Future findMemberDeclarations(protocol.Request request) async { |
| 82 var params = | 84 var params = |
| 83 new protocol.SearchFindMemberDeclarationsParams.fromRequest(request); | 85 new protocol.SearchFindMemberDeclarationsParams.fromRequest(request); |
| 84 // schedule search | 86 await server.onAnalysisComplete; |
| 87 // respond | |
| 85 String searchId = (_nextSearchId++).toString(); | 88 String searchId = (_nextSearchId++).toString(); |
| 86 { | 89 _sendSearchResult( |
| 87 var matchesFuture = searchEngine.searchMemberDeclarations(params.name); | 90 request, |
| 88 matchesFuture.then((List<SearchMatch> matches) { | 91 new protocol.SearchFindMemberDeclarationsResult(searchId)); |
| 89 _sendSearchNotification(searchId, true, matches.map(toResult)); | 92 // search |
| 90 }); | 93 List<SearchMatch> matches = |
| 91 } | 94 await searchEngine.searchMemberDeclarations(params.name); |
| 92 // respond | 95 _sendSearchNotification(searchId, true, matches.map(toResult)); |
| 93 return new protocol.SearchFindMemberDeclarationsResult( | |
| 94 searchId).toResponse(request.id); | |
| 95 } | 96 } |
| 96 | 97 |
| 97 protocol.Response findMemberReferences(protocol.Request request) { | 98 Future findMemberReferences(protocol.Request request) async { |
| 98 var params = | 99 var params = |
| 99 new protocol.SearchFindMemberReferencesParams.fromRequest(request); | 100 new protocol.SearchFindMemberReferencesParams.fromRequest(request); |
| 100 // schedule search | 101 await server.onAnalysisComplete; |
| 102 // respond | |
| 101 String searchId = (_nextSearchId++).toString(); | 103 String searchId = (_nextSearchId++).toString(); |
| 102 { | 104 _sendSearchResult( |
| 103 var matchesFuture = searchEngine.searchMemberReferences(params.name); | 105 request, |
| 104 matchesFuture.then((List<SearchMatch> matches) { | 106 new protocol.SearchFindMemberReferencesResult(searchId)); |
| 105 _sendSearchNotification(searchId, true, matches.map(toResult)); | 107 // search |
| 106 }); | 108 List<SearchMatch> matches = |
| 107 } | 109 await searchEngine.searchMemberReferences(params.name); |
| 108 // respond | 110 _sendSearchNotification(searchId, true, matches.map(toResult)); |
| 109 return new protocol.SearchFindMemberReferencesResult( | |
| 110 searchId).toResponse(request.id); | |
| 111 } | 111 } |
| 112 | 112 |
| 113 protocol.Response findTopLevelDeclarations(protocol.Request request) { | 113 Future findTopLevelDeclarations(protocol.Request request) async { |
| 114 var params = | 114 var params = |
| 115 new protocol.SearchFindTopLevelDeclarationsParams.fromRequest(request); | 115 new protocol.SearchFindTopLevelDeclarationsParams.fromRequest(request); |
| 116 // schedule search | 116 await server.onAnalysisComplete; |
| 117 // respond | |
| 117 String searchId = (_nextSearchId++).toString(); | 118 String searchId = (_nextSearchId++).toString(); |
| 118 { | 119 _sendSearchResult( |
| 119 var matchesFuture = | 120 request, |
| 120 searchEngine.searchTopLevelDeclarations(params.pattern); | 121 new protocol.SearchFindTopLevelDeclarationsResult(searchId)); |
| 121 matchesFuture.then((List<SearchMatch> matches) { | 122 // search |
| 122 _sendSearchNotification(searchId, true, matches.map(toResult)); | 123 List<SearchMatch> matches = |
| 123 }); | 124 await searchEngine.searchTopLevelDeclarations(params.pattern); |
| 124 } | 125 _sendSearchNotification(searchId, true, matches.map(toResult)); |
| 125 // respond | |
| 126 return new protocol.SearchFindTopLevelDeclarationsResult( | |
| 127 searchId).toResponse(request.id); | |
| 128 } | 126 } |
| 129 | 127 |
| 130 /** | 128 /** |
| 131 * Implement the `search.getTypeHierarchy` request. | 129 * Implement the `search.getTypeHierarchy` request. |
| 132 */ | 130 */ |
| 133 protocol.Response getTypeHierarchy(protocol.Request request) { | 131 Future getTypeHierarchy(protocol.Request request) async { |
| 134 var params = new protocol.SearchGetTypeHierarchyParams.fromRequest(request); | 132 var params = new protocol.SearchGetTypeHierarchyParams.fromRequest(request); |
| 133 await server.onAnalysisComplete; | |
| 135 // prepare parameters | 134 // prepare parameters |
| 136 // prepare Element | |
| 137 List<Element> elements = | 135 List<Element> elements = |
| 138 server.getElementsAtOffset(params.file, params.offset); | 136 server.getElementsAtOffset(params.file, params.offset); |
| 139 if (elements.isEmpty) { | 137 if (elements.isEmpty) { |
| 140 protocol.Response response = | 138 protocol.Response response = |
| 141 new protocol.SearchGetTypeHierarchyResult().toResponse(request.id); | 139 new protocol.SearchGetTypeHierarchyResult().toResponse(request.id); |
| 142 return response; | 140 server.sendResponse(response); |
| 143 } | 141 } |
| 144 Element element = elements.first; | 142 Element element = elements.first; |
| 145 // prepare type hierarchy | 143 // prepare type hierarchy |
| 146 TypeHierarchyComputer computer = new TypeHierarchyComputer(searchEngine); | 144 TypeHierarchyComputer computer = new TypeHierarchyComputer(searchEngine); |
| 147 computer.compute(element).then((List<protocol.TypeHierarchyItem> items) { | 145 List<protocol.TypeHierarchyItem> items = await computer.compute(element); |
| 148 protocol.Response response = new protocol.SearchGetTypeHierarchyResult( | 146 protocol.Response response = new protocol.SearchGetTypeHierarchyResult( |
| 149 hierarchyItems: items).toResponse(request.id); | 147 hierarchyItems: items).toResponse(request.id); |
| 150 server.sendResponse(response); | 148 server.sendResponse(response); |
| 151 }); | |
| 152 // delay response | |
| 153 return protocol.Response.DELAYED_RESPONSE; | |
| 154 } | 149 } |
| 155 | 150 |
| 156 @override | 151 @override |
| 157 protocol.Response handleRequest(protocol.Request request) { | 152 protocol.Response handleRequest(protocol.Request request) { |
| 158 try { | 153 try { |
| 159 String requestName = request.method; | 154 String requestName = request.method; |
| 160 if (requestName == SEARCH_FIND_ELEMENT_REFERENCES) { | 155 if (requestName == SEARCH_FIND_ELEMENT_REFERENCES) { |
| 161 return findElementReferences(request); | 156 findElementReferences(request); |
| 157 return protocol.Response.DELAYED_RESPONSE; | |
| 162 } else if (requestName == SEARCH_FIND_MEMBER_DECLARATIONS) { | 158 } else if (requestName == SEARCH_FIND_MEMBER_DECLARATIONS) { |
| 163 return findMemberDeclarations(request); | 159 findMemberDeclarations(request); |
| 160 return protocol.Response.DELAYED_RESPONSE; | |
| 164 } else if (requestName == SEARCH_FIND_MEMBER_REFERENCES) { | 161 } else if (requestName == SEARCH_FIND_MEMBER_REFERENCES) { |
| 165 return findMemberReferences(request); | 162 findMemberReferences(request); |
| 163 return protocol.Response.DELAYED_RESPONSE; | |
| 166 } else if (requestName == SEARCH_FIND_TOP_LEVEL_DECLARATIONS) { | 164 } else if (requestName == SEARCH_FIND_TOP_LEVEL_DECLARATIONS) { |
| 167 return findTopLevelDeclarations(request); | 165 findTopLevelDeclarations(request); |
| 166 return protocol.Response.DELAYED_RESPONSE; | |
| 168 } else if (requestName == SEARCH_GET_TYPE_HIERARCHY) { | 167 } else if (requestName == SEARCH_GET_TYPE_HIERARCHY) { |
| 169 return getTypeHierarchy(request); | 168 getTypeHierarchy(request); |
| 169 return protocol.Response.DELAYED_RESPONSE; | |
| 170 } | 170 } |
| 171 } on protocol.RequestFailure catch (exception) { | 171 } on protocol.RequestFailure catch (exception) { |
| 172 return exception.response; | 172 return exception.response; |
| 173 } | 173 } |
| 174 return null; | 174 return null; |
| 175 } | 175 } |
| 176 | 176 |
| 177 void _sendSearchNotification(String searchId, bool isLast, | 177 void _sendSearchNotification(String searchId, bool isLast, |
| 178 Iterable<protocol.SearchResult> results) { | 178 Iterable<protocol.SearchResult> results) { |
| 179 server.sendNotification( | 179 server.sendNotification( |
| 180 new protocol.SearchResultsParams( | 180 new protocol.SearchResultsParams( |
| 181 searchId, | 181 searchId, |
| 182 results.toList(), | 182 results.toList(), |
| 183 isLast).toNotification()); | 183 isLast).toNotification()); |
| 184 } | 184 } |
| 185 | 185 |
| 186 /** | |
| 187 * Send a search response with the given [result] to the given [request]. | |
| 188 */ | |
| 189 void _sendSearchResult(protocol.Request request, result) { | |
| 190 protocol.Response response = result.toResponse(request.id); | |
| 191 server.sendResponse(response); | |
| 192 } | |
| 193 | |
| 186 static protocol.SearchResult toResult(SearchMatch match) { | 194 static protocol.SearchResult toResult(SearchMatch match) { |
| 187 return protocol.newSearchResult_fromMatch(match); | 195 return protocol.newSearchResult_fromMatch(match); |
| 188 } | 196 } |
| 189 } | 197 } |
| OLD | NEW |