| 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 analysis_server.src.protocol.protocol_internal; | |
| 6 | |
| 7 import 'dart:collection'; | 5 import 'dart:collection'; |
| 8 import 'dart:convert' hide JsonDecoder; | 6 import 'dart:convert' hide JsonDecoder; |
| 9 | 7 |
| 10 import 'package:analysis_server/protocol/protocol.dart'; | 8 import 'package:analysis_server/protocol/protocol.dart'; |
| 11 import 'package:analysis_server/protocol/protocol_generated.dart'; | 9 import 'package:analysis_server/protocol/protocol_generated.dart'; |
| 10 import 'package:analyzer_plugin/protocol/protocol_common.dart'; |
| 11 import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' |
| 12 show JsonDecoder; |
| 13 |
| 14 export 'package:analyzer_plugin/src/protocol/protocol_internal.dart' |
| 15 show JsonDecoder; |
| 12 | 16 |
| 13 final Map<String, RefactoringKind> REQUEST_ID_REFACTORING_KINDS = | 17 final Map<String, RefactoringKind> REQUEST_ID_REFACTORING_KINDS = |
| 14 new HashMap<String, RefactoringKind>(); | 18 new HashMap<String, RefactoringKind>(); |
| 15 | 19 |
| 16 /** | 20 /** |
| 17 * Adds the given [sourceEdits] to the list in [sourceFileEdit]. | 21 * Adds the given [sourceEdits] to the list in [sourceFileEdit]. |
| 18 */ | 22 */ |
| 19 void addAllEditsForSource( | 23 void addAllEditsForSource( |
| 20 SourceFileEdit sourceFileEdit, Iterable<SourceEdit> edits) { | 24 SourceFileEdit sourceFileEdit, Iterable<SourceEdit> edits) { |
| 21 edits.forEach(sourceFileEdit.add); | 25 edits.forEach(sourceFileEdit.add); |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 * a JSON presentation. | 242 * a JSON presentation. |
| 239 */ | 243 */ |
| 240 abstract class HasToJson { | 244 abstract class HasToJson { |
| 241 /** | 245 /** |
| 242 * Returns a JSON presentation of the object. | 246 * Returns a JSON presentation of the object. |
| 243 */ | 247 */ |
| 244 Map<String, Object> toJson(); | 248 Map<String, Object> toJson(); |
| 245 } | 249 } |
| 246 | 250 |
| 247 /** | 251 /** |
| 248 * Base class for decoding JSON objects. The derived class must implement | |
| 249 * error reporting logic. | |
| 250 */ | |
| 251 abstract class JsonDecoder { | |
| 252 /** | |
| 253 * Retrieve the RefactoringKind that should be assumed when decoding | |
| 254 * refactoring feedback objects, or null if no refactoring feedback object is | |
| 255 * expected to be encountered. | |
| 256 */ | |
| 257 RefactoringKind get refactoringKind; | |
| 258 | |
| 259 /** | |
| 260 * Decode a JSON object that is expected to be a boolean. The strings "true" | |
| 261 * and "false" are also accepted. | |
| 262 */ | |
| 263 bool decodeBool(String jsonPath, Object json) { | |
| 264 if (json is bool) { | |
| 265 return json; | |
| 266 } else if (json == 'true') { | |
| 267 return true; | |
| 268 } else if (json == 'false') { | |
| 269 return false; | |
| 270 } | |
| 271 throw mismatch(jsonPath, 'bool', json); | |
| 272 } | |
| 273 | |
| 274 /** | |
| 275 * Decode a JSON object that is expected to be an integer. A string | |
| 276 * representation of an integer is also accepted. | |
| 277 */ | |
| 278 int decodeInt(String jsonPath, Object json) { | |
| 279 if (json is int) { | |
| 280 return json; | |
| 281 } else if (json is String) { | |
| 282 return int.parse(json, onError: (String value) { | |
| 283 throw mismatch(jsonPath, 'int', json); | |
| 284 }); | |
| 285 } | |
| 286 throw mismatch(jsonPath, 'int', json); | |
| 287 } | |
| 288 | |
| 289 /** | |
| 290 * Decode a JSON object that is expected to be a List. The [decoder] is used | |
| 291 * to decode the items in the list. | |
| 292 * | |
| 293 * The type parameter [E] is the expected type of the elements in the list. | |
| 294 */ | |
| 295 List/*<E>*/ decodeList/*<E>*/(String jsonPath, Object json, | |
| 296 [JsonDecoderCallback/*<E>*/ decoder]) { | |
| 297 if (json == null) { | |
| 298 return/*<E>*/ []; | |
| 299 } else if (json is List) { | |
| 300 List/*<E>*/ result = /*<E>*/ []; | |
| 301 for (int i = 0; i < json.length; i++) { | |
| 302 result.add(decoder('$jsonPath[$i]', json[i])); | |
| 303 } | |
| 304 return result; | |
| 305 } else { | |
| 306 throw mismatch(jsonPath, 'List', json); | |
| 307 } | |
| 308 } | |
| 309 | |
| 310 /** | |
| 311 * Decode a JSON object that is expected to be a Map. [keyDecoder] is used | |
| 312 * to decode the keys, and [valueDecoder] is used to decode the values. | |
| 313 */ | |
| 314 Map/*<K, V>*/ decodeMap/*<K, V>*/(String jsonPath, Object json, | |
| 315 {JsonDecoderCallback/*<K>*/ keyDecoder, | |
| 316 JsonDecoderCallback/*<V>*/ valueDecoder}) { | |
| 317 if (json == null) { | |
| 318 return {}; | |
| 319 } else if (json is Map) { | |
| 320 Map/*<K, V>*/ result = /*<K, V>*/ {}; | |
| 321 json.forEach((String key, value) { | |
| 322 Object/*=K*/ decodedKey; | |
| 323 if (keyDecoder != null) { | |
| 324 decodedKey = keyDecoder('$jsonPath.key', key); | |
| 325 } else { | |
| 326 decodedKey = key as Object/*=K*/; | |
| 327 } | |
| 328 if (valueDecoder != null) { | |
| 329 value = valueDecoder('$jsonPath[${JSON.encode(key)}]', value); | |
| 330 } | |
| 331 result[decodedKey] = value as Object/*=V*/; | |
| 332 }); | |
| 333 return result; | |
| 334 } else { | |
| 335 throw mismatch(jsonPath, 'Map', json); | |
| 336 } | |
| 337 } | |
| 338 | |
| 339 /** | |
| 340 * Decode a JSON object that is expected to be a string. | |
| 341 */ | |
| 342 String decodeString(String jsonPath, Object json) { | |
| 343 if (json is String) { | |
| 344 return json; | |
| 345 } else { | |
| 346 throw mismatch(jsonPath, 'String', json); | |
| 347 } | |
| 348 } | |
| 349 | |
| 350 /** | |
| 351 * Decode a JSON object that is expected to be one of several choices, | |
| 352 * where the choices are disambiguated by the contents of the field [field]. | |
| 353 * [decoders] is a map from each possible string in the field to the decoder | |
| 354 * that should be used to decode the JSON object. | |
| 355 */ | |
| 356 Object decodeUnion(String jsonPath, Map json, String field, | |
| 357 Map<String, JsonDecoderCallback> decoders) { | |
| 358 if (json is Map) { | |
| 359 if (!json.containsKey(field)) { | |
| 360 throw missingKey(jsonPath, field); | |
| 361 } | |
| 362 var disambiguatorPath = '$jsonPath[${JSON.encode(field)}]'; | |
| 363 String disambiguator = decodeString(disambiguatorPath, json[field]); | |
| 364 if (!decoders.containsKey(disambiguator)) { | |
| 365 throw mismatch( | |
| 366 disambiguatorPath, 'One of: ${decoders.keys.toList()}', json); | |
| 367 } | |
| 368 return decoders[disambiguator](jsonPath, json); | |
| 369 } else { | |
| 370 throw mismatch(jsonPath, 'Map', json); | |
| 371 } | |
| 372 } | |
| 373 | |
| 374 /** | |
| 375 * Create an exception to throw if the JSON object at [jsonPath] fails to | |
| 376 * match the API definition of [expected]. | |
| 377 */ | |
| 378 dynamic mismatch(String jsonPath, String expected, [Object actual]); | |
| 379 | |
| 380 /** | |
| 381 * Create an exception to throw if the JSON object at [jsonPath] is missing | |
| 382 * the key [key]. | |
| 383 */ | |
| 384 dynamic missingKey(String jsonPath, String key); | |
| 385 } | |
| 386 | |
| 387 /** | |
| 388 * JsonDecoder for decoding requests. Errors are reporting by throwing a | 252 * JsonDecoder for decoding requests. Errors are reporting by throwing a |
| 389 * [RequestFailure]. | 253 * [RequestFailure]. |
| 390 */ | 254 */ |
| 391 class RequestDecoder extends JsonDecoder { | 255 class RequestDecoder extends JsonDecoder { |
| 392 /** | 256 /** |
| 393 * The request being deserialized. | 257 * The request being deserialized. |
| 394 */ | 258 */ |
| 395 final Request _request; | 259 final Request _request; |
| 396 | 260 |
| 397 RequestDecoder(this._request); | 261 RequestDecoder(this._request); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 /** | 327 /** |
| 464 * The result data associated with a response. | 328 * The result data associated with a response. |
| 465 */ | 329 */ |
| 466 abstract class ResponseResult implements HasToJson { | 330 abstract class ResponseResult implements HasToJson { |
| 467 /** | 331 /** |
| 468 * Return a response whose result data is this object for the request with the | 332 * Return a response whose result data is this object for the request with the |
| 469 * given [id]. | 333 * given [id]. |
| 470 */ | 334 */ |
| 471 Response toResponse(String id); | 335 Response toResponse(String id); |
| 472 } | 336 } |
| OLD | NEW |