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 /// A response to a service protocol extension RPC. | 7 /// A response to a service protocol extension RPC. |
8 /// | 8 /// |
9 /// If the RPC was successful, use [ServiceExtensionResponse.result], otherwise | 9 /// If the RPC was successful, use [ServiceExtensionResponse.result], otherwise |
10 /// use [ServiceExtensionResponse.error]. | 10 /// use [ServiceExtensionResponse.error]. |
(...skipping 20 matching lines...) Expand all Loading... |
31 /// Requires [errorCode] to be [invalidParams] or between [extensionErrorMin] | 31 /// Requires [errorCode] to be [invalidParams] or between [extensionErrorMin] |
32 /// and [extensionErrorMax]. Requires [errorDetail] to be a JSON object | 32 /// and [extensionErrorMax]. Requires [errorDetail] to be a JSON object |
33 /// encoded as a string. When forming the JSON-RPC message [errorDetail] will | 33 /// encoded as a string. When forming the JSON-RPC message [errorDetail] will |
34 /// be inlined directly. | 34 /// be inlined directly. |
35 ServiceExtensionResponse.error(int errorCode, String errorDetail) | 35 ServiceExtensionResponse.error(int errorCode, String errorDetail) |
36 : _result = null, | 36 : _result = null, |
37 _errorCode = errorCode, | 37 _errorCode = errorCode, |
38 _errorDetail = errorDetail { | 38 _errorDetail = errorDetail { |
39 _validateErrorCode(_errorCode); | 39 _validateErrorCode(_errorCode); |
40 if (_errorDetail is! String) { | 40 if (_errorDetail is! String) { |
41 throw new ArgumentError.value(_errorDetail, | 41 throw new ArgumentError.value( |
42 "errorDetail", | 42 _errorDetail, "errorDetail", "Must be a String"); |
43 "Must be a String"); | |
44 } | 43 } |
45 } | 44 } |
46 | 45 |
47 /// Invalid method parameter(s) error code. | 46 /// Invalid method parameter(s) error code. |
48 @deprecated static const kInvalidParams = invalidParams; | 47 @deprecated |
| 48 static const kInvalidParams = invalidParams; |
| 49 |
49 /// Generic extension error code. | 50 /// Generic extension error code. |
50 @deprecated static const kExtensionError = extensionError; | 51 @deprecated |
| 52 static const kExtensionError = extensionError; |
| 53 |
51 /// Maximum extension provided error code. | 54 /// Maximum extension provided error code. |
52 @deprecated static const kExtensionErrorMax = extensionErrorMax; | 55 @deprecated |
| 56 static const kExtensionErrorMax = extensionErrorMax; |
| 57 |
53 /// Minimum extension provided error code. | 58 /// Minimum extension provided error code. |
54 @deprecated static const kExtensionErrorMin = extensionErrorMin; | 59 @deprecated |
| 60 static const kExtensionErrorMin = extensionErrorMin; |
55 | 61 |
56 /// Invalid method parameter(s) error code. | 62 /// Invalid method parameter(s) error code. |
57 static const invalidParams = -32602; | 63 static const invalidParams = -32602; |
| 64 |
58 /// Generic extension error code. | 65 /// Generic extension error code. |
59 static const extensionError = -32000; | 66 static const extensionError = -32000; |
| 67 |
60 /// Maximum extension provided error code. | 68 /// Maximum extension provided error code. |
61 static const extensionErrorMax = -32000; | 69 static const extensionErrorMax = -32000; |
| 70 |
62 /// Minimum extension provided error code. | 71 /// Minimum extension provided error code. |
63 static const extensionErrorMin = -32016; | 72 static const extensionErrorMin = -32016; |
64 | 73 |
65 | |
66 static String _errorCodeMessage(int errorCode) { | 74 static String _errorCodeMessage(int errorCode) { |
67 _validateErrorCode(errorCode); | 75 _validateErrorCode(errorCode); |
68 if (errorCode == kInvalidParams) { | 76 if (errorCode == kInvalidParams) { |
69 return "Invalid params"; | 77 return "Invalid params"; |
70 } | 78 } |
71 return "Server error"; | 79 return "Server error"; |
72 } | 80 } |
73 | 81 |
74 static _validateErrorCode(int errorCode) { | 82 static _validateErrorCode(int errorCode) { |
75 if (errorCode is! int) { | 83 if (errorCode is! int) { |
76 throw new ArgumentError.value(errorCode, "errorCode", "Must be an int"); | 84 throw new ArgumentError.value(errorCode, "errorCode", "Must be an int"); |
77 } | 85 } |
78 if (errorCode == invalidParams) { | 86 if (errorCode == invalidParams) { |
79 return; | 87 return; |
80 } | 88 } |
81 if ((errorCode >= extensionErrorMin) && | 89 if ((errorCode >= extensionErrorMin) && (errorCode <= extensionErrorMax)) { |
82 (errorCode <= extensionErrorMax)) { | |
83 return; | 90 return; |
84 } | 91 } |
85 throw new ArgumentError.value(errorCode, "errorCode", "Out of range"); | 92 throw new ArgumentError.value(errorCode, "errorCode", "Out of range"); |
86 } | 93 } |
87 | 94 |
88 bool _isError() => (_errorCode != null) && (_errorDetail != null); | 95 bool _isError() => (_errorCode != null) && (_errorDetail != null); |
89 | 96 |
90 String _toString() { | 97 String _toString() { |
91 if (_result != null) { | 98 if (_result != null) { |
92 return _result; | 99 return _result; |
93 } else { | 100 } else { |
94 assert(_errorCode != null); | 101 assert(_errorCode != null); |
95 assert(_errorDetail != null); | 102 assert(_errorDetail != null); |
96 return JSON.encode({ | 103 return JSON.encode({ |
97 'code': _errorCode, | 104 'code': _errorCode, |
98 'message': _errorCodeMessage(_errorCode), | 105 'message': _errorCodeMessage(_errorCode), |
99 'data': { | 106 'data': {'details': _errorDetail} |
100 'details': _errorDetail | |
101 } | |
102 }); | 107 }); |
103 } | 108 } |
104 } | 109 } |
105 } | 110 } |
106 | 111 |
107 /// A service protocol extension handler. Registered with [registerExtension]. | 112 /// A service protocol extension handler. Registered with [registerExtension]. |
108 /// | 113 /// |
109 /// Must complete to a [ServiceExtensionResponse]. | 114 /// Must complete to a [ServiceExtensionResponse]. |
110 /// | 115 /// |
111 /// [method] - the method name of the service protocol request. | 116 /// [method] - the method name of the service protocol request. |
112 /// [parameters] - A map holding the parameters to the service protocol request. | 117 /// [parameters] - A map holding the parameters to the service protocol request. |
113 /// | 118 /// |
114 /// *NOTE*: All parameter names and values are **encoded as strings**. | 119 /// *NOTE*: All parameter names and values are **encoded as strings**. |
115 typedef Future<ServiceExtensionResponse> | 120 typedef Future<ServiceExtensionResponse> ServiceExtensionHandler( |
116 ServiceExtensionHandler(String method, Map<String, String> parameters); | 121 String method, Map<String, String> parameters); |
117 | 122 |
118 /// Register a [ServiceExtensionHandler] that will be invoked in this isolate | 123 /// Register a [ServiceExtensionHandler] that will be invoked in this isolate |
119 /// for [method]. *NOTE*: Service protocol extensions must be registered | 124 /// for [method]. *NOTE*: Service protocol extensions must be registered |
120 /// in each isolate. | 125 /// in each isolate. |
121 /// | 126 /// |
122 /// *NOTE*: [method] must begin with 'ext.' and you should use the following | 127 /// *NOTE*: [method] must begin with 'ext.' and you should use the following |
123 /// structure to avoid conflicts with other packages: 'ext.package.command'. | 128 /// structure to avoid conflicts with other packages: 'ext.package.command'. |
124 /// That is, immediately following the 'ext.' prefix, should be the registering | 129 /// That is, immediately following the 'ext.' prefix, should be the registering |
125 /// package name followed by another period ('.') and then the command name. | 130 /// package name followed by another period ('.') and then the command name. |
126 /// For example: 'ext.dart.io.getOpenFiles'. | 131 /// For example: 'ext.dart.io.getOpenFiles'. |
127 /// | 132 /// |
128 /// Because service extensions are isolate specific, clients using extensions | 133 /// Because service extensions are isolate specific, clients using extensions |
129 /// must always include an 'isolateId' parameter with each RPC. | 134 /// must always include an 'isolateId' parameter with each RPC. |
130 void registerExtension(String method, ServiceExtensionHandler handler) { | 135 void registerExtension(String method, ServiceExtensionHandler handler) { |
131 if (method is! String) { | 136 if (method is! String) { |
132 throw new ArgumentError.value(method, | 137 throw new ArgumentError.value(method, 'method', 'Must be a String'); |
133 'method', | |
134 'Must be a String'); | |
135 } | 138 } |
136 if (!method.startsWith('ext.')) { | 139 if (!method.startsWith('ext.')) { |
137 throw new ArgumentError.value(method, | 140 throw new ArgumentError.value(method, 'method', 'Must begin with ext.'); |
138 'method', | |
139 'Must begin with ext.'); | |
140 } | 141 } |
141 if (_lookupExtension(method) != null) { | 142 if (_lookupExtension(method) != null) { |
142 throw new ArgumentError('Extension already registered: $method'); | 143 throw new ArgumentError('Extension already registered: $method'); |
143 } | 144 } |
144 if (handler is! ServiceExtensionHandler) { | 145 if (handler is! ServiceExtensionHandler) { |
145 throw new ArgumentError.value(handler, | 146 throw new ArgumentError.value( |
146 'handler', | 147 handler, 'handler', 'Must be a ServiceExtensionHandler'); |
147 'Must be a ServiceExtensionHandler'); | |
148 } | 148 } |
149 _registerExtension(method, handler); | 149 _registerExtension(method, handler); |
150 } | 150 } |
151 | 151 |
152 /// Post an event of [eventKind] with payload of [eventData] to the `Extension` | 152 /// Post an event of [eventKind] with payload of [eventData] to the `Extension` |
153 /// event stream. | 153 /// event stream. |
154 void postEvent(String eventKind, Map eventData) { | 154 void postEvent(String eventKind, Map eventData) { |
155 if (eventKind is! String) { | 155 if (eventKind is! String) { |
156 throw new ArgumentError.value(eventKind, | 156 throw new ArgumentError.value(eventKind, 'eventKind', 'Must be a String'); |
157 'eventKind', | |
158 'Must be a String'); | |
159 } | 157 } |
160 if (eventData is! Map) { | 158 if (eventData is! Map) { |
161 throw new ArgumentError.value(eventData, | 159 throw new ArgumentError.value(eventData, 'eventData', 'Must be a Map'); |
162 'eventData', | |
163 'Must be a Map'); | |
164 } | 160 } |
165 String eventDataAsString = JSON.encode(eventData); | 161 String eventDataAsString = JSON.encode(eventData); |
166 _postEvent(eventKind, eventDataAsString); | 162 _postEvent(eventKind, eventDataAsString); |
167 } | 163 } |
168 | 164 |
169 external void _postEvent(String eventKind, String eventData); | 165 external void _postEvent(String eventKind, String eventData); |
170 | 166 |
171 // Both of these functions are written inside C++ to avoid updating the data | 167 // Both of these functions are written inside C++ to avoid updating the data |
172 // structures in Dart, getting an OOB, and observing stale state. Do not move | 168 // structures in Dart, getting an OOB, and observing stale state. Do not move |
173 // these into Dart code unless you can ensure that the operations will can be | 169 // these into Dart code unless you can ensure that the operations will can be |
174 // done atomically. Native code lives in vm/isolate.cc- | 170 // done atomically. Native code lives in vm/isolate.cc- |
175 // LookupServiceExtensionHandler and RegisterServiceExtensionHandler. | 171 // LookupServiceExtensionHandler and RegisterServiceExtensionHandler. |
176 external ServiceExtensionHandler _lookupExtension(String method); | 172 external ServiceExtensionHandler _lookupExtension(String method); |
177 external _registerExtension(String method, ServiceExtensionHandler handler); | 173 external _registerExtension(String method, ServiceExtensionHandler handler); |
OLD | NEW |