| // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'dart:isolate'; |
| |
| patch bool debugger({bool when: true, |
| String message}) native "Developer_debugger"; |
| |
| patch Object inspect(Object object) native "Developer_inspect"; |
| |
| patch void log(String message, |
| {DateTime time, |
| int sequenceNumber, |
| int level: 0, |
| String name: '', |
| Zone zone, |
| Object error, |
| StackTrace stackTrace}) { |
| if (message is! String) { |
| throw new ArgumentError(message, "message", "Must be a String"); |
| } |
| if (time == null) { |
| time = new DateTime.now(); |
| } |
| if (time is! DateTime) { |
| throw new ArgumentError(time, "time", "Must be a DateTime"); |
| } |
| if (sequenceNumber == null) { |
| sequenceNumber = _nextSequenceNumber++; |
| } else { |
| _nextSequenceNumber = sequenceNumber + 1; |
| } |
| _log(message, |
| time.millisecondsSinceEpoch, |
| sequenceNumber, |
| level, |
| name, |
| zone, |
| error, |
| stackTrace); |
| } |
| |
| int _nextSequenceNumber = 0; |
| |
| _log(String message, |
| int timestamp, |
| int sequenceNumber, |
| int level, |
| String name, |
| Zone zone, |
| Object error, |
| StackTrace stackTrace) native "Developer_log"; |
| |
| patch void _postEvent(String eventKind, String eventData) |
| native "Developer_postEvent"; |
| |
| patch ServiceExtensionHandler _lookupExtension(String method) |
| native "Developer_lookupExtension"; |
| |
| patch _registerExtension(String method, ServiceExtensionHandler handler) |
| native "Developer_registerExtension"; |
| |
| // This code is only invoked when there is no other Dart code on the stack. |
| _runExtension(ServiceExtensionHandler handler, |
| String method, |
| List<String> parameterKeys, |
| List<String> parameterValues, |
| SendPort replyPort, |
| Object id, |
| bool trace_service) { |
| var parameters = {}; |
| for (var i = 0; i < parameterKeys.length; i++) { |
| parameters[parameterKeys[i]] = parameterValues[i]; |
| } |
| var response; |
| try { |
| response = handler(method, parameters); |
| } catch (e, st) { |
| var errorDetails = (st == null) ? '$e' : '$e\n$st'; |
| response = new ServiceExtensionResponse.error( |
| ServiceExtensionResponse.kExtensionError, |
| errorDetails); |
| _postResponse(replyPort, id, response, trace_service); |
| return; |
| } |
| if (response is! Future) { |
| response = new ServiceExtensionResponse.error( |
| ServiceExtensionResponse.kExtensionError, |
| "Extension handler must return a Future"); |
| _postResponse(replyPort, id, response, trace_service); |
| return; |
| } |
| response.catchError((e, st) { |
| // Catch any errors eagerly and wrap them in a ServiceExtensionResponse. |
| var errorDetails = (st == null) ? '$e' : '$e\n$st'; |
| return new ServiceExtensionResponse.error( |
| ServiceExtensionResponse.kExtensionError, |
| errorDetails); |
| }).then((response) { |
| // Post the valid response or the wrapped error after verifying that |
| // the response is a ServiceExtensionResponse. |
| if (response is! ServiceExtensionResponse) { |
| response = new ServiceExtensionResponse.error( |
| ServiceExtensionResponse.kExtensionError, |
| "Extension handler must complete to a ServiceExtensionResponse"); |
| } |
| _postResponse(replyPort, id, response, trace_service); |
| }).catchError((e, st) { |
| // We do not expect any errors to occur in the .then or .catchError blocks |
| // but, suppress them just in case. |
| }); |
| } |
| |
| // This code is only invoked by _runExtension. |
| _postResponse(SendPort replyPort, |
| Object id, |
| ServiceExtensionResponse response, |
| bool trace_service) { |
| assert(replyPort != null); |
| if (id == null) { |
| if (trace_service) { |
| print("vm-service: posting no response for request"); |
| } |
| // No id -> no response. |
| replyPort.send(null); |
| return; |
| } |
| assert(id != null); |
| StringBuffer sb = new StringBuffer(); |
| sb.write('{"jsonrpc":"2.0",'); |
| if (response._isError()) { |
| if (trace_service) { |
| print("vm-service: posting error response for request $id"); |
| } |
| sb.write('"error":'); |
| } else { |
| if (trace_service) { |
| print("vm-service: posting response for request $id"); |
| } |
| sb.write('"result":'); |
| } |
| sb.write('${response._toString()},'); |
| if (id is String) { |
| sb.write('"id":"$id"}'); |
| } else { |
| sb.write('"id":$id}'); |
| } |
| replyPort.send(sb.toString()); |
| } |