| 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 domain.completion; | 5 library domain.completion; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_server/src/analysis_server.dart'; | 9 import 'package:analysis_server/src/analysis_server.dart'; |
| 10 import 'package:analysis_server/src/constants.dart'; | 10 import 'package:analysis_server/src/constants.dart'; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 * The subscription for the cached context's source change stream. | 42 * The subscription for the cached context's source change stream. |
| 43 */ | 43 */ |
| 44 StreamSubscription<SourcesChangedEvent> _sourcesChangedSubscription; | 44 StreamSubscription<SourcesChangedEvent> _sourcesChangedSubscription; |
| 45 | 45 |
| 46 /** | 46 /** |
| 47 * Code completion peformance for the last completion operation. | 47 * Code completion peformance for the last completion operation. |
| 48 */ | 48 */ |
| 49 CompletionPerformance performance; | 49 CompletionPerformance performance; |
| 50 | 50 |
| 51 /** | 51 /** |
| 52 * A list of code completion peformance measurements for the latest |
| 53 * completion operation up to [performanceListMaxLength] measurements. |
| 54 */ |
| 55 final List<CompletionPerformance> performanceList = |
| 56 new List<CompletionPerformance>(); |
| 57 |
| 58 /** |
| 59 * The maximum number of performance measurements to keep. |
| 60 * This defaults to zero for efficiency, but clients may change this. |
| 61 */ |
| 62 int performanceListMaxLength = 0; |
| 63 |
| 64 /** |
| 65 * Performance for the last priority change event. |
| 66 */ |
| 67 CompletionPerformance priorityChangedPerformance; |
| 68 |
| 69 /** |
| 52 * Initialize a new request handler for the given [server]. | 70 * Initialize a new request handler for the given [server]. |
| 53 */ | 71 */ |
| 54 CompletionDomainHandler(this.server) { | 72 CompletionDomainHandler(this.server) { |
| 55 server.onContextsChanged.listen(contextsChanged); | 73 server.onContextsChanged.listen(contextsChanged); |
| 56 server.onPriorityChange.listen(priorityChanged); | 74 server.onPriorityChange.listen(priorityChanged); |
| 57 } | 75 } |
| 58 | 76 |
| 59 /** | 77 /** |
| 60 * Return the completion manager for most recent [Source] and [AnalysisContext
], | 78 * Return the completion manager for most recent [Source] and [AnalysisContext
], |
| 61 * or `null` if none. | 79 * or `null` if none. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 } | 130 } |
| 113 return null; | 131 return null; |
| 114 } | 132 } |
| 115 | 133 |
| 116 /** | 134 /** |
| 117 * If the set the priority files has changed, then pre-cache completion | 135 * If the set the priority files has changed, then pre-cache completion |
| 118 * information related to the first priority file. | 136 * information related to the first priority file. |
| 119 */ | 137 */ |
| 120 void priorityChanged(PriorityChangeEvent event) { | 138 void priorityChanged(PriorityChangeEvent event) { |
| 121 Source source = event.firstSource; | 139 Source source = event.firstSource; |
| 122 if (source == null) { | 140 priorityChangedPerformance = new CompletionPerformance(); |
| 123 return; | 141 priorityChangedPerformance.source = source; |
| 142 if (source != null) { |
| 143 AnalysisContext context = server.getAnalysisContextForSource(source); |
| 144 if (context != null) { |
| 145 String computeTag = 'computeCache'; |
| 146 priorityChangedPerformance.logStartTime(computeTag); |
| 147 CompletionManager manager = completionManagerFor(context, source); |
| 148 manager.computeCache().then((bool success) { |
| 149 priorityChangedPerformance.logElapseTime(computeTag); |
| 150 priorityChangedPerformance.complete( |
| 151 'priorityChanged caching: $success'); |
| 152 }); |
| 153 return; |
| 154 } |
| 124 } | 155 } |
| 125 AnalysisContext context = server.getAnalysisContextForSource(source); | 156 priorityChangedPerformance.complete(); |
| 126 if (context == null) { | |
| 127 return; | |
| 128 } | |
| 129 completionManagerFor(context, source).computeCache(); | |
| 130 } | 157 } |
| 131 | 158 |
| 132 /** | 159 /** |
| 133 * Process a `completion.getSuggestions` request. | 160 * Process a `completion.getSuggestions` request. |
| 134 */ | 161 */ |
| 135 Response processRequest(Request request) { | 162 Response processRequest(Request request) { |
| 136 performance = new CompletionPerformance(); | 163 performance = new CompletionPerformance(); |
| 137 // extract params | 164 // extract params |
| 138 CompletionGetSuggestionsParams params = | 165 CompletionGetSuggestionsParams params = |
| 139 new CompletionGetSuggestionsParams.fromRequest(request); | 166 new CompletionGetSuggestionsParams.fromRequest(request); |
| 140 // schedule completion analysis | 167 // schedule completion analysis |
| 141 String completionId = (_nextCompletionId++).toString(); | 168 String completionId = (_nextCompletionId++).toString(); |
| 142 CompletionManager manager = completionManagerFor( | 169 AnalysisContext context = server.getAnalysisContext(params.file); |
| 143 server.getAnalysisContext(params.file), | 170 Source source = server.getSource(params.file); |
| 144 server.getSource(params.file)); | 171 recordRequest(performance, context, source, params.offset); |
| 172 CompletionManager manager = completionManagerFor(context, source); |
| 145 CompletionRequest completionRequest = | 173 CompletionRequest completionRequest = |
| 146 new CompletionRequest(params.offset, performance); | 174 new CompletionRequest(params.offset, performance); |
| 175 int notificationCount = 0; |
| 147 manager.results(completionRequest).listen((CompletionResult result) { | 176 manager.results(completionRequest).listen((CompletionResult result) { |
| 148 sendCompletionNotification( | 177 ++notificationCount; |
| 149 completionId, | 178 performance.logElapseTime("notification $notificationCount", () { |
| 150 result.replacementOffset, | 179 sendCompletionNotification( |
| 151 result.replacementLength, | 180 completionId, |
| 152 result.suggestions, | 181 result.replacementOffset, |
| 153 result.last); | 182 result.replacementLength, |
| 183 result.suggestions, |
| 184 result.last); |
| 185 }); |
| 154 if (result.last) { | 186 if (result.last) { |
| 187 performance.notificationCount = notificationCount; |
| 188 performance.suggestionCount = result.suggestions.length; |
| 155 performance.complete(); | 189 performance.complete(); |
| 156 } | 190 } |
| 157 }); | 191 }); |
| 158 // initial response without results | 192 // initial response without results |
| 159 return new CompletionGetSuggestionsResult( | 193 return new CompletionGetSuggestionsResult( |
| 160 completionId).toResponse(request.id); | 194 completionId).toResponse(request.id); |
| 161 } | 195 } |
| 162 | 196 |
| 163 /** | 197 /** |
| 198 * If tracking code completion performance over time, then |
| 199 * record addition information about the request in the performance record. |
| 200 */ |
| 201 void recordRequest(CompletionPerformance performance, AnalysisContext context, |
| 202 Source source, int offset) { |
| 203 performance.source = source; |
| 204 performance.offset = offset; |
| 205 if (priorityChangedPerformance != null && |
| 206 priorityChangedPerformance.source != source) { |
| 207 priorityChangedPerformance = null; |
| 208 } |
| 209 if (performanceListMaxLength == 0 || context == null || source == null) { |
| 210 return; |
| 211 } |
| 212 TimestampedData<String> data = context.getContents(source); |
| 213 if (data == null) { |
| 214 return; |
| 215 } |
| 216 performance.contents = data.data; |
| 217 while (performanceList.length >= performanceListMaxLength) { |
| 218 performanceList.removeAt(0); |
| 219 } |
| 220 performanceList.add(performance); |
| 221 } |
| 222 |
| 223 /** |
| 164 * Send completion notification results. | 224 * Send completion notification results. |
| 165 */ | 225 */ |
| 166 void sendCompletionNotification(String completionId, int replacementOffset, | 226 void sendCompletionNotification(String completionId, int replacementOffset, |
| 167 int replacementLength, Iterable<CompletionSuggestion> results, bool isLast
) { | 227 int replacementLength, Iterable<CompletionSuggestion> results, bool isLast
) { |
| 168 server.sendNotification( | 228 server.sendNotification( |
| 169 new CompletionResultsParams( | 229 new CompletionResultsParams( |
| 170 completionId, | 230 completionId, |
| 171 replacementOffset, | 231 replacementOffset, |
| 172 replacementLength, | 232 replacementLength, |
| 173 results, | 233 results, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 201 * Discard the sourcesChanged subscription if any | 261 * Discard the sourcesChanged subscription if any |
| 202 */ | 262 */ |
| 203 void _discardManager() { | 263 void _discardManager() { |
| 204 if (_sourcesChangedSubscription != null) { | 264 if (_sourcesChangedSubscription != null) { |
| 205 _sourcesChangedSubscription.cancel(); | 265 _sourcesChangedSubscription.cancel(); |
| 206 _sourcesChangedSubscription = null; | 266 _sourcesChangedSubscription = null; |
| 207 } | 267 } |
| 208 _manager = null; | 268 _manager = null; |
| 209 } | 269 } |
| 210 } | 270 } |
| OLD | NEW |