Chromium Code Reviews| 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 part of service; | 5 part of service; |
| 6 | 6 |
| 7 /// A [ServiceObject] is an object known to the VM service and is tied | 7 /// A [ServiceObject] is an object known to the VM service and is tied |
| 8 /// to an owning [Isolate]. | 8 /// to an owning [Isolate]. |
| 9 abstract class ServiceObject extends Observable { | 9 abstract class ServiceObject extends Observable { |
| 10 /// The owner of this [ServiceObject]. This can be an [Isolate], a | 10 /// The owner of this [ServiceObject]. This can be an [Isolate], a |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 46 | 46 |
| 47 @observable String name; | 47 @observable String name; |
| 48 @observable String vmName; | 48 @observable String vmName; |
| 49 | 49 |
| 50 /// Creates an empty [ServiceObject]. | 50 /// Creates an empty [ServiceObject]. |
| 51 ServiceObject._empty(this._owner); | 51 ServiceObject._empty(this._owner); |
| 52 | 52 |
| 53 /// Creates a [ServiceObject] initialized from [map]. | 53 /// Creates a [ServiceObject] initialized from [map]. |
| 54 factory ServiceObject._fromMap(ServiceObjectOwner owner, | 54 factory ServiceObject._fromMap(ServiceObjectOwner owner, |
| 55 ObservableMap map) { | 55 ObservableMap map) { |
| 56 if (map == null) { | |
| 57 return null; | |
| 58 } | |
| 56 if (!_isServiceMap(map)) { | 59 if (!_isServiceMap(map)) { |
| 57 Logger.root.severe('Malformed service object: $map'); | 60 Logger.root.severe('Malformed service object: $map'); |
| 58 } | 61 } |
| 59 assert(_isServiceMap(map)); | 62 assert(_isServiceMap(map)); |
| 60 var type = _stripRef(map['type']); | 63 var type = _stripRef(map['type']); |
| 61 var obj = null; | 64 var obj = null; |
| 62 assert(type != 'VM'); | 65 assert(type != 'VM'); |
| 63 switch (type) { | 66 switch (type) { |
| 64 case 'Code': | 67 case 'Code': |
| 65 obj = new Code._empty(owner); | 68 obj = new Code._empty(owner); |
| 66 break; | 69 break; |
| 67 case 'Error': | 70 case 'Error': |
| 68 obj = new ServiceError._empty(owner); | 71 obj = new DartError._empty(owner); |
| 69 break; | 72 break; |
| 70 case 'Isolate': | 73 case 'Isolate': |
| 71 obj = new Isolate._empty(owner); | 74 obj = new Isolate._empty(owner); |
| 72 break; | 75 break; |
| 76 case 'ServiceError': | |
| 77 obj = new ServiceError._empty(owner); | |
| 78 break; | |
| 79 case 'ServiceException': | |
| 80 obj = new ServiceException._empty(owner); | |
| 81 break; | |
| 73 case 'Script': | 82 case 'Script': |
| 74 obj = new Script._empty(owner); | 83 obj = new Script._empty(owner); |
| 75 break; | 84 break; |
| 76 default: | 85 default: |
| 77 obj = new ServiceMap._empty(owner); | 86 obj = new ServiceMap._empty(owner); |
| 78 } | 87 } |
| 79 obj.update(map); | 88 obj.update(map); |
| 80 return obj; | 89 return obj; |
| 81 } | 90 } |
| 82 | 91 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 161 @observable String architecture = 'unknown'; | 170 @observable String architecture = 'unknown'; |
| 162 @observable double uptime = 0.0; | 171 @observable double uptime = 0.0; |
| 163 | 172 |
| 164 VM() : super._empty(null) { | 173 VM() : super._empty(null) { |
| 165 name = 'vm'; | 174 name = 'vm'; |
| 166 vmName = 'vm'; | 175 vmName = 'vm'; |
| 167 _cache['vm'] = this; | 176 _cache['vm'] = this; |
| 168 update(toObservable({'id':'vm', 'type':'@VM'})); | 177 update(toObservable({'id':'vm', 'type':'@VM'})); |
| 169 } | 178 } |
| 170 | 179 |
| 180 final StreamController<ServiceException> exceptions = | |
| 181 new StreamController.broadcast(); | |
| 182 final StreamController<ServiceError> errors = | |
| 183 new StreamController.broadcast(); | |
| 184 | |
| 171 static final RegExp _currentIsolateMatcher = new RegExp(r'isolates/\d+'); | 185 static final RegExp _currentIsolateMatcher = new RegExp(r'isolates/\d+'); |
| 172 static final RegExp _currentObjectMatcher = new RegExp(r'isolates/\d+(/|$)'); | 186 static final RegExp _currentObjectMatcher = new RegExp(r'isolates/\d+/'); |
| 173 static final String _isolatesPrefix = 'isolates/'; | 187 static final String _isolatesPrefix = 'isolates/'; |
| 174 | 188 |
| 175 String _parseObjectId(String id) { | 189 String _parseObjectId(String id) { |
| 176 Match m = _currentObjectMatcher.matchAsPrefix(id); | 190 Match m = _currentObjectMatcher.matchAsPrefix(id); |
| 177 if (m == null) { | 191 if (m == null) { |
| 178 return null; | 192 return null; |
| 179 } | 193 } |
| 180 return m.input.substring(m.end); | 194 return m.input.substring(m.end); |
| 181 } | 195 } |
| 182 | 196 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 241 // Cache miss. Get the object from the vm directly. | 255 // Cache miss. Get the object from the vm directly. |
| 242 return getAsMap(id).then((ObservableMap map) { | 256 return getAsMap(id).then((ObservableMap map) { |
| 243 var obj = new ServiceObject._fromMap(this, map); | 257 var obj = new ServiceObject._fromMap(this, map); |
| 244 if (obj.canCache) { | 258 if (obj.canCache) { |
| 245 _cache.putIfAbsent(id, () => obj); | 259 _cache.putIfAbsent(id, () => obj); |
| 246 } | 260 } |
| 247 return obj; | 261 return obj; |
| 248 }); | 262 }); |
| 249 } | 263 } |
| 250 | 264 |
| 251 /// Gets [id] as an [ObservableMap] from the service directly. | 265 /// Gets [id] as an [ObservableMap] from the service directly. If |
| 266 /// an error occurs, the future is completed as an error with a | |
| 267 /// ServiceError or ServiceException. Therefore any chained then() calls | |
| 268 /// will only receive a map encoding a valid ServiceObject. | |
| 252 Future<ObservableMap> getAsMap(String id) { | 269 Future<ObservableMap> getAsMap(String id) { |
| 253 return getString(id).then((response) { | 270 return getString(id).then((response) { |
| 254 try { | 271 try { |
| 255 var map = JSON.decode(response); | 272 var map = toObservable(JSON.decode(response)); |
| 256 return toObservable(map); | 273 // Verify that the top level response is a service map. |
| 274 if (!_isServiceMap(map)) { | |
| 275 return new Future.error( | |
| 276 new ServiceObject._fromMap(this, toObservable({ | |
| 277 'type': 'ServiceException', | |
| 278 'id': '', | |
| 279 'kind': 'FormatException', | |
| 280 'response': map, | |
| 281 'message': 'Top level service responses must be service maps.', | |
| 282 }))); | |
| 283 } | |
| 284 // Preemptively capture ServiceError and ServiceExceptions. | |
| 285 if (map['type'] == 'ServiceError') { | |
| 286 return new Future.error(new ServiceObject._fromMap(this, map)); | |
| 287 } else if (map['type'] == 'ServiceException') { | |
| 288 return new Future.error(new ServiceObject._fromMap(this, map)); | |
| 289 } | |
| 290 // map is now guaranteed to be a non-error/exception ServiceObject. | |
| 291 return map; | |
| 257 } catch (e, st) { | 292 } catch (e, st) { |
| 258 return toObservable({ | 293 print(e); |
| 259 'type': 'Error', | 294 print(st); |
| 295 return new Future.error( | |
| 296 new ServiceObject._fromMap(this, toObservable({ | |
| 297 'type': 'ServiceException', | |
| 260 'id': '', | 298 'id': '', |
| 261 'kind': 'DecodeError', | 299 'kind': 'DecodeException', |
| 262 'message': '$e', | 300 'response': response, |
| 263 }); | 301 'message': 'Could not decode JSON: $e', |
| 302 }))); | |
| 264 } | 303 } |
| 265 }).catchError((error) { | 304 }).catchError((error) { |
| 266 return toObservable({ | 305 // ServiceError, forward to VM's ServiceError stream. |
| 267 'type': 'Error', | 306 errors.add(error); |
| 268 'id': '', | 307 return new Future.error(error); |
| 269 'kind': 'LastResort', | 308 }, test: (e) => e is ServiceError).catchError((exception) { |
| 270 'message': '$error' | 309 // ServiceException, forward to VM's ServiceException stream. |
| 271 }); | 310 exceptions.add(exception); |
| 272 }); | 311 return new Future.error(exception); |
| 312 }, test: (e) => e is ServiceException); | |
| 273 } | 313 } |
| 274 | 314 |
| 275 /// Get [id] as a [String] from the service directly. See [getAsMap]. | 315 /// Get [id] as a [String] from the service directly. See [getAsMap]. |
| 276 Future<String> getString(String id); | 316 Future<String> getString(String id); |
| 277 | 317 |
| 278 void _update(ObservableMap map, bool mapIsRef) { | 318 void _update(ObservableMap map, bool mapIsRef) { |
| 279 if (mapIsRef) { | 319 if (mapIsRef) { |
| 280 return; | 320 return; |
| 281 } | 321 } |
| 282 _loaded = true; | 322 _loaded = true; |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 302 } | 342 } |
| 303 // Update the individual isolates asynchronously. | 343 // Update the individual isolates asynchronously. |
| 304 newIsolateCache.forEach((isolateId, isolate) { | 344 newIsolateCache.forEach((isolateId, isolate) { |
| 305 isolate.reload(); | 345 isolate.reload(); |
| 306 }); | 346 }); |
| 307 | 347 |
| 308 _isolateCache = newIsolateCache; | 348 _isolateCache = newIsolateCache; |
| 309 } | 349 } |
| 310 } | 350 } |
| 311 | 351 |
| 352 /// Snapshot in time of tag counters. | |
| 353 class TagProfileSnapshot { | |
| 354 final double seconds; | |
| 355 final List<int> counters; | |
| 356 int get sum => _sum; | |
| 357 int _sum = 0; | |
| 358 TagProfileSnapshot(this.seconds, int countersLength) | |
| 359 : counters = new List<int>(countersLength); | |
| 360 | |
| 361 /// Set [counters] and update [sum]. | |
| 362 void set(List<int> counters) { | |
| 363 this.counters.setAll(0, counters); | |
| 364 for (var i = 0; i < this.counters.length; i++) { | |
| 365 _sum += this.counters[i]; | |
| 366 } | |
| 367 } | |
| 368 | |
| 369 /// Set [counters] with the delta from [counters] to [old_counters] | |
| 370 /// and update [sum]. | |
| 371 void delta(List<int> counters, List<int> old_counters) { | |
| 372 for (var i = 0; i < this.counters.length; i++) { | |
| 373 this.counters[i] = counters[i] - old_counters[i]; | |
| 374 _sum += this.counters[i]; | |
| 375 } | |
| 376 } | |
| 377 | |
| 378 /// Update [counters] with new maximum values seen in [counters]. | |
| 379 void max(List<int> counters) { | |
| 380 for (var i = 0; i < counters.length; i++) { | |
| 381 var c = counters[i]; | |
| 382 this.counters[i] = this.counters[i] > c ? this.counters[i] : c; | |
| 383 } | |
| 384 } | |
| 385 | |
| 386 /// Zero [counters]. | |
| 387 void zero() { | |
| 388 for (var i = 0; i < counters.length; i++) { | |
| 389 counters[i] = 0; | |
| 390 } | |
| 391 } | |
| 392 } | |
| 393 | |
| 394 class TagProfile { | |
| 395 final List<String> names = new List<String>(); | |
| 396 final List<TagProfileSnapshot> snapshots = new List<TagProfileSnapshot>(); | |
| 397 double get updatedAtSeconds => _seconds; | |
| 398 double _seconds; | |
| 399 TagProfileSnapshot _maxSnapshot; | |
| 400 int _historySize; | |
| 401 int _countersLength = 0; | |
| 402 | |
| 403 TagProfile(this._historySize); | |
| 404 | |
| 405 void _processTagProfile(double seconds, ObservableMap tagProfile) { | |
| 406 _seconds = seconds; | |
| 407 var counters = tagProfile['counters']; | |
| 408 if (names.length == 0) { | |
| 409 // Initialization. | |
| 410 names.addAll(tagProfile['names']); | |
| 411 _countersLength = tagProfile['counters'].length; | |
| 412 for (var i = 0; i < _historySize; i++) { | |
| 413 var snapshot = new TagProfileSnapshot(0.0, _countersLength); | |
| 414 snapshot.zero(); | |
| 415 snapshots.add(snapshot); | |
| 416 } | |
| 417 // The counters monotonically grow, keep track of the maximum value. | |
| 418 _maxSnapshot = new TagProfileSnapshot(0.0, _countersLength); | |
| 419 _maxSnapshot.set(counters); | |
| 420 return; | |
| 421 } | |
| 422 var snapshot = new TagProfileSnapshot(seconds, _countersLength); | |
| 423 // We snapshot the delta from the current counters to the maximum counter | |
| 424 // values. | |
| 425 snapshot.delta(counters, _maxSnapshot.counters); | |
| 426 _maxSnapshot.max(counters); | |
| 427 snapshots.add(snapshot); | |
| 428 // Only keep _historySize snapshots. | |
| 429 if (snapshots.length > _historySize) { | |
| 430 snapshots.removeAt(0); | |
| 431 } | |
| 432 } | |
| 433 } | |
| 434 | |
| 312 /// State for a running isolate. | 435 /// State for a running isolate. |
| 313 class Isolate extends ServiceObjectOwner { | 436 class Isolate extends ServiceObjectOwner { |
| 314 @reflectable VM get vm => owner; | 437 @reflectable VM get vm => owner; |
| 315 @reflectable Isolate get isolate => this; | 438 @reflectable Isolate get isolate => this; |
| 316 | 439 |
| 317 String get link => _id; | 440 String get link => _id; |
| 318 String get hashLink => '#/$_id'; | 441 String get hashLink => '#/$_id'; |
| 319 | 442 |
| 320 @observable bool pausedOnStart = false; | 443 @observable bool pausedOnStart = false; |
| 321 @observable bool pausedOnExit = false; | 444 @observable bool pausedOnExit = false; |
| 322 @observable bool running = false; | 445 @observable bool running = false; |
| 323 @observable bool idle = false; | 446 @observable bool idle = false; |
| 324 | 447 |
| 325 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>(); | 448 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>(); |
| 449 final TagProfile tagProfile = new TagProfile(20); | |
| 326 | 450 |
| 327 Isolate._empty(ServiceObjectOwner owner) : super._empty(owner); | 451 Isolate._empty(ServiceObjectOwner owner) : super._empty(owner) { |
| 452 assert(owner is VM); | |
| 453 } | |
| 328 | 454 |
| 329 /// Creates a link to [id] relative to [this]. | 455 /// Creates a link to [id] relative to [this]. |
| 330 @reflectable String relativeLink(String id) => '${this.id}/$id'; | 456 @reflectable String relativeLink(String id) => '${this.id}/$id'; |
| 331 /// Creates a relative link to [id] with a '#/' prefix. | 457 /// Creates a relative link to [id] with a '#/' prefix. |
| 332 @reflectable String relativeHashLink(String id) => '#/${relativeLink(id)}'; | 458 @reflectable String relativeHashLink(String id) => '#/${relativeLink(id)}'; |
| 333 | 459 |
| 334 static const TAG_ROOT_ID = 'code/tag-0'; | 460 static const TAG_ROOT_ID = 'code/tag-0'; |
| 335 | 461 |
| 336 /// Returns the Code object for the root tag. | 462 /// Returns the Code object for the root tag. |
| 337 Code tagRoot() { | 463 Code tagRoot() { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 405 } | 531 } |
| 406 // Build the object from the map directly. | 532 // Build the object from the map directly. |
| 407 obj = new ServiceObject._fromMap(this, map); | 533 obj = new ServiceObject._fromMap(this, map); |
| 408 if (obj.canCache) { | 534 if (obj.canCache) { |
| 409 _cache[id] = obj; | 535 _cache[id] = obj; |
| 410 } | 536 } |
| 411 return obj; | 537 return obj; |
| 412 } | 538 } |
| 413 | 539 |
| 414 Future<ServiceObject> get(String id) { | 540 Future<ServiceObject> get(String id) { |
| 541 // Do not allow null ids or empty ids. | |
| 542 assert(id != null && id != ''); | |
| 415 var obj = _cache[id]; | 543 var obj = _cache[id]; |
| 416 if (obj != null) { | 544 if (obj != null) { |
| 417 return obj.reload(); | 545 return obj.reload(); |
| 418 } | 546 } |
| 419 // Cache miss. Get the object from the vm directly. | 547 // Cache miss. Get the object from the vm directly. |
| 420 return vm.getAsMap(relativeLink(id)).then((ObservableMap map) { | 548 return vm.getAsMap(relativeLink(id)).then((ObservableMap map) { |
| 421 var obj = new ServiceObject._fromMap(this, map); | 549 var obj = new ServiceObject._fromMap(this, map); |
| 422 if (obj.canCache) { | 550 if (obj.canCache) { |
| 423 _cache.putIfAbsent(id, () => obj); | 551 _cache.putIfAbsent(id, () => obj); |
| 424 } | 552 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 437 @observable final Map<String, double> timers = | 565 @observable final Map<String, double> timers = |
| 438 toObservable(new Map<String, double>()); | 566 toObservable(new Map<String, double>()); |
| 439 | 567 |
| 440 @observable int newHeapUsed = 0; | 568 @observable int newHeapUsed = 0; |
| 441 @observable int oldHeapUsed = 0; | 569 @observable int oldHeapUsed = 0; |
| 442 @observable int newHeapCapacity = 0; | 570 @observable int newHeapCapacity = 0; |
| 443 @observable int oldHeapCapacity = 0; | 571 @observable int oldHeapCapacity = 0; |
| 444 | 572 |
| 445 @observable String fileAndLine; | 573 @observable String fileAndLine; |
| 446 | 574 |
| 575 @observable DartError error; | |
| 576 | |
| 447 void _update(ObservableMap map, bool mapIsRef) { | 577 void _update(ObservableMap map, bool mapIsRef) { |
| 448 mainPort = map['mainPort']; | 578 mainPort = map['mainPort']; |
| 449 name = map['name']; | 579 name = map['name']; |
| 450 vmName = map['name']; | 580 vmName = map['name']; |
| 451 if (mapIsRef) { | 581 if (mapIsRef) { |
| 452 return; | 582 return; |
| 453 } | 583 } |
| 454 _loaded = true; | 584 _loaded = true; |
| 455 _upgradeCollection(map, isolate); | 585 _upgradeCollection(map, isolate); |
| 456 if (map['rootLib'] == null || | 586 if (map['rootLib'] == null || |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 485 newHeapUsed = map['heap']['usedNew']; | 615 newHeapUsed = map['heap']['usedNew']; |
| 486 oldHeapUsed = map['heap']['usedOld']; | 616 oldHeapUsed = map['heap']['usedOld']; |
| 487 newHeapCapacity = map['heap']['capacityNew']; | 617 newHeapCapacity = map['heap']['capacityNew']; |
| 488 oldHeapCapacity = map['heap']['capacityOld']; | 618 oldHeapCapacity = map['heap']['capacityOld']; |
| 489 | 619 |
| 490 // Isolate status | 620 // Isolate status |
| 491 pausedOnStart = map['pausedOnStart']; | 621 pausedOnStart = map['pausedOnStart']; |
| 492 pausedOnExit = map['pausedOnExit']; | 622 pausedOnExit = map['pausedOnExit']; |
| 493 running = map['topFrame'] != null; | 623 running = map['topFrame'] != null; |
| 494 idle = !pausedOnStart && !pausedOnExit && !running; | 624 idle = !pausedOnStart && !pausedOnExit && !running; |
| 625 error = map['error']; | |
| 626 } | |
| 627 | |
| 628 Future<TagProfile> updateTagProfile() { | |
| 629 return vm.getAsMap(relativeLink('profile/tag')).then((ObservableMap m) { | |
| 630 var seconds = new DateTime.now().millisecondsSinceEpoch / 1000.0; | |
| 631 tagProfile._processTagProfile(seconds, m); | |
| 632 return tagProfile; | |
| 633 }); | |
| 495 } | 634 } |
| 496 | 635 |
| 497 @reflectable CodeTrieNode profileTrieRoot; | 636 @reflectable CodeTrieNode profileTrieRoot; |
| 498 // The profile trie is serialized as a list of integers. Each node | 637 // The profile trie is serialized as a list of integers. Each node |
| 499 // is recreated by consuming some portion of the list. The format is as | 638 // is recreated by consuming some portion of the list. The format is as |
| 500 // follows: | 639 // follows: |
| 501 // [0] index into codeTable of code object. | 640 // [0] index into codeTable of code object. |
| 502 // [1] tick count (number of times this stack frame occured). | 641 // [1] tick count (number of times this stack frame occured). |
| 503 // [2] child node count | 642 // [2] child node count |
| 504 // Reading the trie is done by recursively reading the tree depth-first | 643 // Reading the trie is done by recursively reading the tree depth-first |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 533 // Recursively read child nodes. | 672 // Recursively read child nodes. |
| 534 for (var i = 0; i < children; i++) { | 673 for (var i = 0; i < children; i++) { |
| 535 var child = _readTrieNode(codeTable); | 674 var child = _readTrieNode(codeTable); |
| 536 node.children.add(child); | 675 node.children.add(child); |
| 537 node.summedChildCount += child.count; | 676 node.summedChildCount += child.count; |
| 538 } | 677 } |
| 539 return node; | 678 return node; |
| 540 } | 679 } |
| 541 } | 680 } |
| 542 | 681 |
| 682 | |
|
turnidge
2014/03/25 17:52:53
Extra blank line.
Cutch
2014/03/25 18:01:52
Done.
| |
| 543 /// A [ServiceObject] which implements [ObservableMap]. | 683 /// A [ServiceObject] which implements [ObservableMap]. |
| 544 class ServiceMap extends ServiceObject implements ObservableMap { | 684 class ServiceMap extends ServiceObject implements ObservableMap { |
| 545 final ObservableMap _map = new ObservableMap(); | 685 final ObservableMap _map = new ObservableMap(); |
| 546 static String objectIdRingPrefix = 'objects/'; | 686 static String objectIdRingPrefix = 'objects/'; |
| 547 | 687 |
| 548 bool get canCache { | 688 bool get canCache { |
| 549 return (_serviceType == 'Class' || | 689 return (_serviceType == 'Class' || |
| 550 _serviceType == 'Function' || | 690 _serviceType == 'Function' || |
| 551 _serviceType == 'Library') && | 691 _serviceType == 'Library') && |
| 552 !_id.startsWith(objectIdRingPrefix); | 692 !_id.startsWith(objectIdRingPrefix); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 596 bool deliverChanges() => _map.deliverChanges(); | 736 bool deliverChanges() => _map.deliverChanges(); |
| 597 void notifyChange(ChangeRecord record) => _map.notifyChange(record); | 737 void notifyChange(ChangeRecord record) => _map.notifyChange(record); |
| 598 notifyPropertyChange(Symbol field, Object oldValue, Object newValue) => | 738 notifyPropertyChange(Symbol field, Object oldValue, Object newValue) => |
| 599 _map.notifyPropertyChange(field, oldValue, newValue); | 739 _map.notifyPropertyChange(field, oldValue, newValue); |
| 600 void observed() => _map.observed(); | 740 void observed() => _map.observed(); |
| 601 void unobserved() => _map.unobserved(); | 741 void unobserved() => _map.unobserved(); |
| 602 Stream<List<ChangeRecord>> get changes => _map.changes; | 742 Stream<List<ChangeRecord>> get changes => _map.changes; |
| 603 bool get hasObservers => _map.hasObservers; | 743 bool get hasObservers => _map.hasObservers; |
| 604 } | 744 } |
| 605 | 745 |
| 746 /// A [DartError] is peered to a Dart Error object. | |
| 747 class DartError extends ServiceObject { | |
| 748 DartError._empty(ServiceObject owner) : super._empty(owner); | |
| 749 | |
| 750 @observable String kind; | |
| 751 @observable String message; | |
| 752 @observable ServiceMap exception; | |
| 753 @observable ServiceMap stacktrace; | |
| 754 | |
| 755 void _update(ObservableMap map, bool mapIsRef) { | |
| 756 kind = map['kind']; | |
| 757 message = map['message']; | |
| 758 exception = new ServiceObject._fromMap(owner, map['exception']); | |
| 759 stacktrace = new ServiceObject._fromMap(owner, map['stacktrace']); | |
| 760 name = 'DartError $kind'; | |
| 761 vmName = name; | |
| 762 } | |
| 763 } | |
| 764 | |
| 765 /// A [ServiceError] is an error that was triggered in the service | |
| 766 /// server or client. Errors are prorammer mistakes that could have | |
| 767 /// been prevented, for example, requesting a non-existant path over the | |
| 768 /// service. | |
| 606 class ServiceError extends ServiceObject { | 769 class ServiceError extends ServiceObject { |
| 607 ServiceError._empty(ServiceObjectOwner owner) : super._empty(owner); | 770 ServiceError._empty(ServiceObjectOwner owner) : super._empty(owner); |
| 608 | 771 |
| 609 @observable String kind; | 772 @observable String kind; |
| 610 @observable String message; | 773 @observable String message; |
| 611 | 774 |
| 612 void _update(ObservableMap map, bool mapIsRef) { | 775 void _update(ObservableMap map, bool mapIsRef) { |
| 613 _loaded = true; | 776 _loaded = true; |
| 614 kind = map['kind']; | 777 kind = map['kind']; |
| 615 message = map['message']; | 778 message = map['message']; |
| 616 name = 'ServiceError $kind'; | 779 name = 'ServiceError $kind'; |
| 617 vmName = name; | 780 vmName = name; |
| 618 } | 781 } |
| 782 } | |
| 619 | 783 |
| 620 // TODO: stackTrace? | 784 /// A [ServiceException] is an exception that was triggered in the service |
| 785 /// server or client. Exceptions are events that should be handled, | |
| 786 /// for example, an isolate went away or the connection to the VM was lost. | |
| 787 class ServiceException extends ServiceObject { | |
| 788 ServiceException._empty(ServiceObject owner) : super._empty(owner); | |
| 789 | |
| 790 @observable String kind; | |
| 791 @observable String message; | |
| 792 @observable dynamic response; | |
| 793 | |
| 794 void _update(ObservableMap map, bool mapIsRef) { | |
| 795 kind = map['kind']; | |
| 796 message = map['message']; | |
| 797 response = map['response']; | |
| 798 name = 'ServiceException $kind'; | |
| 799 vmName = name; | |
| 800 } | |
| 621 } | 801 } |
| 622 | 802 |
| 623 class ScriptLine { | 803 class ScriptLine { |
| 624 @reflectable final int line; | 804 @reflectable final int line; |
| 625 @reflectable final String text; | 805 @reflectable final String text; |
| 626 ScriptLine(this.line, this.text); | 806 ScriptLine(this.line, this.text); |
| 627 } | 807 } |
| 628 | 808 |
| 629 class Script extends ServiceObject { | 809 class Script extends ServiceObject { |
| 630 @reflectable final lines = new ObservableList<ScriptLine>(); | 810 @reflectable final lines = new ObservableList<ScriptLine>(); |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 993 var v = list[i]; | 1173 var v = list[i]; |
| 994 if ((v is ObservableMap) && _isServiceMap(v)) { | 1174 if ((v is ObservableMap) && _isServiceMap(v)) { |
| 995 list[i] = owner.getFromMap(v); | 1175 list[i] = owner.getFromMap(v); |
| 996 } else if (v is ObservableList) { | 1176 } else if (v is ObservableList) { |
| 997 _upgradeObservableList(v, owner); | 1177 _upgradeObservableList(v, owner); |
| 998 } else if (v is ObservableMap) { | 1178 } else if (v is ObservableMap) { |
| 999 _upgradeObservableMap(v, owner); | 1179 _upgradeObservableMap(v, owner); |
| 1000 } | 1180 } |
| 1001 } | 1181 } |
| 1002 } | 1182 } |
| OLD | NEW |