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 |