| Index: pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
|
| diff --git a/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart b/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
|
| index 8aa8f72b25d2fc119bb9da4640337788f1448cb1..65c33cd445686076c75834359a46c507df3d7f23 100644
|
| --- a/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
|
| +++ b/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
|
| @@ -12,6 +12,74 @@ import 'package:analyzer_plugin/protocol/protocol.dart';
|
| import 'package:analyzer_plugin/protocol/protocol_generated.dart';
|
|
|
| /**
|
| + * The type of the function used to run a built-in plugin in an isolate.
|
| + */
|
| +typedef void EntryPoint(SendPort sendPort);
|
| +
|
| +/**
|
| + * A communication channel appropriate for built-in plugins.
|
| + */
|
| +class BuiltInServerIsolateChannel extends ServerIsolateChannel {
|
| + /**
|
| + * The entry point
|
| + */
|
| + final EntryPoint entryPoint;
|
| +
|
| + @override
|
| + final String pluginId;
|
| +
|
| + /**
|
| + * Initialize a newly created channel to communicate with an isolate running
|
| + * the given [entryPoint].
|
| + */
|
| + BuiltInServerIsolateChannel(this.entryPoint, this.pluginId,
|
| + InstrumentationService instrumentationService)
|
| + : super._(instrumentationService);
|
| +
|
| + @override
|
| + Future<Isolate> _spawnIsolate() {
|
| + return Isolate.spawn(entryPoint, _receivePort.sendPort,
|
| + onError: _errorPort?.sendPort, onExit: _exitPort?.sendPort);
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * A communication channel appropriate for discovered plugins.
|
| + */
|
| +class DiscoveredServerIsolateChannel extends ServerIsolateChannel {
|
| + /**
|
| + * The URI for the Dart file that will be run in the isolate that this channel
|
| + * communicates with.
|
| + */
|
| + final Uri pluginUri;
|
| +
|
| + /**
|
| + * The URI for the '.packages' file that will control how 'package:' URIs are
|
| + * resolved.
|
| + */
|
| + final Uri packagesUri;
|
| +
|
| + /**
|
| + * Initialize a newly created channel to communicate with an isolate running
|
| + * the code at the given [uri].
|
| + */
|
| + DiscoveredServerIsolateChannel(this.pluginUri, this.packagesUri,
|
| + InstrumentationService instrumentationService)
|
| + : super._(instrumentationService);
|
| +
|
| + @override
|
| + String get pluginId => pluginUri.toString();
|
| +
|
| + @override
|
| + Future<Isolate> _spawnIsolate() {
|
| + return Isolate.spawnUri(pluginUri, <String>[], _receivePort.sendPort,
|
| + onError: _errorPort?.sendPort,
|
| + onExit: _exitPort?.sendPort,
|
| + packageConfig: packagesUri);
|
| + }
|
| +}
|
| +
|
| +/**
|
| * The object that allows a [ServerPlugin] to receive [Request]s and to return
|
| * both [Response]s and [Notification]s. It communicates with the analysis
|
| * server by passing data to the server's main isolate.
|
| @@ -83,22 +151,10 @@ class PluginIsolateChannel implements PluginCommunicationChannel {
|
| }
|
|
|
| /**
|
| - * The communication channel that allows an analysis server to send [Request]s
|
| + * A communication channel that allows an analysis server to send [Request]s
|
| * to, and to receive both [Response]s and [Notification]s from, a plugin.
|
| */
|
| -class ServerIsolateChannel implements ServerCommunicationChannel {
|
| - /**
|
| - * The URI for the Dart file that will be run in the isolate that this channel
|
| - * communicates with.
|
| - */
|
| - final Uri pluginUri;
|
| -
|
| - /**
|
| - * The URI for the '.packages' file that will control how 'package:' URIs are
|
| - * resolved.
|
| - */
|
| - final Uri packagesUri;
|
| -
|
| +abstract class ServerIsolateChannel implements ServerCommunicationChannel {
|
| /**
|
| * The instrumentation service that is being used by the analysis server.
|
| */
|
| @@ -132,11 +188,32 @@ class ServerIsolateChannel implements ServerCommunicationChannel {
|
| ReceivePort _exitPort;
|
|
|
| /**
|
| - * Initialize a newly created channel to communicate with an isolate running
|
| - * the code at the given [uri].
|
| + * Return a communication channel appropriate for communicating with a
|
| + * built-in plugin.
|
| */
|
| - ServerIsolateChannel(
|
| - this.pluginUri, this.packagesUri, this.instrumentationService);
|
| + factory ServerIsolateChannel.builtIn(EntryPoint entryPoint, String pluginId,
|
| + InstrumentationService instrumentationService) =
|
| + BuiltInServerIsolateChannel;
|
| +
|
| + /**
|
| + * Return a communication channel appropriate for communicating with a
|
| + * discovered plugin.
|
| + */
|
| + factory ServerIsolateChannel.discovered(Uri pluginUri, Uri packagesUri,
|
| + InstrumentationService instrumentationService) =
|
| + DiscoveredServerIsolateChannel;
|
| +
|
| + /**
|
| + * Initialize a newly created channel.
|
| + */
|
| + ServerIsolateChannel._(this.instrumentationService);
|
| +
|
| + /**
|
| + * Return the id of the plugin running in the isolate, used to identify the
|
| + * plugin to the instrumentation service.
|
| + */
|
| + String get pluginId;
|
| +
|
| @override
|
| void close() {
|
| _receivePort?.close();
|
| @@ -166,14 +243,10 @@ class ServerIsolateChannel implements ServerCommunicationChannel {
|
| });
|
| }
|
| try {
|
| - _isolate = await Isolate.spawnUri(
|
| - pluginUri, <String>[], _receivePort.sendPort,
|
| - onError: _errorPort?.sendPort,
|
| - onExit: _exitPort?.sendPort,
|
| - packageConfig: packagesUri);
|
| + _isolate = await _spawnIsolate();
|
| } catch (exception, stackTrace) {
|
| instrumentationService.logPluginError(
|
| - new PluginData(pluginUri.toString(), null, null),
|
| + new PluginData(pluginId, null, null),
|
| RequestErrorCode.PLUGIN_ERROR.toString(),
|
| exception.toString(),
|
| stackTrace.toString());
|
| @@ -191,11 +264,11 @@ class ServerIsolateChannel implements ServerCommunicationChannel {
|
| } else if (input is Map) {
|
| if (input.containsKey('id')) {
|
| String encodedInput = JSON.encode(input);
|
| - instrumentationService.logPluginResponse(pluginUri, encodedInput);
|
| + instrumentationService.logPluginResponse(pluginId, encodedInput);
|
| onResponse(new Response.fromJson(input));
|
| } else if (input.containsKey('event')) {
|
| String encodedInput = JSON.encode(input);
|
| - instrumentationService.logPluginNotification(pluginUri, encodedInput);
|
| + instrumentationService.logPluginNotification(pluginId, encodedInput);
|
| onNotification(new Notification.fromJson(input));
|
| }
|
| }
|
| @@ -207,8 +280,12 @@ class ServerIsolateChannel implements ServerCommunicationChannel {
|
| void sendRequest(Request request) {
|
| Map<String, Object> json = request.toJson();
|
| String encodedRequest = JSON.encode(json);
|
| -// print('[server] Send request: $encodedRequest');
|
| - instrumentationService.logPluginRequest(pluginUri, encodedRequest);
|
| + instrumentationService.logPluginRequest(pluginId, encodedRequest);
|
| _sendPort.send(json);
|
| }
|
| +
|
| + /**
|
| + * Spawn the isolate in which the plugin is running.
|
| + */
|
| + Future<Isolate> _spawnIsolate();
|
| }
|
|
|