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 static int LexicalSortName(ServiceObject o1, ServiceObject o2) { | 10 static int LexicalSortName(ServiceObject o1, ServiceObject o2) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 81 break; | 81 break; |
| 82 case 'Function': | 82 case 'Function': |
| 83 obj = new ServiceFunction._empty(owner); | 83 obj = new ServiceFunction._empty(owner); |
| 84 break; | 84 break; |
| 85 case 'Isolate': | 85 case 'Isolate': |
| 86 obj = new Isolate._empty(owner.vm); | 86 obj = new Isolate._empty(owner.vm); |
| 87 break; | 87 break; |
| 88 case 'Library': | 88 case 'Library': |
| 89 obj = new Library._empty(owner); | 89 obj = new Library._empty(owner); |
| 90 break; | 90 break; |
| 91 case 'Null': | |
| 92 return null; | |
| 93 case 'ServiceError': | 91 case 'ServiceError': |
| 94 obj = new ServiceError._empty(owner); | 92 obj = new ServiceError._empty(owner); |
| 95 break; | 93 break; |
| 96 case 'ServiceEvent': | 94 case 'ServiceEvent': |
| 97 obj = new ServiceEvent._empty(owner); | 95 obj = new ServiceEvent._empty(owner); |
| 98 break; | 96 break; |
| 99 case 'ServiceException': | 97 case 'ServiceException': |
| 100 obj = new ServiceException._empty(owner); | 98 obj = new ServiceException._empty(owner); |
| 101 break; | 99 break; |
| 102 case 'Script': | 100 case 'Script': |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 261 map = _parseJSON(eventMessage); | 259 map = _parseJSON(eventMessage); |
| 262 } catch (e, st) { | 260 } catch (e, st) { |
| 263 Logger.root.severe('Ignoring malformed event message: ${eventMessage}'); | 261 Logger.root.severe('Ignoring malformed event message: ${eventMessage}'); |
| 264 return; | 262 return; |
| 265 } | 263 } |
| 266 if (map['type'] != 'ServiceEvent') { | 264 if (map['type'] != 'ServiceEvent') { |
| 267 Logger.root.severe( | 265 Logger.root.severe( |
| 268 "Expected 'ServiceEvent' but found '${map['type']}'"); | 266 "Expected 'ServiceEvent' but found '${map['type']}'"); |
| 269 return; | 267 return; |
| 270 } | 268 } |
| 269 | |
| 271 // Extract the owning isolate from the event itself. | 270 // Extract the owning isolate from the event itself. |
| 272 String owningIsolateId = map['isolate']['id']; | 271 String owningIsolateId = map['isolate']['id']; |
| 273 _getIsolate(owningIsolateId).then((owningIsolate) { | 272 _getIsolate(owningIsolateId).then((owningIsolate) { |
| 274 var event = new ServiceObject._fromMap(owningIsolate, map); | 273 var event = new ServiceObject._fromMap(owningIsolate, map); |
| 275 events.add(event); | 274 events.add(event); |
| 276 }); | 275 }); |
| 277 } | 276 } |
| 278 | 277 |
| 279 static final RegExp _currentIsolateMatcher = new RegExp(r'isolates/\d+'); | 278 static final RegExp _currentIsolateMatcher = new RegExp(r'isolates/\d+'); |
| 280 static final RegExp _currentObjectMatcher = new RegExp(r'isolates/\d+/'); | 279 static final RegExp _currentObjectMatcher = new RegExp(r'isolates/\d+/'); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 409 'message': 'Could not decode JSON: $e', | 408 'message': 'Could not decode JSON: $e', |
| 410 }))); | 409 }))); |
| 411 } | 410 } |
| 412 | 411 |
| 413 /// Gets [id] as an [ObservableMap] from the service directly. If | 412 /// Gets [id] as an [ObservableMap] from the service directly. If |
| 414 /// an error occurs, the future is completed as an error with a | 413 /// an error occurs, the future is completed as an error with a |
| 415 /// ServiceError or ServiceException. Therefore any chained then() calls | 414 /// ServiceError or ServiceException. Therefore any chained then() calls |
| 416 /// will only receive a map encoding a valid ServiceObject. | 415 /// will only receive a map encoding a valid ServiceObject. |
| 417 Future<ObservableMap> getAsMap(String id) { | 416 Future<ObservableMap> getAsMap(String id) { |
| 418 return getString(id).then((response) { | 417 return getString(id).then((response) { |
| 418 print("GOT $response"); | |
|
koda
2014/07/29 15:55:12
Seems you left some debug printing here. But this
Cutch
2014/07/29 17:04:35
We have the logging package for this. It's easy to
| |
| 419 var map = _parseJSON(response); | 419 var map = _parseJSON(response); |
| 420 return _processMap(map); | 420 return _processMap(map); |
| 421 }).catchError((error) { | 421 }).catchError((error) { |
| 422 // ServiceError, forward to VM's ServiceError stream. | 422 // ServiceError, forward to VM's ServiceError stream. |
| 423 errors.add(error); | 423 errors.add(error); |
| 424 return new Future.error(error); | 424 return new Future.error(error); |
| 425 }, test: (e) => e is ServiceError).catchError((exception) { | 425 }, test: (e) => e is ServiceError).catchError((exception) { |
| 426 // ServiceException, forward to VM's ServiceException stream. | 426 // ServiceException, forward to VM's ServiceException stream. |
| 427 exceptions.add(exception); | 427 exceptions.add(exception); |
| 428 return new Future.error(exception); | 428 return new Future.error(exception); |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 747 void _update(ObservableMap map, bool mapIsRef) { | 747 void _update(ObservableMap map, bool mapIsRef) { |
| 748 mainPort = map['mainPort']; | 748 mainPort = map['mainPort']; |
| 749 name = map['name']; | 749 name = map['name']; |
| 750 vmName = map['name']; | 750 vmName = map['name']; |
| 751 if (mapIsRef) { | 751 if (mapIsRef) { |
| 752 return; | 752 return; |
| 753 } | 753 } |
| 754 _loaded = true; | 754 _loaded = true; |
| 755 loading = false; | 755 loading = false; |
| 756 | 756 |
| 757 reloadBreakpoints(); | |
| 758 | |
| 757 // Remap DebuggerEvent to ServiceEvent so that the observatory can | 759 // Remap DebuggerEvent to ServiceEvent so that the observatory can |
| 758 // work against 1.5 vms in the short term. | 760 // work against 1.5 vms in the short term. |
| 759 // | 761 // |
| 760 // TODO(turnidge): Remove this when no longer needed. | 762 // TODO(turnidge): Remove this when no longer needed. |
| 761 var pause = map['pauseEvent']; | 763 var pause = map['pauseEvent']; |
| 762 if (pause != null) { | 764 if (pause != null) { |
| 763 if (pause['type'] == 'DebuggerEvent') { | 765 if (pause['type'] == 'DebuggerEvent') { |
| 764 pause['type'] = 'ServiceEvent'; | 766 pause['type'] = 'ServiceEvent'; |
| 765 } | 767 } |
| 766 } | 768 } |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 883 // Number of children. | 885 // Number of children. |
| 884 var children = _trieData[_trieDataCursor++]; | 886 var children = _trieData[_trieDataCursor++]; |
| 885 // Recursively read child nodes. | 887 // Recursively read child nodes. |
| 886 for (var i = 0; i < children; i++) { | 888 for (var i = 0; i < children; i++) { |
| 887 var child = _readTrieNode(codeTable); | 889 var child = _readTrieNode(codeTable); |
| 888 node.children.add(child); | 890 node.children.add(child); |
| 889 node.summedChildCount += child.count; | 891 node.summedChildCount += child.count; |
| 890 } | 892 } |
| 891 return node; | 893 return node; |
| 892 } | 894 } |
| 895 | |
| 896 ServiceMap breakpoints; | |
| 897 | |
| 898 void _removeBreakpoint(ServiceMap bpt) { | |
| 899 var script = bpt['location']['script']; | |
| 900 var tokenPos = bpt['location']['tokenPos']; | |
| 901 assert(tokenPos != null); | |
| 902 if (script.loaded) { | |
| 903 var line = script.tokenToLine(tokenPos); | |
| 904 assert(line != null); | |
| 905 assert(script.lines[line - 1].bpt == bpt); | |
| 906 script.lines[line - 1].bpt = null; | |
| 907 } | |
| 908 } | |
| 909 | |
| 910 void _addBreakpoint(ServiceMap bpt) { | |
| 911 var script = bpt['location']['script']; | |
| 912 var tokenPos = bpt['location']['tokenPos']; | |
| 913 assert(tokenPos != null); | |
| 914 if (script.loaded) { | |
| 915 var line = script.tokenToLine(tokenPos); | |
| 916 assert(line != null); | |
| 917 assert(script.lines[line - 1].bpt == null); | |
| 918 script.lines[line - 1].bpt = bpt; | |
| 919 } else { | |
| 920 // Load the script and then plop in the breakpoint. | |
| 921 script.load().then((_) { | |
| 922 _addBreakpoint(bpt); | |
| 923 }); | |
| 924 } | |
| 925 } | |
| 926 | |
| 927 void _updateBreakpoints(ServiceMap newBreakpoints) { | |
| 928 // Remove all of the old breakpoints from the Script lines. | |
| 929 if (breakpoints != null) { | |
| 930 for (var bpt in breakpoints['breakpoints']) { | |
| 931 _removeBreakpoint(bpt); | |
| 932 } | |
| 933 } | |
| 934 // Add all of the new breakpoints to the Script lines. | |
| 935 for (var bpt in newBreakpoints['breakpoints']) { | |
| 936 _addBreakpoint(bpt); | |
| 937 } | |
| 938 breakpoints = newBreakpoints; | |
| 939 } | |
| 940 | |
| 941 Future<ServiceObject> _inProgressReloadBpts; | |
| 942 | |
| 943 Future reloadBreakpoints() { | |
| 944 // TODO(turnidge): Can reusing the Future here ever cause us to | |
| 945 // get stale breakpoints? | |
| 946 if (_inProgressReloadBpts == null) { | |
| 947 _inProgressReloadBpts = | |
| 948 get('debug/breakpoints').then((newBpts) { | |
| 949 _updateBreakpoints(newBpts); | |
| 950 }).whenComplete(() { | |
| 951 _inProgressReloadBpts = null; | |
| 952 }); | |
| 953 } | |
| 954 return _inProgressReloadBpts; | |
| 955 } | |
| 956 | |
| 957 Future<ServiceObject> setBreakpoint(Script script, int line) { | |
| 958 return get(script.id + "/setBreakpoint?line=${line}").then((result) { | |
| 959 if (result is DartError) { | |
| 960 // Unable to set a breakpoint at desired line. | |
| 961 script.lines[line - 1].possibleBpt = false; | |
| 962 } | |
| 963 return reloadBreakpoints(); | |
| 964 }); | |
| 965 } | |
| 966 | |
| 967 Future clearBreakpoint(ServiceMap bpt) { | |
| 968 return get('${bpt.id}/clear').then((result) { | |
| 969 if (result is DartError) { | |
| 970 // TODO(turnidge): Handle this more gracefully. | |
| 971 Logger.root.severe(result.message); | |
| 972 } | |
| 973 if (pauseEvent != null && | |
| 974 pauseEvent.breakpoint != null && | |
| 975 (pauseEvent.breakpoint['id'] == bpt['id'])) { | |
| 976 return isolate.reload(); | |
| 977 } else { | |
| 978 return reloadBreakpoints(); | |
| 979 } | |
| 980 }); | |
| 981 } | |
| 982 | |
| 983 Future pause() { | |
| 984 return get("debug/pause").then((result) { | |
| 985 if (result is DartError) { | |
| 986 // TODO(turnidge): Handle this more gracefully. | |
| 987 Logger.root.severe(result.message); | |
| 988 } | |
| 989 return isolate.reload(); | |
| 990 }); | |
| 991 } | |
| 992 | |
| 993 Future resume() { | |
| 994 return get("debug/resume").then((result) { | |
| 995 if (result is DartError) { | |
| 996 // TODO(turnidge): Handle this more gracefully. | |
| 997 Logger.root.severe(result.message); | |
| 998 } | |
| 999 return isolate.reload(); | |
| 1000 }); | |
| 1001 } | |
| 1002 | |
| 1003 Future stepInto() { | |
| 1004 print('isolate.stepInto'); | |
| 1005 return get("debug/resume?step=into").then((result) { | |
| 1006 if (result is DartError) { | |
| 1007 // TODO(turnidge): Handle this more gracefully. | |
| 1008 Logger.root.severe(result.message); | |
| 1009 } | |
| 1010 return isolate.reload(); | |
| 1011 }); | |
| 1012 } | |
| 1013 | |
| 1014 Future stepOver() { | |
| 1015 return get("debug/resume?step=over").then((result) { | |
| 1016 if (result is DartError) { | |
| 1017 // TODO(turnidge): Handle this more gracefully. | |
| 1018 Logger.root.severe(result.message); | |
| 1019 } | |
| 1020 return isolate.reload(); | |
| 1021 }); | |
| 1022 } | |
| 1023 | |
| 1024 Future stepOut() { | |
| 1025 return get("debug/resume?step=out").then((result) { | |
| 1026 if (result is DartError) { | |
| 1027 // TODO(turnidge): Handle this more gracefully. | |
| 1028 Logger.root.severe(result.message); | |
| 1029 } | |
| 1030 return isolate.reload(); | |
| 1031 }); | |
| 1032 } | |
| 893 } | 1033 } |
| 894 | 1034 |
| 895 /// A [ServiceObject] which implements [ObservableMap]. | 1035 /// A [ServiceObject] which implements [ObservableMap]. |
| 896 class ServiceMap extends ServiceObject implements ObservableMap { | 1036 class ServiceMap extends ServiceObject implements ObservableMap { |
| 897 final ObservableMap _map = new ObservableMap(); | 1037 final ObservableMap _map = new ObservableMap(); |
| 898 static String objectIdRingPrefix = 'objects/'; | 1038 static String objectIdRingPrefix = 'objects/'; |
| 899 | 1039 |
| 900 bool get canCache { | 1040 bool get canCache { |
| 901 return (_serviceType == 'Class' || | 1041 return (_serviceType == 'Class' || |
| 902 _serviceType == 'Function' || | 1042 _serviceType == 'Function' || |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1300 isDart = !kind.isFake(); | 1440 isDart = !kind.isFake(); |
| 1301 | 1441 |
| 1302 if (mapIsRef) { return; } | 1442 if (mapIsRef) { return; } |
| 1303 | 1443 |
| 1304 isStatic = map['isStatic']; | 1444 isStatic = map['isStatic']; |
| 1305 isConst = map['isConst']; | 1445 isConst = map['isConst']; |
| 1306 parent = map['parent']; | 1446 parent = map['parent']; |
| 1307 script = map['script']; | 1447 script = map['script']; |
| 1308 tokenPos = map['tokenPos']; | 1448 tokenPos = map['tokenPos']; |
| 1309 endTokenPos = map['endTokenPos']; | 1449 endTokenPos = map['endTokenPos']; |
| 1310 code = map['code']; | 1450 code = _convertNull(map['code']); |
| 1311 unoptimizedCode = map['unoptimized_code']; | 1451 unoptimizedCode = _convertNull(map['unoptimized_code']); |
| 1312 isOptimizable = map['is_optimizable']; | 1452 isOptimizable = map['is_optimizable']; |
| 1313 isInlinable = map['is_inlinable']; | 1453 isInlinable = map['is_inlinable']; |
| 1314 deoptimizations = map['deoptimizations']; | 1454 deoptimizations = map['deoptimizations']; |
| 1315 usageCounter = map['usage_counter']; | 1455 usageCounter = map['usage_counter']; |
| 1316 | 1456 |
| 1317 if (parent == null) { | 1457 if (parent == null) { |
| 1318 qualifiedName = (owningClass != null) ? | 1458 qualifiedName = (owningClass != null) ? |
| 1319 "${owningClass.name}.${name}" : | 1459 "${owningClass.name}.${name}" : |
| 1320 name; | 1460 name; |
| 1321 } else { | 1461 } else { |
| 1322 qualifiedName = "${parent.qualifiedName}.${name}"; | 1462 qualifiedName = "${parent.qualifiedName}.${name}"; |
| 1323 } | 1463 } |
| 1324 | 1464 |
| 1325 } | 1465 } |
| 1326 } | 1466 } |
| 1327 | 1467 |
| 1328 class ScriptLine extends Observable { | 1468 class ScriptLine extends Observable { |
| 1469 final Script script; | |
| 1329 final int line; | 1470 final int line; |
| 1330 final String text; | 1471 final String text; |
| 1331 @observable int hits; | 1472 @observable int hits; |
| 1332 ScriptLine(this.line, this.text); | 1473 @observable ServiceMap bpt; |
| 1474 @observable bool possibleBpt = true; | |
| 1475 | |
| 1476 static bool _isTrivialToken(String token) { | |
| 1477 if (token == 'else') { | |
| 1478 return true; | |
| 1479 } | |
| 1480 for (var c in token.split('')) { | |
| 1481 switch (c) { | |
| 1482 case '{': | |
| 1483 case '}': | |
| 1484 case '(': | |
| 1485 case ')': | |
| 1486 case ';': | |
| 1487 break; | |
| 1488 default: | |
| 1489 return false; | |
| 1490 } | |
| 1491 } | |
| 1492 return true; | |
| 1493 } | |
| 1494 | |
| 1495 static bool _isTrivialLine(String text) { | |
| 1496 var wsTokens = text.split(new RegExp(r"(\s)+")); | |
| 1497 for (var wsToken in wsTokens) { | |
| 1498 var tokens = wsToken.split(new RegExp(r"(\b)")); | |
| 1499 for (var token in tokens) { | |
| 1500 if (!_isTrivialToken(token)) { | |
| 1501 return false; | |
| 1502 } | |
| 1503 } | |
| 1504 } | |
| 1505 return true; | |
| 1506 } | |
| 1507 | |
| 1508 ScriptLine(this.script, this.line, this.text) { | |
| 1509 possibleBpt = !_isTrivialLine(text); | |
| 1510 | |
| 1511 // TODO(turnidge): This is not so efficient. Consider improving. | |
| 1512 for (var bpt in this.script.isolate.breakpoints['breakpoints']) { | |
| 1513 var bptScript = bpt['location']['script']; | |
| 1514 var bptTokenPos = bpt['location']['tokenPos']; | |
| 1515 if (bptScript == this.script && | |
| 1516 bptScript.tokenToLine(bptTokenPos) == line) { | |
| 1517 this.bpt = bpt; | |
| 1518 } | |
| 1519 } | |
| 1520 } | |
| 1333 } | 1521 } |
| 1334 | 1522 |
| 1335 class Script extends ServiceObject with Coverage { | 1523 class Script extends ServiceObject with Coverage { |
| 1336 final lines = new ObservableList<ScriptLine>(); | 1524 final lines = new ObservableList<ScriptLine>(); |
| 1337 final _hits = new Map<int, int>(); | 1525 final _hits = new Map<int, int>(); |
| 1338 @observable String kind; | 1526 @observable String kind; |
| 1339 @observable int firstTokenPos; | 1527 @observable int firstTokenPos; |
| 1340 @observable int lastTokenPos; | 1528 @observable int lastTokenPos; |
| 1341 @observable Library owningLibrary; | 1529 @observable Library owningLibrary; |
| 1342 bool get canCache => true; | 1530 bool get canCache => true; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1376 } | 1564 } |
| 1377 | 1565 |
| 1378 void _parseTokenPosTable(List<List<int>> table) { | 1566 void _parseTokenPosTable(List<List<int>> table) { |
| 1379 if (table == null) { | 1567 if (table == null) { |
| 1380 return; | 1568 return; |
| 1381 } | 1569 } |
| 1382 _tokenToLine.clear(); | 1570 _tokenToLine.clear(); |
| 1383 _tokenToCol.clear(); | 1571 _tokenToCol.clear(); |
| 1384 firstTokenPos = null; | 1572 firstTokenPos = null; |
| 1385 lastTokenPos = null; | 1573 lastTokenPos = null; |
| 1574 var lineSet = new Set(); | |
| 1575 | |
| 1386 for (var line in table) { | 1576 for (var line in table) { |
| 1387 // Each entry begins with a line number... | 1577 // Each entry begins with a line number... |
| 1388 var lineNumber = line[0]; | 1578 var lineNumber = line[0]; |
| 1579 lineSet.add(lineNumber); | |
| 1389 for (var pos = 1; pos < line.length; pos += 2) { | 1580 for (var pos = 1; pos < line.length; pos += 2) { |
| 1390 // ...and is followed by (token offset, col number) pairs. | 1581 // ...and is followed by (token offset, col number) pairs. |
| 1391 var tokenOffset = line[pos]; | 1582 var tokenOffset = line[pos]; |
| 1392 var colNumber = line[pos+1]; | 1583 var colNumber = line[pos+1]; |
| 1393 if (firstTokenPos == null) { | 1584 if (firstTokenPos == null) { |
| 1394 // Mark first token position. | 1585 // Mark first token position. |
| 1395 firstTokenPos = tokenOffset; | 1586 firstTokenPos = tokenOffset; |
| 1396 lastTokenPos = tokenOffset; | 1587 lastTokenPos = tokenOffset; |
| 1397 } else { | 1588 } else { |
| 1398 // Keep track of max and min token positions. | 1589 // Keep track of max and min token positions. |
| 1399 firstTokenPos = (firstTokenPos <= tokenOffset) ? | 1590 firstTokenPos = (firstTokenPos <= tokenOffset) ? |
| 1400 firstTokenPos : tokenOffset; | 1591 firstTokenPos : tokenOffset; |
| 1401 lastTokenPos = (lastTokenPos >= tokenOffset) ? | 1592 lastTokenPos = (lastTokenPos >= tokenOffset) ? |
| 1402 lastTokenPos : tokenOffset; | 1593 lastTokenPos : tokenOffset; |
| 1403 } | 1594 } |
| 1404 _tokenToLine[tokenOffset] = lineNumber; | 1595 _tokenToLine[tokenOffset] = lineNumber; |
| 1405 _tokenToCol[tokenOffset] = colNumber; | 1596 _tokenToCol[tokenOffset] = colNumber; |
| 1406 } | 1597 } |
| 1407 } | 1598 } |
| 1599 | |
| 1600 for (var line in lines) { | |
| 1601 // Remove possible breakpoints on lines with no tokens. | |
| 1602 if (!lineSet.contains(line.line)) { | |
| 1603 line.possibleBpt = false; | |
| 1604 } | |
| 1605 } | |
| 1408 } | 1606 } |
| 1409 | 1607 |
| 1410 void _processHits(List scriptHits) { | 1608 void _processHits(List scriptHits) { |
| 1411 // Update hits table. | 1609 // Update hits table. |
| 1412 for (var i = 0; i < scriptHits.length; i += 2) { | 1610 for (var i = 0; i < scriptHits.length; i += 2) { |
| 1413 var line = scriptHits[i]; | 1611 var line = scriptHits[i]; |
| 1414 var hit = scriptHits[i + 1]; // hit status. | 1612 var hit = scriptHits[i + 1]; // hit status. |
| 1415 assert(line >= 1); // Lines start at 1. | 1613 assert(line >= 1); // Lines start at 1. |
| 1416 var oldHits = _hits[line]; | 1614 var oldHits = _hits[line]; |
| 1417 if (oldHits != null) { | 1615 if (oldHits != null) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1430 } | 1628 } |
| 1431 var sourceLines = source.split('\n'); | 1629 var sourceLines = source.split('\n'); |
| 1432 if (sourceLines.length == 0) { | 1630 if (sourceLines.length == 0) { |
| 1433 return; | 1631 return; |
| 1434 } | 1632 } |
| 1435 // We have the source to the script. This is now loaded. | 1633 // We have the source to the script. This is now loaded. |
| 1436 _loaded = true; | 1634 _loaded = true; |
| 1437 lines.clear(); | 1635 lines.clear(); |
| 1438 Logger.root.info('Adding ${sourceLines.length} source lines for ${_url}'); | 1636 Logger.root.info('Adding ${sourceLines.length} source lines for ${_url}'); |
| 1439 for (var i = 0; i < sourceLines.length; i++) { | 1637 for (var i = 0; i < sourceLines.length; i++) { |
| 1440 lines.add(new ScriptLine(i + 1, sourceLines[i])); | 1638 lines.add(new ScriptLine(this, i + 1, sourceLines[i])); |
| 1441 } | 1639 } |
| 1442 _applyHitsToLines(); | 1640 _applyHitsToLines(); |
| 1443 } | 1641 } |
| 1444 | 1642 |
| 1445 void _applyHitsToLines() { | 1643 void _applyHitsToLines() { |
| 1446 if (lines.length == 0) { | |
| 1447 return; | |
| 1448 } | |
| 1449 for (var line in lines) { | 1644 for (var line in lines) { |
| 1450 var hits = _hits[line.line]; | 1645 var hits = _hits[line.line]; |
| 1451 line.hits = hits; | 1646 line.hits = hits; |
| 1452 } | 1647 } |
| 1453 } | 1648 } |
| 1454 } | 1649 } |
| 1455 | 1650 |
| 1456 class CodeTick { | 1651 class CodeTick { |
| 1457 final int address; | 1652 final int address; |
| 1458 final int exclusiveTicks; | 1653 final int exclusiveTicks; |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1983 localAddress = map['localAddress']; | 2178 localAddress = map['localAddress']; |
| 1984 localPort = map['localPort']; | 2179 localPort = map['localPort']; |
| 1985 remoteAddress = map['remoteAddress']; | 2180 remoteAddress = map['remoteAddress']; |
| 1986 remotePort = map['remotePort']; | 2181 remotePort = map['remotePort']; |
| 1987 | 2182 |
| 1988 fd = map['fd']; | 2183 fd = map['fd']; |
| 1989 socketOwner = map['owner']; | 2184 socketOwner = map['owner']; |
| 1990 } | 2185 } |
| 1991 } | 2186 } |
| 1992 | 2187 |
| 2188 // Convert any ServiceMaps representing a null instance into an actual null. | |
| 2189 _convertNull(obj) { | |
| 2190 if (obj is ServiceMap && | |
| 2191 obj.serviceType == 'Null') { | |
| 2192 return null; | |
| 2193 } | |
| 2194 return obj; | |
| 2195 } | |
| 2196 | |
| 1993 // Returns true if [map] is a service map. i.e. it has the following keys: | 2197 // Returns true if [map] is a service map. i.e. it has the following keys: |
| 1994 // 'id' and a 'type'. | 2198 // 'id' and a 'type'. |
| 1995 bool _isServiceMap(ObservableMap m) { | 2199 bool _isServiceMap(ObservableMap m) { |
| 1996 return (m != null) && (m['id'] != null) && (m['type'] != null); | 2200 return (m != null) && (m['id'] != null) && (m['type'] != null); |
| 1997 } | 2201 } |
| 1998 | 2202 |
| 1999 bool _hasRef(String type) => type.startsWith('@'); | 2203 bool _hasRef(String type) => type.startsWith('@'); |
| 2000 String _stripRef(String type) => (_hasRef(type) ? type.substring(1) : type); | 2204 String _stripRef(String type) => (_hasRef(type) ? type.substring(1) : type); |
| 2001 | 2205 |
| 2002 /// Recursively upgrades all [ServiceObject]s inside [collection] which must | 2206 /// Recursively upgrades all [ServiceObject]s inside [collection] which must |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 2030 var v = list[i]; | 2234 var v = list[i]; |
| 2031 if ((v is ObservableMap) && _isServiceMap(v)) { | 2235 if ((v is ObservableMap) && _isServiceMap(v)) { |
| 2032 list[i] = owner.getFromMap(v); | 2236 list[i] = owner.getFromMap(v); |
| 2033 } else if (v is ObservableList) { | 2237 } else if (v is ObservableList) { |
| 2034 _upgradeObservableList(v, owner); | 2238 _upgradeObservableList(v, owner); |
| 2035 } else if (v is ObservableMap) { | 2239 } else if (v is ObservableMap) { |
| 2036 _upgradeObservableMap(v, owner); | 2240 _upgradeObservableMap(v, owner); |
| 2037 } | 2241 } |
| 2038 } | 2242 } |
| 2039 } | 2243 } |
| OLD | NEW |