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 /// Helper function for canceling a Future<StreamSubscription>. | 7 /// Helper function for canceling a Future<StreamSubscription>. |
8 Future cancelFutureSubscription( | 8 Future cancelFutureSubscription( |
9 Future<StreamSubscription> subscriptionFuture) async { | 9 Future<StreamSubscription> subscriptionFuture) async { |
10 if (subscriptionFuture != null) { | 10 if (subscriptionFuture != null) { |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 break; | 210 break; |
211 case 'Library': | 211 case 'Library': |
212 obj = new Library._empty(owner); | 212 obj = new Library._empty(owner); |
213 break; | 213 break; |
214 case 'Message': | 214 case 'Message': |
215 obj = new ServiceMessage._empty(owner); | 215 obj = new ServiceMessage._empty(owner); |
216 break; | 216 break; |
217 case 'SourceLocation': | 217 case 'SourceLocation': |
218 obj = new SourceLocation._empty(owner); | 218 obj = new SourceLocation._empty(owner); |
219 break; | 219 break; |
| 220 case 'UnresolvedSourceLocation': |
| 221 obj = new UnresolvedSourceLocation._empty(owner); |
| 222 break; |
220 case 'Object': | 223 case 'Object': |
221 switch (vmType) { | 224 switch (vmType) { |
222 case 'ICData': | 225 case 'ICData': |
223 obj = new ICData._empty(owner); | 226 obj = new ICData._empty(owner); |
224 break; | 227 break; |
225 case 'Instructions': | 228 case 'Instructions': |
226 obj = new Instructions._empty(owner); | 229 obj = new Instructions._empty(owner); |
227 break; | 230 break; |
228 case 'LocalVarDescriptors': | 231 case 'LocalVarDescriptors': |
229 obj = new LocalVarDescriptors._empty(owner); | 232 obj = new LocalVarDescriptors._empty(owner); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 /// be [loaded]. | 428 /// be [loaded]. |
426 ServiceObject getFromMap(ObservableMap map); | 429 ServiceObject getFromMap(ObservableMap map); |
427 } | 430 } |
428 | 431 |
429 /// A [SourceLocation] represents a location or range in the source code. | 432 /// A [SourceLocation] represents a location or range in the source code. |
430 class SourceLocation extends ServiceObject { | 433 class SourceLocation extends ServiceObject { |
431 Script script; | 434 Script script; |
432 int tokenPos; | 435 int tokenPos; |
433 int endTokenPos; | 436 int endTokenPos; |
434 | 437 |
| 438 Future<int> getLine() async { |
| 439 await script.load(); |
| 440 return script.tokenToLine(tokenPos); |
| 441 } |
| 442 |
| 443 Future<int> getColumn() async { |
| 444 await script.load(); |
| 445 return script.tokenToCol(tokenPos); |
| 446 } |
| 447 |
435 SourceLocation._empty(ServiceObject owner) : super._empty(owner); | 448 SourceLocation._empty(ServiceObject owner) : super._empty(owner); |
436 | 449 |
437 void _update(ObservableMap map, bool mapIsRef) { | 450 void _update(ObservableMap map, bool mapIsRef) { |
438 assert(!mapIsRef); | 451 assert(!mapIsRef); |
439 _upgradeCollection(map, owner); | 452 _upgradeCollection(map, owner); |
440 script = map['script']; | 453 script = map['script']; |
441 tokenPos = map['tokenPos']; | 454 tokenPos = map['tokenPos']; |
| 455 endTokenPos = map['endTokenPos']; |
| 456 |
442 assert(script != null && tokenPos != null); | 457 assert(script != null && tokenPos != null); |
443 endTokenPos = map['endTokenPos']; | 458 } |
| 459 |
| 460 Future<String> toUserString() async { |
| 461 int line = await getLine(); |
| 462 int column = await getColumn(); |
| 463 return '${script.name}:${line}:${column}'; |
444 } | 464 } |
445 | 465 |
446 String toString() { | 466 String toString() { |
447 if (endTokenPos == null) { | 467 if (endTokenPos == null) { |
448 return '${script.name}:token(${tokenPos})'; | 468 return '${script.name}:token(${tokenPos})'; |
449 } else { | 469 } else { |
450 return '${script.name}:tokens(${tokenPos}-${endTokenPos})'; | 470 return '${script.name}:tokens(${tokenPos}-${endTokenPos})'; |
451 } | 471 } |
452 } | 472 } |
453 } | 473 } |
454 | 474 |
| 475 /// An [UnresolvedSourceLocation] represents a location in the source |
| 476 // code which has not been precisely mapped to a token position. |
| 477 class UnresolvedSourceLocation extends ServiceObject { |
| 478 Script script; |
| 479 String scriptUri; |
| 480 int line; |
| 481 int column; |
| 482 int tokenPos; |
| 483 |
| 484 Future<int> getLine() async { |
| 485 if (tokenPos != null) { |
| 486 await script.load(); |
| 487 return script.tokenToLine(tokenPos); |
| 488 } else { |
| 489 return line; |
| 490 } |
| 491 } |
| 492 |
| 493 Future<int> getColumn() async { |
| 494 if (tokenPos != null) { |
| 495 await script.load(); |
| 496 return script.tokenToCol(tokenPos); |
| 497 } else { |
| 498 return column; |
| 499 } |
| 500 } |
| 501 |
| 502 UnresolvedSourceLocation._empty(ServiceObject owner) : super._empty(owner); |
| 503 |
| 504 void _update(ObservableMap map, bool mapIsRef) { |
| 505 assert(!mapIsRef); |
| 506 _upgradeCollection(map, owner); |
| 507 script = map['script']; |
| 508 scriptUri = map['scriptUri']; |
| 509 line = map['line']; |
| 510 column = map['column']; |
| 511 tokenPos = map['tokenPos']; |
| 512 |
| 513 assert(script != null || scriptUri != null); |
| 514 assert(line != null || tokenPos != null); |
| 515 } |
| 516 |
| 517 Future<String> toUserString() async { |
| 518 StringBuffer sb = new StringBuffer(); |
| 519 |
| 520 int line = await getLine(); |
| 521 int column = await getColumn(); |
| 522 |
| 523 if (script != null) { |
| 524 sb.write('${script.name}:'); |
| 525 } else { |
| 526 sb.write('${scriptUri}:'); |
| 527 } |
| 528 if (column != null) { |
| 529 sb.write('${line}:${column}'); |
| 530 } else { |
| 531 sb.write('${line}'); |
| 532 } |
| 533 return sb.toString(); |
| 534 } |
| 535 |
| 536 String toString() { |
| 537 StringBuffer sb = new StringBuffer(); |
| 538 if (script != null) { |
| 539 sb.write('${script.name}:'); |
| 540 } else { |
| 541 sb.write('${scriptUri}:'); |
| 542 } |
| 543 if (tokenPos != null) { |
| 544 sb.write('token(${tokenPos})'); |
| 545 } else if (column != null) { |
| 546 sb.write('${line}:${column}'); |
| 547 } else { |
| 548 sb.write('${line}'); |
| 549 } |
| 550 sb.write('[unresolved]'); |
| 551 return sb.toString(); |
| 552 } |
| 553 } |
| 554 |
455 class _EventStreamState { | 555 class _EventStreamState { |
456 VM _vm; | 556 VM _vm; |
457 String streamId; | 557 String streamId; |
458 | 558 |
459 Function _onDone; | 559 Function _onDone; |
460 | 560 |
461 // A list of all subscribed controllers for this stream. | 561 // A list of all subscribed controllers for this stream. |
462 List _controllers = []; | 562 List _controllers = []; |
463 | 563 |
464 // Completes when the listen rpc is finished. | 564 // Completes when the listen rpc is finished. |
(...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1383 // Ignore GC events for now. | 1483 // Ignore GC events for now. |
1384 break; | 1484 break; |
1385 | 1485 |
1386 default: | 1486 default: |
1387 // Log unrecognized events. | 1487 // Log unrecognized events. |
1388 Logger.root.severe('Unrecognized event: $event'); | 1488 Logger.root.severe('Unrecognized event: $event'); |
1389 break; | 1489 break; |
1390 } | 1490 } |
1391 } | 1491 } |
1392 | 1492 |
1393 Future<ServiceObject> addBreakpoint(Script script, int line) async { | 1493 Future<ServiceObject> addBreakpoint( |
| 1494 Script script, int line, [int col]) async { |
1394 // TODO(turnidge): Pass line as an int instead of a string. | 1495 // TODO(turnidge): Pass line as an int instead of a string. |
1395 try { | 1496 try { |
1396 Map params = { | 1497 Map params = { |
1397 'scriptId': script.id, | 1498 'scriptId': script.id, |
1398 'line': '$line', | 1499 'line': line.toString(), |
1399 }; | 1500 }; |
| 1501 if (col != null) { |
| 1502 params['column'] = col.toString(); |
| 1503 } |
1400 Breakpoint bpt = await invokeRpc('addBreakpoint', params); | 1504 Breakpoint bpt = await invokeRpc('addBreakpoint', params); |
1401 if (bpt.resolved && | 1505 if (bpt.resolved && |
1402 script.loaded && | 1506 script.loaded && |
1403 script.tokenToLine(bpt.location.tokenPos) != line) { | 1507 script.tokenToLine(bpt.location.tokenPos) != line) { |
1404 // TODO(turnidge): Can this still happen? | 1508 // TODO(turnidge): Can this still happen? |
1405 script.getLine(line).possibleBpt = false; | 1509 script.getLine(line).possibleBpt = false; |
1406 } | 1510 } |
1407 return bpt; | 1511 return bpt; |
1408 } on ServerRpcException catch(e) { | 1512 } on ServerRpcException catch(e) { |
1409 if (e.code == ServerRpcException.kCannotAddBreakpoint) { | 1513 if (e.code == ServerRpcException.kCannotAddBreakpoint) { |
1410 // Unable to set a breakpoint at the desired line. | 1514 // Unable to set a breakpoint at the desired line. |
1411 script.getLine(line).possibleBpt = false; | 1515 script.getLine(line).possibleBpt = false; |
1412 } | 1516 } |
1413 rethrow; | 1517 rethrow; |
1414 } | 1518 } |
1415 } | 1519 } |
1416 | 1520 |
| 1521 Future<ServiceObject> addBreakpointByScriptUri( |
| 1522 String uri, int line, [int col]) { |
| 1523 Map params = { |
| 1524 'scriptUri': uri, |
| 1525 'line': line.toString(), |
| 1526 }; |
| 1527 if (col != null) { |
| 1528 params['column'] = col.toString(); |
| 1529 } |
| 1530 return invokeRpc('addBreakpoint', params); |
| 1531 } |
| 1532 |
1417 Future<ServiceObject> addBreakpointAtEntry(ServiceFunction function) { | 1533 Future<ServiceObject> addBreakpointAtEntry(ServiceFunction function) { |
1418 return invokeRpc('addBreakpointAtEntry', | 1534 return invokeRpc('addBreakpointAtEntry', |
1419 { 'functionId': function.id }); | 1535 { 'functionId': function.id }); |
1420 } | 1536 } |
1421 | 1537 |
1422 Future<ServiceObject> addBreakOnActivation(Instance closure) { | 1538 Future<ServiceObject> addBreakOnActivation(Instance closure) { |
1423 return invokeRpc('_addBreakpointAtActivation', | 1539 return invokeRpc('_addBreakpointAtActivation', |
1424 { 'objectId': closure.id }); | 1540 { 'objectId': closure.id }); |
1425 } | 1541 } |
1426 | 1542 |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1848 Breakpoint._empty(ServiceObjectOwner owner) : super._empty(owner); | 1964 Breakpoint._empty(ServiceObjectOwner owner) : super._empty(owner); |
1849 | 1965 |
1850 // TODO(turnidge): Add state to track if a breakpoint has been | 1966 // TODO(turnidge): Add state to track if a breakpoint has been |
1851 // removed from the program. Remove from the cache when deleted. | 1967 // removed from the program. Remove from the cache when deleted. |
1852 bool get canCache => true; | 1968 bool get canCache => true; |
1853 bool get immutable => false; | 1969 bool get immutable => false; |
1854 | 1970 |
1855 // A unique integer identifier for this breakpoint. | 1971 // A unique integer identifier for this breakpoint. |
1856 @observable int number; | 1972 @observable int number; |
1857 | 1973 |
1858 // Source location information. | 1974 // Either SourceLocation or UnresolvedSourceLocation. |
1859 @observable SourceLocation location; | 1975 @observable ServiceObject location; |
| 1976 |
| 1977 // The breakpoint is in a file which is not yet loaded. |
| 1978 @observable bool latent; |
1860 | 1979 |
1861 // The breakpoint has been assigned to a final source location. | 1980 // The breakpoint has been assigned to a final source location. |
1862 @observable bool resolved; | 1981 @observable bool resolved; |
1863 | 1982 |
1864 void _update(ObservableMap map, bool mapIsRef) { | 1983 void _update(ObservableMap map, bool mapIsRef) { |
1865 _loaded = true; | 1984 _loaded = true; |
1866 _upgradeCollection(map, owner); | 1985 _upgradeCollection(map, owner); |
1867 | 1986 |
1868 var newNumber = map['breakpointNumber']; | 1987 var newNumber = map['breakpointNumber']; |
1869 // number never changes. | 1988 // number never changes. |
1870 assert((number == null) || (number == newNumber)); | 1989 assert((number == null) || (number == newNumber)); |
1871 number = newNumber; | 1990 number = newNumber; |
1872 | |
1873 resolved = map['resolved']; | 1991 resolved = map['resolved']; |
1874 | 1992 |
1875 var oldLocation = location; | 1993 var oldLocation = location; |
1876 var newLocation = map['location']; | 1994 var newLocation = map['location']; |
1877 var oldScript; | 1995 if (oldLocation is UnresolvedSourceLocation && |
1878 var newScript; | 1996 newLocation is SourceLocation) { |
1879 var oldTokenPos; | 1997 // Breakpoint has been resolved. Remove old breakpoint. |
1880 var newTokenPos; | 1998 var oldScript = oldLocation.script; |
1881 if (oldLocation != null) { | 1999 if (oldScript != null && oldScript.loaded) { |
1882 oldScript = location.script; | |
1883 oldTokenPos = location.tokenPos; | |
1884 } | |
1885 if (newLocation != null) { | |
1886 newScript = newLocation.script; | |
1887 newTokenPos = newLocation.tokenPos; | |
1888 } | |
1889 // script never changes | |
1890 assert((oldScript == null) || (oldScript == newScript)); | |
1891 bool tokenPosChanged = oldTokenPos != newTokenPos; | |
1892 if (newScript.loaded && | |
1893 (newTokenPos != null) && | |
1894 tokenPosChanged) { | |
1895 // The breakpoint has moved. Remove it and add it later. | |
1896 if (oldScript != null) { | |
1897 oldScript._removeBreakpoint(this); | 2000 oldScript._removeBreakpoint(this); |
1898 } | 2001 } |
1899 } | 2002 } |
1900 location = newLocation; | 2003 location = newLocation; |
1901 if (newScript.loaded && tokenPosChanged) { | 2004 var newScript = location.script; |
| 2005 if (newScript != null && newScript.loaded) { |
1902 newScript._addBreakpoint(this); | 2006 newScript._addBreakpoint(this); |
1903 } | 2007 } |
| 2008 |
| 2009 assert(resolved || location is UnresolvedSourceLocation); |
1904 } | 2010 } |
1905 | 2011 |
1906 void remove() { | 2012 void remove() { |
1907 // Remove any references to this breakpoint. It has been removed. | 2013 // Remove any references to this breakpoint. It has been removed. |
1908 location.script._removeBreakpoint(this); | 2014 location.script._removeBreakpoint(this); |
1909 if ((isolate.pauseEvent != null) && | 2015 if ((isolate.pauseEvent != null) && |
1910 (isolate.pauseEvent.breakpoint != null) && | 2016 (isolate.pauseEvent.breakpoint != null) && |
1911 (isolate.pauseEvent.breakpoint.id == id)) { | 2017 (isolate.pauseEvent.breakpoint.id == id)) { |
1912 isolate.pauseEvent.breakpoint = null; | 2018 isolate.pauseEvent.breakpoint = null; |
1913 } | 2019 } |
(...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2886 } | 2992 } |
2887 | 2993 |
2888 void _applyHitsToLines() { | 2994 void _applyHitsToLines() { |
2889 for (var line in lines) { | 2995 for (var line in lines) { |
2890 var hits = _hits[line.line]; | 2996 var hits = _hits[line.line]; |
2891 line.hits = hits; | 2997 line.hits = hits; |
2892 } | 2998 } |
2893 } | 2999 } |
2894 | 3000 |
2895 void _addBreakpoint(Breakpoint bpt) { | 3001 void _addBreakpoint(Breakpoint bpt) { |
2896 var line = tokenToLine(bpt.location.tokenPos); | 3002 var line; |
| 3003 if (bpt.location.tokenPos != null) { |
| 3004 line = tokenToLine(bpt.location.tokenPos); |
| 3005 } else { |
| 3006 line = bpt.location.line; |
| 3007 } |
2897 getLine(line).addBreakpoint(bpt); | 3008 getLine(line).addBreakpoint(bpt); |
2898 } | 3009 } |
2899 | 3010 |
2900 void _removeBreakpoint(Breakpoint bpt) { | 3011 void _removeBreakpoint(Breakpoint bpt) { |
2901 var line = tokenToLine(bpt.location.tokenPos); | 3012 var line; |
| 3013 if (bpt.location.tokenPos != null) { |
| 3014 line = tokenToLine(bpt.location.tokenPos); |
| 3015 } else { |
| 3016 line = bpt.location.line; |
| 3017 } |
2902 if (line != null) { | 3018 if (line != null) { |
2903 getLine(line).removeBreakpoint(bpt); | 3019 getLine(line).removeBreakpoint(bpt); |
2904 } | 3020 } |
2905 } | 3021 } |
2906 | 3022 |
2907 List<LocalVarLocation> scanLineForLocalVariableLocations(Pattern pattern, | 3023 List<LocalVarLocation> scanLineForLocalVariableLocations(Pattern pattern, |
2908 String name, | 3024 String name, |
2909 String lineContents, | 3025 String lineContents, |
2910 int lineNumber, | 3026 int lineNumber, |
2911 int columnOffset) { | 3027 int columnOffset) { |
(...skipping 908 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3820 var v = list[i]; | 3936 var v = list[i]; |
3821 if ((v is ObservableMap) && _isServiceMap(v)) { | 3937 if ((v is ObservableMap) && _isServiceMap(v)) { |
3822 list[i] = owner.getFromMap(v); | 3938 list[i] = owner.getFromMap(v); |
3823 } else if (v is ObservableList) { | 3939 } else if (v is ObservableList) { |
3824 _upgradeObservableList(v, owner); | 3940 _upgradeObservableList(v, owner); |
3825 } else if (v is ObservableMap) { | 3941 } else if (v is ObservableMap) { |
3826 _upgradeObservableMap(v, owner); | 3942 _upgradeObservableMap(v, owner); |
3827 } | 3943 } |
3828 } | 3944 } |
3829 } | 3945 } |
OLD | NEW |