| 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:async'; | 5 import 'dart:async'; | 
| 6 import 'dart:collection'; | 6 import 'dart:collection'; | 
| 7 import 'dart:io' show Platform; | 7 import 'dart:io' show Platform; | 
| 8 | 8 | 
| 9 import 'package:analysis_server/src/plugin/notification_manager.dart'; | 9 import 'package:analysis_server/src/plugin/notification_manager.dart'; | 
|  | 10 import 'package:analyzer/context/context_root.dart' as analyzer; | 
| 10 import 'package:analyzer/file_system/file_system.dart'; | 11 import 'package:analyzer/file_system/file_system.dart'; | 
| 11 import 'package:analyzer/instrumentation/instrumentation.dart'; | 12 import 'package:analyzer/instrumentation/instrumentation.dart'; | 
| 12 import 'package:analyzer/src/generated/bazel.dart'; | 13 import 'package:analyzer/src/generated/bazel.dart'; | 
| 13 import 'package:analyzer/src/generated/gn.dart'; | 14 import 'package:analyzer/src/generated/gn.dart'; | 
| 14 import 'package:analyzer_plugin/channel/channel.dart'; | 15 import 'package:analyzer_plugin/channel/channel.dart'; | 
| 15 import 'package:analyzer_plugin/protocol/protocol.dart'; | 16 import 'package:analyzer_plugin/protocol/protocol.dart'; | 
| 16 import 'package:analyzer_plugin/protocol/protocol_generated.dart'; | 17 import 'package:analyzer_plugin/protocol/protocol_generated.dart'; | 
| 17 import 'package:analyzer_plugin/src/channel/isolate_channel.dart'; | 18 import 'package:analyzer_plugin/src/channel/isolate_channel.dart'; | 
| 18 import 'package:analyzer_plugin/src/protocol/protocol_internal.dart'; | 19 import 'package:analyzer_plugin/src/protocol/protocol_internal.dart'; | 
| 19 import 'package:convert/convert.dart'; | 20 import 'package:convert/convert.dart'; | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
| 50 | 51 | 
| 51   /** | 52   /** | 
| 52    * The instrumentation service that is being used by the analysis server. | 53    * The instrumentation service that is being used by the analysis server. | 
| 53    */ | 54    */ | 
| 54   final InstrumentationService instrumentationService; | 55   final InstrumentationService instrumentationService; | 
| 55 | 56 | 
| 56   /** | 57   /** | 
| 57    * The context roots that are currently using the results produced by the | 58    * The context roots that are currently using the results produced by the | 
| 58    * plugin. | 59    * plugin. | 
| 59    */ | 60    */ | 
| 60   Set<ContextRoot> contextRoots = new HashSet<ContextRoot>(); | 61   Set<analyzer.ContextRoot> contextRoots = new HashSet<analyzer.ContextRoot>(); | 
| 61 | 62 | 
| 62   /** | 63   /** | 
| 63    * The current execution of the plugin, or `null` if the plugin is not | 64    * The current execution of the plugin, or `null` if the plugin is not | 
| 64    * currently being executed. | 65    * currently being executed. | 
| 65    */ | 66    */ | 
| 66   PluginSession currentSession; | 67   PluginSession currentSession; | 
| 67 | 68 | 
| 68   /** | 69   /** | 
| 69    * Initialize the newly created information about a plugin. | 70    * Initialize the newly created information about a plugin. | 
| 70    */ | 71    */ | 
| 71   PluginInfo(this.path, this.executionPath, this.packagesPath, | 72   PluginInfo(this.path, this.executionPath, this.packagesPath, | 
| 72       this.notificationManager, this.instrumentationService); | 73       this.notificationManager, this.instrumentationService); | 
| 73 | 74 | 
| 74   /** | 75   /** | 
| 75    * Add the given [contextRoot] to the set of context roots being analyzed by | 76    * Add the given [contextRoot] to the set of context roots being analyzed by | 
| 76    * this plugin. | 77    * this plugin. | 
| 77    */ | 78    */ | 
| 78   void addContextRoot(ContextRoot contextRoot) { | 79   void addContextRoot(analyzer.ContextRoot contextRoot) { | 
| 79     if (contextRoots.add(contextRoot)) { | 80     if (contextRoots.add(contextRoot)) { | 
| 80       _updatePluginRoots(); | 81       _updatePluginRoots(); | 
| 81     } | 82     } | 
| 82   } | 83   } | 
| 83 | 84 | 
| 84   /** | 85   /** | 
| 85    * Remove the given [contextRoot] from the set of context roots being analyzed | 86    * Remove the given [contextRoot] from the set of context roots being analyzed | 
| 86    * by this plugin. | 87    * by this plugin. | 
| 87    */ | 88    */ | 
| 88   void removeContextRoot(ContextRoot contextRoot) { | 89   void removeContextRoot(analyzer.ContextRoot contextRoot) { | 
| 89     if (contextRoots.remove(contextRoot)) { | 90     if (contextRoots.remove(contextRoot)) { | 
| 90       _updatePluginRoots(); | 91       _updatePluginRoots(); | 
| 91     } | 92     } | 
| 92   } | 93   } | 
| 93 | 94 | 
| 94   /** | 95   /** | 
| 95    * Start a new isolate that is running the plugin. Return the state object | 96    * Start a new isolate that is running the plugin. Return the state object | 
| 96    * used to interact with the plugin. | 97    * used to interact with the plugin. | 
| 97    */ | 98    */ | 
| 98   Future<PluginSession> start(String byteStorePath) async { | 99   Future<PluginSession> start(String byteStorePath) async { | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 114     Future<Null> doneFuture = currentSession.stop(); | 115     Future<Null> doneFuture = currentSession.stop(); | 
| 115     currentSession = null; | 116     currentSession = null; | 
| 116     return doneFuture; | 117     return doneFuture; | 
| 117   } | 118   } | 
| 118 | 119 | 
| 119   /** | 120   /** | 
| 120    * Update the context roots that the plugin should be analyzing. | 121    * Update the context roots that the plugin should be analyzing. | 
| 121    */ | 122    */ | 
| 122   void _updatePluginRoots() { | 123   void _updatePluginRoots() { | 
| 123     if (currentSession != null) { | 124     if (currentSession != null) { | 
| 124       AnalysisSetContextRootsParams params = | 125       AnalysisSetContextRootsParams params = new AnalysisSetContextRootsParams( | 
| 125           new AnalysisSetContextRootsParams(contextRoots.toList()); | 126           contextRoots | 
|  | 127               .map((analyzer.ContextRoot contextRoot) => | 
|  | 128                   new ContextRoot(contextRoot.root, contextRoot.exclude)) | 
|  | 129               .toList()); | 
| 126       currentSession.sendRequest(params); | 130       currentSession.sendRequest(params); | 
| 127     } | 131     } | 
| 128   } | 132   } | 
| 129 } | 133 } | 
| 130 | 134 | 
| 131 /** | 135 /** | 
| 132  * An object used to manage the currently running plugins. | 136  * An object used to manage the currently running plugins. | 
| 133  */ | 137  */ | 
| 134 class PluginManager { | 138 class PluginManager { | 
| 135   /** | 139   /** | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
| 164    */ | 168    */ | 
| 165   PluginManager(this.resourceProvider, this.byteStorePath, | 169   PluginManager(this.resourceProvider, this.byteStorePath, | 
| 166       this.notificationManager, this.instrumentationService); | 170       this.notificationManager, this.instrumentationService); | 
| 167 | 171 | 
| 168   /** | 172   /** | 
| 169    * Add the plugin with the given [path] to the list of plugins that should be | 173    * Add the plugin with the given [path] to the list of plugins that should be | 
| 170    * used when analyzing code for the given [contextRoot]. If the plugin had not | 174    * used when analyzing code for the given [contextRoot]. If the plugin had not | 
| 171    * yet been started, then it will be started by this method. | 175    * yet been started, then it will be started by this method. | 
| 172    */ | 176    */ | 
| 173   Future<Null> addPluginToContextRoot( | 177   Future<Null> addPluginToContextRoot( | 
| 174       ContextRoot contextRoot, String path) async { | 178       analyzer.ContextRoot contextRoot, String path) async { | 
| 175     PluginInfo plugin = _pluginMap[path]; | 179     PluginInfo plugin = _pluginMap[path]; | 
| 176     if (plugin == null) { | 180     if (plugin == null) { | 
| 177       List<String> pluginPaths = _pathsFor(path); | 181       List<String> pluginPaths = _pathsFor(path); | 
| 178       plugin = new PluginInfo(path, pluginPaths[0], pluginPaths[1], | 182       plugin = new PluginInfo(path, pluginPaths[0], pluginPaths[1], | 
| 179           notificationManager, instrumentationService); | 183           notificationManager, instrumentationService); | 
| 180       _pluginMap[path] = plugin; | 184       _pluginMap[path] = plugin; | 
| 181       if (pluginPaths[0] != null) { | 185       if (pluginPaths[0] != null) { | 
| 182         PluginSession session = await plugin.start(byteStorePath); | 186         PluginSession session = await plugin.start(byteStorePath); | 
| 183         session.onDone.then((_) { | 187         session.onDone.then((_) { | 
| 184           _pluginMap.remove(path); | 188           _pluginMap.remove(path); | 
| 185         }); | 189         }); | 
| 186       } | 190       } | 
| 187     } | 191     } | 
| 188     plugin.addContextRoot(contextRoot); | 192     plugin.addContextRoot(contextRoot); | 
| 189   } | 193   } | 
| 190 | 194 | 
| 191   /** | 195   /** | 
| 192    * Broadcast a request built from the given [params] to all of the plugins | 196    * Broadcast a request built from the given [params] to all of the plugins | 
| 193    * that are currently associated with the given [contextRoot]. Return a list | 197    * that are currently associated with the given [contextRoot]. Return a list | 
| 194    * containing futures that will complete when each of the plugins have sent a | 198    * containing futures that will complete when each of the plugins have sent a | 
| 195    * response. | 199    * response. | 
| 196    */ | 200    */ | 
| 197   List<Future<Response>> broadcast( | 201   List<Future<Response>> broadcast( | 
| 198       ContextRoot contextRoot, RequestParams params) { | 202       analyzer.ContextRoot contextRoot, RequestParams params) { | 
| 199     List<PluginInfo> plugins = pluginsForContextRoot(contextRoot); | 203     List<PluginInfo> plugins = pluginsForContextRoot(contextRoot); | 
| 200     return plugins | 204     return plugins | 
| 201         .map((PluginInfo plugin) => plugin.currentSession?.sendRequest(params)) | 205         .map((PluginInfo plugin) => plugin.currentSession?.sendRequest(params)) | 
| 202         .toList(); | 206         .toList(); | 
| 203   } | 207   } | 
| 204 | 208 | 
| 205   /** | 209   /** | 
| 206    * Return a list of all of the plugins that are currently associated with the | 210    * Return a list of all of the plugins that are currently associated with the | 
| 207    * given [contextRoot]. | 211    * given [contextRoot]. | 
| 208    */ | 212    */ | 
| 209   @visibleForTesting | 213   @visibleForTesting | 
| 210   List<PluginInfo> pluginsForContextRoot(ContextRoot contextRoot) { | 214   List<PluginInfo> pluginsForContextRoot(analyzer.ContextRoot contextRoot) { | 
| 211     List<PluginInfo> plugins = <PluginInfo>[]; | 215     List<PluginInfo> plugins = <PluginInfo>[]; | 
| 212     for (PluginInfo plugin in _pluginMap.values) { | 216     for (PluginInfo plugin in _pluginMap.values) { | 
| 213       if (plugin.contextRoots.contains(contextRoot)) { | 217       if (plugin.contextRoots.contains(contextRoot)) { | 
| 214         plugins.add(plugin); | 218         plugins.add(plugin); | 
| 215       } | 219       } | 
| 216     } | 220     } | 
| 217     return plugins; | 221     return plugins; | 
| 218   } | 222   } | 
| 219 | 223 | 
| 220   /** | 224   /** | 
| 221    * The given [contextRoot] is no longer being analyzed. | 225    * The given [contextRoot] is no longer being analyzed. | 
| 222    */ | 226    */ | 
| 223   void removedContextRoot(ContextRoot contextRoot) { | 227   void removedContextRoot(analyzer.ContextRoot contextRoot) { | 
| 224     List<PluginInfo> plugins = _pluginMap.values.toList(); | 228     List<PluginInfo> plugins = _pluginMap.values.toList(); | 
| 225     for (PluginInfo plugin in plugins) { | 229     for (PluginInfo plugin in plugins) { | 
| 226       plugin.removeContextRoot(contextRoot); | 230       plugin.removeContextRoot(contextRoot); | 
| 227       if (plugin.contextRoots.isEmpty) { | 231       if (plugin.contextRoots.isEmpty) { | 
| 228         _pluginMap.remove(plugin.path); | 232         _pluginMap.remove(plugin.path); | 
| 229         plugin.stop(); | 233         plugin.stop(); | 
| 230       } | 234       } | 
| 231     } | 235     } | 
| 232   } | 236   } | 
| 233 | 237 | 
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 490   Future<Null> stop() { | 494   Future<Null> stop() { | 
| 491     if (channel == null) { | 495     if (channel == null) { | 
| 492       throw new StateError('Cannot stop a plugin that is not running.'); | 496       throw new StateError('Cannot stop a plugin that is not running.'); | 
| 493     } | 497     } | 
| 494     // TODO(brianwilkerson) Ensure that the isolate is killed if it does not | 498     // TODO(brianwilkerson) Ensure that the isolate is killed if it does not | 
| 495     // terminate normally. | 499     // terminate normally. | 
| 496     sendRequest(new PluginShutdownParams()); | 500     sendRequest(new PluginShutdownParams()); | 
| 497     return pluginStoppedCompleter.future; | 501     return pluginStoppedCompleter.future; | 
| 498   } | 502   } | 
| 499 } | 503 } | 
| OLD | NEW | 
|---|