| Index: runtime/bin/vmservice/client/lib/src/service/object.dart
|
| diff --git a/runtime/bin/vmservice/client/lib/src/service/object.dart b/runtime/bin/vmservice/client/lib/src/service/object.dart
|
| index 5e008d16d4e34474c361fd98c440a38b39849955..9319efe1da46017d6367b45a0b2758dd53fb7bd2 100644
|
| --- a/runtime/bin/vmservice/client/lib/src/service/object.dart
|
| +++ b/runtime/bin/vmservice/client/lib/src/service/object.dart
|
| @@ -99,6 +99,8 @@ abstract class ServiceObject extends Observable {
|
| return reload();
|
| }
|
|
|
| + Future<ServiceObject> _inProgressReload;
|
| +
|
| /// Reload [this]. Returns a future which completes to [this] or
|
| /// a [ServiceError].
|
| Future<ServiceObject> reload() {
|
| @@ -110,17 +112,23 @@ abstract class ServiceObject extends Observable {
|
| if (loaded && immutable) {
|
| return new Future.value(this);
|
| }
|
| - return vm.getAsMap(link).then((ObservableMap map) {
|
| - var mapType = _stripRef(map['type']);
|
| - if (mapType != _serviceType) {
|
| - // If the type changes, return a new object instead of
|
| - // updating the existing one.
|
| - assert(mapType == 'Error' || mapType == 'Null');
|
| - return new ServiceObject._fromMap(owner, map);
|
| - }
|
| - update(map);
|
| - return this;
|
| + if (_inProgressReload == null) {
|
| + _inProgressReload = vm.getAsMap(link).then((ObservableMap map) {
|
| + var mapType = _stripRef(map['type']);
|
| + if (mapType != _serviceType) {
|
| + // If the type changes, return a new object instead of
|
| + // updating the existing one.
|
| + assert(mapType == 'Error' || mapType == 'Null');
|
| + return new ServiceObject._fromMap(owner, map);
|
| + }
|
| + update(map);
|
| + return this;
|
| + }).whenComplete(() {
|
| + // This reload is complete.
|
| + _inProgressReload = null;
|
| });
|
| + }
|
| + return _inProgressReload;
|
| }
|
|
|
| /// Update [this] using [map] as a source. [map] can be a reference.
|
| @@ -819,6 +827,14 @@ class Script extends ServiceObject {
|
|
|
| Script._empty(ServiceObjectOwner owner) : super._empty(owner);
|
|
|
| + /// This function maps a token position to a line number.
|
| + int tokenToLine(int token) => _tokenToLine[token];
|
| + Map _tokenToLine;
|
| +
|
| + /// This function maps a token position to a column number.
|
| + int tokenToCol(int token) => _tokenToCol[token];
|
| + Map _tokenToCol;
|
| +
|
| void _update(ObservableMap map, bool mapIsRef) {
|
| kind = map['kind'];
|
| _url = map['name'];
|
| @@ -826,6 +842,26 @@ class Script extends ServiceObject {
|
| name = _shortUrl;
|
| vmName = _url;
|
| _processSource(map['source']);
|
| + _parseTokenPosTable(map['tokenPosTable']);
|
| + }
|
| +
|
| + void _parseTokenPosTable(List<List<int>> table) {
|
| + if (table == null) {
|
| + return;
|
| + }
|
| + _tokenToLine = {};
|
| + _tokenToCol = {};
|
| + for (var line in table) {
|
| + // Each entry begins with a line number...
|
| + var lineNumber = line[0];
|
| + for (var pos = 1; pos < line.length; pos += 2) {
|
| + // ...and is followed by (token offset, col number) pairs.
|
| + var tokenOffset = line[pos];
|
| + var colNumber = line[pos+1];
|
| + _tokenToLine[tokenOffset] = lineNumber;
|
| + _tokenToCol[tokenOffset] = colNumber;
|
| + }
|
| + }
|
| }
|
|
|
| void _processHits(List scriptHits) {
|
|
|