| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library protocol; | 5 library protocol; |
| 6 | 6 |
| 7 import 'dart:convert' show JsonDecoder; | 7 import 'dart:convert' show JsonDecoder; |
| 8 | 8 |
| 9 /** | 9 /** |
| 10 * Instances of the class [Request] represent a request that was received. | 10 * Instances of the class [Request] represent a request that was received. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 /** | 48 /** |
| 49 * Initialize a newly created [Request] to have the given [id] and [method] | 49 * Initialize a newly created [Request] to have the given [id] and [method] |
| 50 * name. | 50 * name. |
| 51 */ | 51 */ |
| 52 Request(this.id, this.method); | 52 Request(this.id, this.method); |
| 53 | 53 |
| 54 /** | 54 /** |
| 55 * Return a request parsed from the given [data], or `null` if the [data] is | 55 * Return a request parsed from the given [data], or `null` if the [data] is |
| 56 * not a valid json representation of a request. The [data] is expected to | 56 * not a valid json representation of a request. The [data] is expected to |
| 57 * have the following format: | 57 * have the following format: |
| 58 * | 58 * |
| 59 * { | 59 * { |
| 60 * 'id': String, | 60 * 'id': String, |
| 61 * 'method': methodName, | 61 * 'method': methodName, |
| 62 * 'params': { | 62 * 'params': { |
| 63 * paramter_name: value | 63 * paramter_name: value |
| 64 * } | 64 * } |
| 65 * } | 65 * } |
| 66 * | 66 * |
| 67 * where the parameters are optional and can contain any number of name/value | 67 * where the parameters are optional and can contain any number of name/value |
| 68 * pairs. | 68 * pairs. |
| 69 */ | 69 */ |
| 70 factory Request.fromString(String data) { | 70 factory Request.fromString(String data) { |
| 71 try { | 71 try { |
| 72 var result = DECODER.convert(data); | 72 var result = DECODER.convert(data); |
| 73 if (result is! Map) { | 73 if (result is! Map) { |
| 74 return null; | 74 return null; |
| 75 } | 75 } |
| 76 String id = result[Request.ID]; | 76 String id = result[Request.ID]; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 /** | 108 /** |
| 109 * Set the value of the parameter with the given [name] to the given [value]. | 109 * Set the value of the parameter with the given [name] to the given [value]. |
| 110 */ | 110 */ |
| 111 void setParameter(String name, Object value) { | 111 void setParameter(String name, Object value) { |
| 112 params[name] = value; | 112 params[name] = value; |
| 113 } | 113 } |
| 114 | 114 |
| 115 /** | 115 /** |
| 116 * Convert the given [value] to a boolean, or throw a [RequestFailure] | 116 * Convert the given [value] to a boolean, or throw a [RequestFailure] |
| 117 * exception if the [value] could not be converted. | 117 * exception if the [value] could not be converted. |
| 118 * | 118 * |
| 119 * The value is typically the result of invoking either [getParameter] or | 119 * The value is typically the result of invoking either [getParameter] or |
| 120 * [getRequiredParameter]. | 120 * [getRequiredParameter]. |
| 121 */ | 121 */ |
| 122 bool toBool(Object value) { | 122 bool toBool(Object value) { |
| 123 if (value is bool) { | 123 if (value is bool) { |
| 124 return value; | 124 return value; |
| 125 } else if (value is String) { | 125 } else if (value is String) { |
| 126 return value == 'true'; | 126 return value == 'true'; |
| 127 } | 127 } |
| 128 throw new RequestFailure(new Response.expectedBoolean(this, value)); | 128 throw new RequestFailure(new Response.expectedBoolean(this, value)); |
| 129 } | 129 } |
| 130 | 130 |
| 131 /** | 131 /** |
| 132 * Convert the given [value] to an integer, or throw a [RequestFailure] | 132 * Convert the given [value] to an integer, or throw a [RequestFailure] |
| 133 * exception if the [value] could not be converted. | 133 * exception if the [value] could not be converted. |
| 134 * | 134 * |
| 135 * The value is typically the result of invoking either [getParameter] or | 135 * The value is typically the result of invoking either [getParameter] or |
| 136 * [getRequiredParameter]. | 136 * [getRequiredParameter]. |
| 137 */ | 137 */ |
| 138 int toInt(Object value) { | 138 int toInt(Object value) { |
| 139 if (value is int) { | 139 if (value is int) { |
| 140 return value; | 140 return value; |
| 141 } else if (value is String) { | 141 } else if (value is String) { |
| 142 return int.parse(value, onError: (String value) { | 142 return int.parse(value, onError: (String value) { |
| 143 throw new RequestFailure(new Response.expectedInteger(this, value)); | 143 throw new RequestFailure(new Response.expectedInteger(this, value)); |
| 144 }); | 144 }); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 170 /** | 170 /** |
| 171 * The unique identifier used to identify the request that this response is | 171 * The unique identifier used to identify the request that this response is |
| 172 * associated with. | 172 * associated with. |
| 173 */ | 173 */ |
| 174 final String id; | 174 final String id; |
| 175 | 175 |
| 176 /** | 176 /** |
| 177 * The error that was caused by attempting to handle the request, or `null` if | 177 * The error that was caused by attempting to handle the request, or `null` if |
| 178 * there was no error. | 178 * there was no error. |
| 179 */ | 179 */ |
| 180 final Object error; | 180 final RequestError error; |
| 181 | 181 |
| 182 /** | 182 /** |
| 183 * A table mapping the names of result fields to their values. The table | 183 * A table mapping the names of result fields to their values. The table |
| 184 * should be empty if there was an error. | 184 * should be empty if there was an error. |
| 185 */ | 185 */ |
| 186 final Map<String, Object> result = new Map<String, Object>(); | 186 final Map<String, Object> result = new Map<String, Object>(); |
| 187 | 187 |
| 188 /** | 188 /** |
| 189 * Initialize a newly created instance to represent a response to a request | 189 * Initialize a newly created instance to represent a response to a request |
| 190 * with the given [id]. If an [error] is provided then the response will | 190 * with the given [id]. If an [error] is provided then the response will |
| 191 * represent an error condition. | 191 * represent an error condition. |
| 192 */ | 192 */ |
| 193 Response(this.id, [this.error]); | 193 Response(this.id, [this.error]); |
| 194 | 194 |
| 195 /** | 195 /** |
| 196 * Initialize a newly created instance to represent an error condition caused | 196 * Initialize a newly created instance to represent an error condition caused |
| 197 * by a [request] referencing a context that does not exist. | 197 * by a [request] referencing a context that does not exist. |
| 198 */ | 198 */ |
| 199 Response.contextDoesNotExist(Request request) | 199 Response.contextDoesNotExist(Request request) |
| 200 : this(request.id, 'Context does not exist'); | 200 : this(request.id, new RequestError(-1, 'Context does not exist')); |
| 201 | 201 |
| 202 /** | 202 /** |
| 203 * Initialize a newly created instance to represent an error condition caused | 203 * Initialize a newly created instance to represent an error condition caused |
| 204 * by a [request] that was expected to have a boolean-valued parameter but was | 204 * by a [request] that was expected to have a boolean-valued parameter but was |
| 205 * passed a non-boolean value. | 205 * passed a non-boolean value. |
| 206 */ | 206 */ |
| 207 Response.expectedBoolean(Request request, String value) | 207 Response.expectedBoolean(Request request, String value) |
| 208 : this(request.id, 'Expected a boolean value, but found "$value"'); | 208 : this(request.id, new RequestError(-2, 'Expected a boolean value, but found
"$value"')); |
| 209 | 209 |
| 210 /** | 210 /** |
| 211 * Initialize a newly created instance to represent an error condition caused | 211 * Initialize a newly created instance to represent an error condition caused |
| 212 * by a [request] that was expected to have a integer-valued parameter but was | 212 * by a [request] that was expected to have a integer-valued parameter but was |
| 213 * passed a non-integer value. | 213 * passed a non-integer value. |
| 214 */ | 214 */ |
| 215 Response.expectedInteger(Request request, String value) | 215 Response.expectedInteger(Request request, String value) |
| 216 : this(request.id, 'Expected an integer value, but found "$value"'); | 216 : this(request.id, new RequestError(-3, 'Expected an integer value, but foun
d "$value"')); |
| 217 | 217 |
| 218 /** | 218 /** |
| 219 * Initialize a newly created instance to represent an error condition caused | 219 * Initialize a newly created instance to represent an error condition caused |
| 220 * by a malformed request. | 220 * by a malformed request. |
| 221 */ | 221 */ |
| 222 Response.invalidRequestFormat() | 222 Response.invalidRequestFormat() |
| 223 : this('', 'Invalid request'); | 223 : this('', new RequestError(-4, 'Invalid request')); |
| 224 | 224 |
| 225 /** | 225 /** |
| 226 * Initialize a newly created instance to represent an error condition caused | 226 * Initialize a newly created instance to represent an error condition caused |
| 227 * by a [request] that does not have a required parameter. | 227 * by a [request] that does not have a required parameter. |
| 228 */ | 228 */ |
| 229 Response.missingRequiredParameter(Request request, String parameterName) | 229 Response.missingRequiredParameter(Request request, String parameterName) |
| 230 : this(request.id, 'Missing required parameter: $parameterName'); | 230 : this(request.id, new RequestError(-5, 'Missing required parameter: $parame
terName')); |
| 231 | 231 |
| 232 /** | 232 /** |
| 233 * Initialize a newly created instance to represent an error condition caused | 233 * Initialize a newly created instance to represent an error condition caused |
| 234 * by a [request] that takes a set of analysis options but for which an | 234 * by a [request] that takes a set of analysis options but for which an |
| 235 * unknown analysis option was provided. | 235 * unknown analysis option was provided. |
| 236 */ | 236 */ |
| 237 Response.unknownAnalysisOption(Request request, String optionName) | 237 Response.unknownAnalysisOption(Request request, String optionName) |
| 238 : this(request.id, 'Unknown analysis option: "$optionName"'); | 238 : this(request.id, new RequestError(-6, 'Unknown analysis option: "$optionNa
me"')); |
| 239 | 239 |
| 240 /** | 240 /** |
| 241 * Initialize a newly created instance to represent an error condition caused | 241 * Initialize a newly created instance to represent an error condition caused |
| 242 * by a [request] that cannot be handled by any known handlers. | 242 * by a [request] that cannot be handled by any known handlers. |
| 243 */ | 243 */ |
| 244 Response.unknownRequest(Request request) | 244 Response.unknownRequest(Request request) |
| 245 : this(request.id, 'Unknown request'); | 245 : this(request.id, new RequestError(-7, 'Unknown request')); |
| 246 | 246 |
| 247 /** | 247 /** |
| 248 * Return the value of the result field with the given [name]. | 248 * Return the value of the result field with the given [name]. |
| 249 */ | 249 */ |
| 250 Object getResult(String name) { | 250 Object getResult(String name) { |
| 251 return result[name]; | 251 return result[name]; |
| 252 } | 252 } |
| 253 | 253 |
| 254 /** | 254 /** |
| 255 * Set the value of the result field with the given [name] to the given [value
]. | 255 * Set the value of the result field with the given [name] to the given [value
]. |
| 256 */ | 256 */ |
| 257 void setResult(String name, Object value) { | 257 void setResult(String name, Object value) { |
| 258 result[name] = value; | 258 result[name] = value; |
| 259 } | 259 } |
| 260 | 260 |
| 261 /** | 261 /** |
| 262 * Return a table representing the structure of the Json object that will be | 262 * Return a table representing the structure of the Json object that will be |
| 263 * sent to the client to represent this response. | 263 * sent to the client to represent this response. |
| 264 */ | 264 */ |
| 265 Map<String, Object> toJson() { | 265 Map<String, Object> toJson() { |
| 266 Map jsonObject = new Map(); | 266 Map jsonObject = new Map(); |
| 267 jsonObject[ID] = id; | 267 jsonObject[ID] = id; |
| 268 jsonObject[ERROR] = error; | 268 jsonObject[ERROR] = error.toJson(); |
| 269 if (!result.isEmpty) { | 269 if (!result.isEmpty) { |
| 270 jsonObject[RESULT] = result; | 270 jsonObject[RESULT] = result; |
| 271 } | 271 } |
| 272 return jsonObject; | 272 return jsonObject; |
| 273 } | 273 } |
| 274 } | 274 } |
| 275 | 275 |
| 276 /** | 276 /** |
| 277 * Instances of the class [RequestError] represent information about an error th
at |
| 278 * occurred while attempting to respond to a [Request]. |
| 279 */ |
| 280 class RequestError { |
| 281 /** |
| 282 * The name of the JSON attribute containing the code that uniquely identifies |
| 283 * the error that occurred. |
| 284 */ |
| 285 static const String CODE = 'code'; |
| 286 |
| 287 /** |
| 288 * The name of the JSON attribute containing an object with additional data |
| 289 * related to the error. |
| 290 */ |
| 291 static const String DATA = 'data'; |
| 292 |
| 293 /** |
| 294 * The name of the JSON attribute containing a short description of the error. |
| 295 */ |
| 296 static const String MESSAGE = 'message'; |
| 297 |
| 298 /** |
| 299 * An error code indicating a parse error. Invalid JSON was received by the |
| 300 * server. An error occurred on the server while parsing the JSON text. |
| 301 */ |
| 302 static const int CODE_PARSE_ERROR = -32700; |
| 303 |
| 304 /** |
| 305 * An error code indicating an invalid request. The JSON sent is not a valid |
| 306 * [Request] object. |
| 307 */ |
| 308 static const int CODE_INVALID_REQUEST = -32600; |
| 309 |
| 310 /** |
| 311 * An error code indicating a method not found. The method does not exist or |
| 312 * is not currently available. |
| 313 */ |
| 314 static const int CODE_METHOD_NOT_FOUND = -32601; |
| 315 |
| 316 /** |
| 317 * An error code indicating one or more invalid parameters. |
| 318 */ |
| 319 static const int CODE_INVALID_PARAMS = -32602; |
| 320 |
| 321 /** |
| 322 * An error code indicating an internal error. |
| 323 */ |
| 324 static const int CODE_INTERNAL_ERROR = -32603; |
| 325 |
| 326 /* |
| 327 * In addition, codes -32000 to -32099 indicate a server error. They are |
| 328 * reserved for implementation-defined server-errors. |
| 329 */ |
| 330 |
| 331 /** |
| 332 * The code that uniquely identifies the error that occurred. |
| 333 */ |
| 334 final int code; |
| 335 |
| 336 /** |
| 337 * A short description of the error. |
| 338 */ |
| 339 final String message; |
| 340 |
| 341 /** |
| 342 * A table mapping the names of notification parameters to their values. |
| 343 */ |
| 344 final Map<String, Object> data = new Map<String, Object>(); |
| 345 |
| 346 /** |
| 347 * Initialize a newly created [Error] to have the given [code] and [message]. |
| 348 */ |
| 349 RequestError(this.code, this.message); |
| 350 |
| 351 /** |
| 352 * Initialize a newly created [Error] to indicate a parse error. Invalid JSON |
| 353 * was received by the server. An error occurred on the server while parsing |
| 354 * the JSON text. |
| 355 */ |
| 356 RequestError.parseError() : this(CODE_PARSE_ERROR, "Parse error"); |
| 357 |
| 358 /** |
| 359 * Initialize a newly created [Error] to indicate an invalid request. The |
| 360 * JSON sent is not a valid [Request] object. |
| 361 */ |
| 362 RequestError.invalidRequest() : this(CODE_INVALID_REQUEST, "Invalid request"); |
| 363 |
| 364 /** |
| 365 * Initialize a newly created [Error] to indicate that a method was not found. |
| 366 * Either the method does not exist or is not currently available. |
| 367 */ |
| 368 RequestError.methodNotFound() : this(CODE_METHOD_NOT_FOUND, "Method not found"
); |
| 369 |
| 370 /** |
| 371 * Initialize a newly created [Error] to indicate one or more invalid |
| 372 * parameters. |
| 373 */ |
| 374 RequestError.invalidParameters() : this(CODE_INVALID_PARAMS, "Invalid paramete
rs"); |
| 375 |
| 376 /** |
| 377 * Initialize a newly created [Error] to indicate an internal error. |
| 378 */ |
| 379 RequestError.internalError() : this(CODE_INTERNAL_ERROR, "Internal error"); |
| 380 |
| 381 /** |
| 382 * Return the value of the data with the given [name], or `null` if there is |
| 383 * no such data associated with this error. |
| 384 */ |
| 385 Object getData(String name) => data[name]; |
| 386 |
| 387 /** |
| 388 * Set the value of the data with the given [name] to the given [value]. |
| 389 */ |
| 390 void setData(String name, Object value) { |
| 391 data[name] = value; |
| 392 } |
| 393 |
| 394 /** |
| 395 * Return a table representing the structure of the Json object that will be |
| 396 * sent to the client to represent this response. |
| 397 */ |
| 398 Map<String, Object> toJson() { |
| 399 Map jsonObject = new Map(); |
| 400 jsonObject[CODE] = code; |
| 401 jsonObject[MESSAGE] = message; |
| 402 if (!data.isEmpty) { |
| 403 jsonObject[DATA] = data; |
| 404 } |
| 405 return jsonObject; |
| 406 } |
| 407 } |
| 408 |
| 409 /** |
| 277 * Instances of the class [Notification] represent a notification from the | 410 * Instances of the class [Notification] represent a notification from the |
| 278 * server about an event that occurred. | 411 * server about an event that occurred. |
| 279 */ | 412 */ |
| 280 class Notification { | 413 class Notification { |
| 281 /** | 414 /** |
| 282 * The name of the JSON attribute containing the name of the event that | 415 * The name of the JSON attribute containing the name of the event that |
| 283 * triggered the notification. | 416 * triggered the notification. |
| 284 */ | 417 */ |
| 285 static const String EVENT = 'event'; | 418 static const String EVENT = 'event'; |
| 286 | 419 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 /** | 487 /** |
| 355 * The response to be returned as a result of the failure. | 488 * The response to be returned as a result of the failure. |
| 356 */ | 489 */ |
| 357 final Response response; | 490 final Response response; |
| 358 | 491 |
| 359 /** | 492 /** |
| 360 * Initialize a newly created exception to return the given reponse. | 493 * Initialize a newly created exception to return the given reponse. |
| 361 */ | 494 */ |
| 362 RequestFailure(this.response); | 495 RequestFailure(this.response); |
| 363 } | 496 } |
| OLD | NEW |