| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 part of dart.developer; | 5 part of dart.developer; |
| 6 | 6 |
| 7 class ServiceExtensionResponse { | 7 class ServiceExtensionResponse { |
| 8 final String _result; | 8 final String _result; |
| 9 final int _errorCode; | 9 final int _errorCode; |
| 10 final String _errorDetail; | 10 final String _errorDetail; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 _registerExtension(method, handler); | 105 _registerExtension(method, handler); |
| 106 } | 106 } |
| 107 | 107 |
| 108 // Both of these functions are written inside C++ to avoid updating the data | 108 // Both of these functions are written inside C++ to avoid updating the data |
| 109 // structures in Dart, getting an OOB, and observing stale state. Do not move | 109 // structures in Dart, getting an OOB, and observing stale state. Do not move |
| 110 // these into Dart code unless you can ensure that the operations will can be | 110 // these into Dart code unless you can ensure that the operations will can be |
| 111 // done atomically. Native code lives in vm/isolate.cc- | 111 // done atomically. Native code lives in vm/isolate.cc- |
| 112 // LookupServiceExtensionHandler and RegisterServiceExtensionHandler. | 112 // LookupServiceExtensionHandler and RegisterServiceExtensionHandler. |
| 113 external ServiceExtensionHandler _lookupExtension(String method); | 113 external ServiceExtensionHandler _lookupExtension(String method); |
| 114 external _registerExtension(String method, ServiceExtensionHandler handler); | 114 external _registerExtension(String method, ServiceExtensionHandler handler); |
| 115 | |
| 116 // This code is only invoked when there is no other Dart code on the stack. | |
| 117 _runExtension(ServiceExtensionHandler handler, | |
| 118 String method, | |
| 119 List<String> parameterKeys, | |
| 120 List<String> parameterValues, | |
| 121 SendPort replyPort, | |
| 122 Object id) { | |
| 123 var parameters = {}; | |
| 124 for (var i = 0; i < parameterKeys.length; i++) { | |
| 125 parameters[parameterKeys[i]] = parameterValues[i]; | |
| 126 } | |
| 127 var response; | |
| 128 try { | |
| 129 response = handler(method, parameters); | |
| 130 } catch (e, st) { | |
| 131 var errorDetails = (st == null) ? '$e' : '$e\n$st'; | |
| 132 response = new ServiceExtensionResponse.error( | |
| 133 ServiceExtensionResponse.kExtensionError, | |
| 134 errorDetails); | |
| 135 _postResponse(replyPort, id, response); | |
| 136 return; | |
| 137 } | |
| 138 if (response is! Future) { | |
| 139 response = new ServiceExtensionResponse.error( | |
| 140 ServiceExtensionResponse.kExtensionError, | |
| 141 "Extension handler must return a Future"); | |
| 142 _postResponse(replyPort, id, response); | |
| 143 return; | |
| 144 } | |
| 145 response.catchError((e, st) { | |
| 146 // Catch any errors eagerly and wrap them in a ServiceExtensionResponse. | |
| 147 var errorDetails = (st == null) ? '$e' : '$e\n$st'; | |
| 148 return new ServiceExtensionResponse.error( | |
| 149 ServiceExtensionResponse.kExtensionError, | |
| 150 errorDetails); | |
| 151 }).then((response) { | |
| 152 // Post the valid response or the wrapped error after verifying that | |
| 153 // the response is a ServiceExtensionResponse. | |
| 154 if (response is! ServiceExtensionResponse) { | |
| 155 response = new ServiceExtensionResponse.error( | |
| 156 ServiceExtensionResponse.kExtensionError, | |
| 157 "Extension handler must complete to a ServiceExtensionResponse"); | |
| 158 } | |
| 159 _postResponse(replyPort, id, response); | |
| 160 }).catchError((e, st) { | |
| 161 // We do not expect any errors to occur in the .then or .catchError blocks | |
| 162 // but, suppress them just in case. | |
| 163 }); | |
| 164 } | |
| 165 | |
| 166 // This code is only invoked by _runExtension. | |
| 167 _postResponse(SendPort replyPort, | |
| 168 Object id, | |
| 169 ServiceExtensionResponse response) { | |
| 170 assert(replyPort != null); | |
| 171 if (id == null) { | |
| 172 // No id -> no response. | |
| 173 replyPort.send(null); | |
| 174 return; | |
| 175 } | |
| 176 assert(id != null); | |
| 177 StringBuffer sb = new StringBuffer(); | |
| 178 sb.write('{"jsonrpc":"2.0",'); | |
| 179 if (response._isError()) { | |
| 180 sb.write('"error":'); | |
| 181 } else { | |
| 182 sb.write('"result":'); | |
| 183 } | |
| 184 sb.write('${response._toString()},'); | |
| 185 if (id is String) { | |
| 186 sb.write('"id":"$id"}'); | |
| 187 } else { | |
| 188 sb.write('"id":$id}'); | |
| 189 } | |
| 190 replyPort.send(sb.toString()); | |
| 191 } | |
| OLD | NEW |