| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import 'dart:collection'; | 5 import 'dart:collection'; |
| 6 | 6 |
| 7 import 'package:analysis_server/protocol/protocol_generated.dart' as server; | 7 import 'package:analysis_server/protocol/protocol_generated.dart' as server; |
| 8 import 'package:analysis_server/src/channel/channel.dart'; | 8 import 'package:analysis_server/src/channel/channel.dart'; |
| 9 import 'package:analysis_server/src/plugin/result_collector.dart'; | 9 import 'package:analysis_server/src/plugin/result_collector.dart'; |
| 10 import 'package:analysis_server/src/plugin/result_converter.dart'; | 10 import 'package:analysis_server/src/plugin/result_converter.dart'; |
| 11 import 'package:analysis_server/src/plugin/result_merger.dart'; | 11 import 'package:analysis_server/src/plugin/result_merger.dart'; |
| 12 import 'package:analyzer/file_system/file_system.dart'; | 12 import 'package:analyzer/file_system/file_system.dart'; |
| 13 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin; | 13 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin; |
| 14 import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin; | 14 import 'package:analyzer_plugin/protocol/protocol_common.dart'; |
| 15 import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin; | 15 import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin; |
| 16 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; | 16 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; |
| 17 | 17 |
| 18 /** | 18 /** |
| 19 * The object used to coordinate the results of notifications from the analysis | 19 * The object used to coordinate the results of notifications from the analysis |
| 20 * server and multiple plugins. | 20 * server and multiple plugins. |
| 21 */ | 21 */ |
| 22 class NotificationManager { | 22 class NotificationManager { |
| 23 /** | 23 /** |
| 24 * The identifier used to identify results from the server. | 24 * The identifier used to identify results from the server. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 48 | 48 |
| 49 /** | 49 /** |
| 50 * The current set of subscriptions to which the client has subscribed. | 50 * The current set of subscriptions to which the client has subscribed. |
| 51 */ | 51 */ |
| 52 Map<server.AnalysisService, Set<String>> currentSubscriptions = | 52 Map<server.AnalysisService, Set<String>> currentSubscriptions = |
| 53 <server.AnalysisService, Set<String>>{}; | 53 <server.AnalysisService, Set<String>>{}; |
| 54 | 54 |
| 55 /** | 55 /** |
| 56 * The collector being used to collect the analysis errors from the plugins. | 56 * The collector being used to collect the analysis errors from the plugins. |
| 57 */ | 57 */ |
| 58 ResultCollector<List<server.AnalysisError>> errors; | 58 ResultCollector<List<AnalysisError>> errors; |
| 59 | 59 |
| 60 /** | 60 /** |
| 61 * The collector being used to collect the folding regions from the plugins. | 61 * The collector being used to collect the folding regions from the plugins. |
| 62 */ | 62 */ |
| 63 ResultCollector<List<server.FoldingRegion>> folding; | 63 ResultCollector<List<FoldingRegion>> folding; |
| 64 | 64 |
| 65 /** | 65 /** |
| 66 * The collector being used to collect the highlight regions from the plugins. | 66 * The collector being used to collect the highlight regions from the plugins. |
| 67 */ | 67 */ |
| 68 ResultCollector<List<server.HighlightRegion>> highlights; | 68 ResultCollector<List<HighlightRegion>> highlights; |
| 69 | 69 |
| 70 /** | 70 /** |
| 71 * The collector being used to collect the navigation parameters from the | 71 * The collector being used to collect the navigation parameters from the |
| 72 * plugins. | 72 * plugins. |
| 73 */ | 73 */ |
| 74 ResultCollector<server.AnalysisNavigationParams> navigation; | 74 ResultCollector<server.AnalysisNavigationParams> navigation; |
| 75 | 75 |
| 76 /** | 76 /** |
| 77 * The collector being used to collect the occurrences from the plugins. | 77 * The collector being used to collect the occurrences from the plugins. |
| 78 */ | 78 */ |
| 79 ResultCollector<List<server.Occurrences>> occurrences; | 79 ResultCollector<List<Occurrences>> occurrences; |
| 80 | 80 |
| 81 /** | 81 /** |
| 82 * The collector being used to collect the outlines from the plugins. | 82 * The collector being used to collect the outlines from the plugins. |
| 83 */ | 83 */ |
| 84 ResultCollector<List<server.Outline>> outlines; | 84 ResultCollector<List<Outline>> outlines; |
| 85 | 85 |
| 86 /** | 86 /** |
| 87 * The object used to convert results. | 87 * The object used to convert results. |
| 88 */ | 88 */ |
| 89 ResultConverter converter = new ResultConverter(); | 89 ResultConverter converter = new ResultConverter(); |
| 90 | 90 |
| 91 /** | 91 /** |
| 92 * The object used to merge results. | 92 * The object used to merge results. |
| 93 */ | 93 */ |
| 94 ResultMerger merger = new ResultMerger(); | 94 ResultMerger merger = new ResultMerger(); |
| 95 | 95 |
| 96 /** | 96 /** |
| 97 * Initialize a newly created notification manager. | 97 * Initialize a newly created notification manager. |
| 98 */ | 98 */ |
| 99 NotificationManager(this.channel, this.provider) { | 99 NotificationManager(this.channel, this.provider) { |
| 100 errors = new ResultCollector<List<server.AnalysisError>>(serverId, | 100 errors = new ResultCollector<List<AnalysisError>>(serverId, |
| 101 predicate: _isIncluded); | 101 predicate: _isIncluded); |
| 102 folding = new ResultCollector<List<server.FoldingRegion>>(serverId); | 102 folding = new ResultCollector<List<FoldingRegion>>(serverId); |
| 103 highlights = new ResultCollector<List<server.HighlightRegion>>(serverId); | 103 highlights = new ResultCollector<List<HighlightRegion>>(serverId); |
| 104 navigation = new ResultCollector<server.AnalysisNavigationParams>(serverId); | 104 navigation = new ResultCollector<server.AnalysisNavigationParams>(serverId); |
| 105 occurrences = new ResultCollector<List<server.Occurrences>>(serverId); | 105 occurrences = new ResultCollector<List<Occurrences>>(serverId); |
| 106 outlines = new ResultCollector<List<server.Outline>>(serverId); | 106 outlines = new ResultCollector<List<Outline>>(serverId); |
| 107 } | 107 } |
| 108 | 108 |
| 109 /** | 109 /** |
| 110 * Handle the given [notification] from the plugin with the given [pluginId]. | 110 * Handle the given [notification] from the plugin with the given [pluginId]. |
| 111 */ | 111 */ |
| 112 void handlePluginNotification( | 112 void handlePluginNotification( |
| 113 String pluginId, plugin.Notification notification) { | 113 String pluginId, plugin.Notification notification) { |
| 114 String event = notification.event; | 114 String event = notification.event; |
| 115 switch (event) { | 115 switch (event) { |
| 116 case plugin.ANALYSIS_NOTIFICATION_ERRORS: | 116 case plugin.ANALYSIS_NOTIFICATION_ERRORS: |
| 117 plugin.AnalysisErrorsParams params = | 117 plugin.AnalysisErrorsParams params = |
| 118 new plugin.AnalysisErrorsParams.fromNotification(notification); | 118 new plugin.AnalysisErrorsParams.fromNotification(notification); |
| 119 recordAnalysisErrors( | 119 recordAnalysisErrors(pluginId, params.file, params.errors); |
| 120 pluginId, | |
| 121 params.file, | |
| 122 params.errors | |
| 123 .map((plugin.AnalysisError error) => | |
| 124 converter.convertAnalysisError(error)) | |
| 125 .toList()); | |
| 126 break; | 120 break; |
| 127 case plugin.ANALYSIS_NOTIFICATION_FOLDING: | 121 case plugin.ANALYSIS_NOTIFICATION_FOLDING: |
| 128 plugin.AnalysisFoldingParams params = | 122 plugin.AnalysisFoldingParams params = |
| 129 new plugin.AnalysisFoldingParams.fromNotification(notification); | 123 new plugin.AnalysisFoldingParams.fromNotification(notification); |
| 130 recordFoldingRegions( | 124 recordFoldingRegions(pluginId, params.file, params.regions); |
| 131 pluginId, | |
| 132 params.file, | |
| 133 params.regions | |
| 134 .map((plugin.FoldingRegion region) => | |
| 135 converter.convertFoldingRegion(region)) | |
| 136 .toList()); | |
| 137 break; | 125 break; |
| 138 case plugin.ANALYSIS_NOTIFICATION_HIGHLIGHTS: | 126 case plugin.ANALYSIS_NOTIFICATION_HIGHLIGHTS: |
| 139 plugin.AnalysisHighlightsParams params = | 127 plugin.AnalysisHighlightsParams params = |
| 140 new plugin.AnalysisHighlightsParams.fromNotification(notification); | 128 new plugin.AnalysisHighlightsParams.fromNotification(notification); |
| 141 recordHighlightRegions( | 129 recordHighlightRegions(pluginId, params.file, params.regions); |
| 142 pluginId, | |
| 143 params.file, | |
| 144 params.regions | |
| 145 .map((plugin.HighlightRegion region) => | |
| 146 converter.convertHighlightRegion(region)) | |
| 147 .toList()); | |
| 148 break; | 130 break; |
| 149 case plugin.ANALYSIS_NOTIFICATION_NAVIGATION: | 131 case plugin.ANALYSIS_NOTIFICATION_NAVIGATION: |
| 150 plugin.AnalysisNavigationParams params = | 132 plugin.AnalysisNavigationParams params = |
| 151 new plugin.AnalysisNavigationParams.fromNotification(notification); | 133 new plugin.AnalysisNavigationParams.fromNotification(notification); |
| 152 recordNavigationParams(pluginId, params.file, | 134 recordNavigationParams(pluginId, params.file, |
| 153 converter.convertAnalysisNavigationParams(params)); | 135 converter.convertAnalysisNavigationParams(params)); |
| 154 break; | 136 break; |
| 155 case plugin.ANALYSIS_NOTIFICATION_OCCURRENCES: | 137 case plugin.ANALYSIS_NOTIFICATION_OCCURRENCES: |
| 156 plugin.AnalysisOccurrencesParams params = | 138 plugin.AnalysisOccurrencesParams params = |
| 157 new plugin.AnalysisOccurrencesParams.fromNotification(notification); | 139 new plugin.AnalysisOccurrencesParams.fromNotification(notification); |
| 158 recordOccurrences( | 140 recordOccurrences(pluginId, params.file, params.occurrences); |
| 159 pluginId, | |
| 160 params.file, | |
| 161 params.occurrences | |
| 162 .map((plugin.Occurrences occurrences) => | |
| 163 converter.convertOccurrences(occurrences)) | |
| 164 .toList()); | |
| 165 break; | 141 break; |
| 166 case plugin.ANALYSIS_NOTIFICATION_OUTLINE: | 142 case plugin.ANALYSIS_NOTIFICATION_OUTLINE: |
| 167 plugin.AnalysisOutlineParams params = | 143 plugin.AnalysisOutlineParams params = |
| 168 new plugin.AnalysisOutlineParams.fromNotification(notification); | 144 new plugin.AnalysisOutlineParams.fromNotification(notification); |
| 169 recordOutlines( | 145 recordOutlines(pluginId, params.file, params.outline); |
| 170 pluginId, | |
| 171 params.file, | |
| 172 params.outline | |
| 173 .map((plugin.Outline outline) => | |
| 174 converter.convertOutline(outline)) | |
| 175 .toList()); | |
| 176 break; | 146 break; |
| 177 case plugin.PLUGIN_NOTIFICATION_ERROR: | 147 case plugin.PLUGIN_NOTIFICATION_ERROR: |
| 178 plugin.PluginErrorParams params = | 148 plugin.PluginErrorParams params = |
| 179 new plugin.PluginErrorParams.fromNotification(notification); | 149 new plugin.PluginErrorParams.fromNotification(notification); |
| 180 // TODO(brianwilkerson) There is no indication for the client as to the | 150 // TODO(brianwilkerson) There is no indication for the client as to the |
| 181 // fact that the error came from a plugin, let alone which plugin it | 151 // fact that the error came from a plugin, let alone which plugin it |
| 182 // came from. We should consider whether we really want to send them to | 152 // came from. We should consider whether we really want to send them to |
| 183 // the client. | 153 // the client. |
| 184 channel.sendNotification(new server.ServerErrorParams( | 154 channel.sendNotification(new server.ServerErrorParams( |
| 185 params.isFatal, params.message, params.stackTrace) | 155 params.isFatal, params.message, params.stackTrace) |
| 186 .toNotification()); | 156 .toNotification()); |
| 187 break; | 157 break; |
| 188 } | 158 } |
| 189 } | 159 } |
| 190 | 160 |
| 191 /** | 161 /** |
| 192 * Record error information from the plugin with the given [pluginId] for the | 162 * Record error information from the plugin with the given [pluginId] for the |
| 193 * file with the given [filePath]. | 163 * file with the given [filePath]. |
| 194 */ | 164 */ |
| 195 void recordAnalysisErrors( | 165 void recordAnalysisErrors( |
| 196 String pluginId, String filePath, List<server.AnalysisError> errorData) { | 166 String pluginId, String filePath, List<AnalysisError> errorData) { |
| 197 if (errors.isCollectingFor(filePath)) { | 167 if (errors.isCollectingFor(filePath)) { |
| 198 errors.putResults(filePath, pluginId, errorData); | 168 errors.putResults(filePath, pluginId, errorData); |
| 199 List<List<server.AnalysisError>> unmergedErrors = | 169 List<List<AnalysisError>> unmergedErrors = errors.getResults(filePath); |
| 200 errors.getResults(filePath); | 170 List<AnalysisError> mergedErrors = |
| 201 List<server.AnalysisError> mergedErrors = | |
| 202 merger.mergeAnalysisErrors(unmergedErrors); | 171 merger.mergeAnalysisErrors(unmergedErrors); |
| 203 channel.sendNotification( | 172 channel.sendNotification( |
| 204 new server.AnalysisErrorsParams(filePath, mergedErrors) | 173 new server.AnalysisErrorsParams(filePath, mergedErrors) |
| 205 .toNotification()); | 174 .toNotification()); |
| 206 } | 175 } |
| 207 } | 176 } |
| 208 | 177 |
| 209 /** | 178 /** |
| 210 * Record folding information from the plugin with the given [pluginId] for | 179 * Record folding information from the plugin with the given [pluginId] for |
| 211 * the file with the given [filePath]. | 180 * the file with the given [filePath]. |
| 212 */ | 181 */ |
| 213 void recordFoldingRegions(String pluginId, String filePath, | 182 void recordFoldingRegions( |
| 214 List<server.FoldingRegion> foldingData) { | 183 String pluginId, String filePath, List<FoldingRegion> foldingData) { |
| 215 if (folding.isCollectingFor(filePath)) { | 184 if (folding.isCollectingFor(filePath)) { |
| 216 folding.putResults(filePath, pluginId, foldingData); | 185 folding.putResults(filePath, pluginId, foldingData); |
| 217 List<List<server.FoldingRegion>> unmergedFolding = | 186 List<List<FoldingRegion>> unmergedFolding = folding.getResults(filePath); |
| 218 folding.getResults(filePath); | 187 List<FoldingRegion> mergedFolding = |
| 219 List<server.FoldingRegion> mergedFolding = | |
| 220 merger.mergeFoldingRegions(unmergedFolding); | 188 merger.mergeFoldingRegions(unmergedFolding); |
| 221 channel.sendNotification( | 189 channel.sendNotification( |
| 222 new server.AnalysisFoldingParams(filePath, mergedFolding) | 190 new server.AnalysisFoldingParams(filePath, mergedFolding) |
| 223 .toNotification()); | 191 .toNotification()); |
| 224 } | 192 } |
| 225 } | 193 } |
| 226 | 194 |
| 227 /** | 195 /** |
| 228 * Record highlight information from the plugin with the given [pluginId] for | 196 * Record highlight information from the plugin with the given [pluginId] for |
| 229 * the file with the given [filePath]. | 197 * the file with the given [filePath]. |
| 230 */ | 198 */ |
| 231 void recordHighlightRegions(String pluginId, String filePath, | 199 void recordHighlightRegions( |
| 232 List<server.HighlightRegion> highlightData) { | 200 String pluginId, String filePath, List<HighlightRegion> highlightData) { |
| 233 if (highlights.isCollectingFor(filePath)) { | 201 if (highlights.isCollectingFor(filePath)) { |
| 234 highlights.putResults(filePath, pluginId, highlightData); | 202 highlights.putResults(filePath, pluginId, highlightData); |
| 235 List<List<server.HighlightRegion>> unmergedHighlights = | 203 List<List<HighlightRegion>> unmergedHighlights = |
| 236 highlights.getResults(filePath); | 204 highlights.getResults(filePath); |
| 237 List<server.HighlightRegion> mergedHighlights = | 205 List<HighlightRegion> mergedHighlights = |
| 238 merger.mergeHighlightRegions(unmergedHighlights); | 206 merger.mergeHighlightRegions(unmergedHighlights); |
| 239 channel.sendNotification( | 207 channel.sendNotification( |
| 240 new server.AnalysisHighlightsParams(filePath, mergedHighlights) | 208 new server.AnalysisHighlightsParams(filePath, mergedHighlights) |
| 241 .toNotification()); | 209 .toNotification()); |
| 242 } | 210 } |
| 243 } | 211 } |
| 244 | 212 |
| 245 /** | 213 /** |
| 246 * Record navigation information from the plugin with the given [pluginId] for | 214 * Record navigation information from the plugin with the given [pluginId] for |
| 247 * the file with the given [filePath]. | 215 * the file with the given [filePath]. |
| 248 */ | 216 */ |
| 249 void recordNavigationParams(String pluginId, String filePath, | 217 void recordNavigationParams(String pluginId, String filePath, |
| 250 server.AnalysisNavigationParams navigationData) { | 218 server.AnalysisNavigationParams navigationData) { |
| 251 if (navigation.isCollectingFor(filePath)) { | 219 if (navigation.isCollectingFor(filePath)) { |
| 252 navigation.putResults(filePath, pluginId, navigationData); | 220 navigation.putResults(filePath, pluginId, navigationData); |
| 253 List<server.AnalysisNavigationParams> unmergedNavigations = | 221 List<server.AnalysisNavigationParams> unmergedNavigations = |
| 254 navigation.getResults(filePath); | 222 navigation.getResults(filePath); |
| 255 server.AnalysisNavigationParams mergedNavigations = | 223 server.AnalysisNavigationParams mergedNavigations = |
| 256 merger.mergeNavigation(unmergedNavigations); | 224 merger.mergeNavigation(unmergedNavigations); |
| 257 channel.sendNotification(mergedNavigations.toNotification()); | 225 channel.sendNotification(mergedNavigations.toNotification()); |
| 258 } | 226 } |
| 259 } | 227 } |
| 260 | 228 |
| 261 /** | 229 /** |
| 262 * Record occurrences information from the plugin with the given [pluginId] | 230 * Record occurrences information from the plugin with the given [pluginId] |
| 263 * for the file with the given [filePath]. | 231 * for the file with the given [filePath]. |
| 264 */ | 232 */ |
| 265 void recordOccurrences(String pluginId, String filePath, | 233 void recordOccurrences( |
| 266 List<server.Occurrences> occurrencesData) { | 234 String pluginId, String filePath, List<Occurrences> occurrencesData) { |
| 267 if (occurrences.isCollectingFor(filePath)) { | 235 if (occurrences.isCollectingFor(filePath)) { |
| 268 occurrences.putResults(filePath, pluginId, occurrencesData); | 236 occurrences.putResults(filePath, pluginId, occurrencesData); |
| 269 List<List<server.Occurrences>> unmergedOccurrences = | 237 List<List<Occurrences>> unmergedOccurrences = |
| 270 occurrences.getResults(filePath); | 238 occurrences.getResults(filePath); |
| 271 List<server.Occurrences> mergedOccurrences = | 239 List<Occurrences> mergedOccurrences = |
| 272 merger.mergeOccurrences(unmergedOccurrences); | 240 merger.mergeOccurrences(unmergedOccurrences); |
| 273 channel.sendNotification( | 241 channel.sendNotification( |
| 274 new server.AnalysisOccurrencesParams(filePath, mergedOccurrences) | 242 new server.AnalysisOccurrencesParams(filePath, mergedOccurrences) |
| 275 .toNotification()); | 243 .toNotification()); |
| 276 } | 244 } |
| 277 } | 245 } |
| 278 | 246 |
| 279 /** | 247 /** |
| 280 * Record outline information from the plugin with the given [pluginId] for | 248 * Record outline information from the plugin with the given [pluginId] for |
| 281 * the file with the given [filePath]. | 249 * the file with the given [filePath]. |
| 282 */ | 250 */ |
| 283 void recordOutlines( | 251 void recordOutlines( |
| 284 String pluginId, String filePath, List<server.Outline> outlineData) { | 252 String pluginId, String filePath, List<Outline> outlineData) { |
| 285 if (outlines.isCollectingFor(filePath)) { | 253 if (outlines.isCollectingFor(filePath)) { |
| 286 outlines.putResults(filePath, pluginId, outlineData); | 254 outlines.putResults(filePath, pluginId, outlineData); |
| 287 List<List<server.Outline>> unmergedOutlines = | 255 List<List<Outline>> unmergedOutlines = outlines.getResults(filePath); |
| 288 outlines.getResults(filePath); | 256 List<Outline> mergedOutlines = merger.mergeOutline(unmergedOutlines); |
| 289 List<server.Outline> mergedOutlines = | |
| 290 merger.mergeOutline(unmergedOutlines); | |
| 291 channel.sendNotification(new server.AnalysisOutlineParams( | 257 channel.sendNotification(new server.AnalysisOutlineParams( |
| 292 filePath, server.FileKind.LIBRARY, mergedOutlines[0]) | 258 filePath, server.FileKind.LIBRARY, mergedOutlines[0]) |
| 293 .toNotification()); | 259 .toNotification()); |
| 294 } | 260 } |
| 295 } | 261 } |
| 296 | 262 |
| 297 /** | 263 /** |
| 298 * Set the lists of [included] and [excluded] files. | 264 * Set the lists of [included] and [excluded] files. |
| 299 */ | 265 */ |
| 300 void setAnalysisRoots(List<String> included, List<String> excluded) { | 266 void setAnalysisRoots(List<String> included, List<String> excluded) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 } | 356 } |
| 391 } | 357 } |
| 392 return false; | 358 return false; |
| 393 } | 359 } |
| 394 | 360 |
| 395 // TODO(brianwilkerson) Return false if error notifications are globally | 361 // TODO(brianwilkerson) Return false if error notifications are globally |
| 396 // disabled. | 362 // disabled. |
| 397 return isIncluded() && !isExcluded(); | 363 return isIncluded() && !isExcluded(); |
| 398 } | 364 } |
| 399 } | 365 } |
| OLD | NEW |