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 |