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 // Some value smaller than the object ring, so requesting a large array | 7 // Some value smaller than the object ring, so requesting a large array |
8 // doesn't result in an expired ref because the elements lapped it in the | 8 // doesn't result in an expired ref because the elements lapped it in the |
9 // object ring. | 9 // object ring. |
10 const int kDefaultFieldLimit = 100; | 10 const int kDefaultFieldLimit = 100; |
(...skipping 1559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1570 } | 1570 } |
1571 | 1571 |
1572 Future stepInto() { | 1572 Future stepInto() { |
1573 return invokeRpc('resume', {'step': 'Into'}); | 1573 return invokeRpc('resume', {'step': 'Into'}); |
1574 } | 1574 } |
1575 | 1575 |
1576 Future stepOver() { | 1576 Future stepOver() { |
1577 return invokeRpc('resume', {'step': 'Over'}); | 1577 return invokeRpc('resume', {'step': 'Over'}); |
1578 } | 1578 } |
1579 | 1579 |
| 1580 Future stepOverAsyncSuspension() { |
| 1581 return invokeRpc('resume', {'step': 'OverAsyncSuspension'}); |
| 1582 } |
| 1583 |
1580 Future stepOut() { | 1584 Future stepOut() { |
1581 return invokeRpc('resume', {'step': 'Out'}); | 1585 return invokeRpc('resume', {'step': 'Out'}); |
1582 } | 1586 } |
1583 | 1587 |
1584 | |
1585 static const int kFirstResume = 0; | |
1586 static const int kSecondResume = 1; | |
1587 /// result[kFirstResume] completes after the inital resume. The UI should | |
1588 /// wait on this future because some other breakpoint may be hit before the | |
1589 /// async continuation. | |
1590 /// result[kSecondResume] completes after the second resume. Tests should | |
1591 /// wait on this future to avoid confusing the pause event at the | |
1592 /// state-machine switch with the pause event after the state-machine switch. | |
1593 Future<List<Future>> asyncStepOver() async { | |
1594 final Completer firstResume = new Completer(); | |
1595 final Completer secondResume = new Completer(); | |
1596 final List<Future> result = [firstResume.future, secondResume.future]; | |
1597 StreamSubscription subscription; | |
1598 | |
1599 // Inner error handling function. | |
1600 handleError(error) { | |
1601 if (subscription != null) { | |
1602 subscription.cancel(); | |
1603 subscription = null; | |
1604 } | |
1605 firstResume.completeError(error); | |
1606 secondResume.completeError(error); | |
1607 } | |
1608 | |
1609 if ((pauseEvent == null) || | |
1610 (pauseEvent.kind != ServiceEvent.kPauseBreakpoint) || | |
1611 (pauseEvent.asyncContinuation == null)) { | |
1612 handleError(new Exception("No async continuation available")); | |
1613 } else { | |
1614 Instance continuation = pauseEvent.asyncContinuation; | |
1615 assert(continuation.isClosure); | |
1616 | |
1617 // Add breakpoint at continuation. | |
1618 Breakpoint continuationBpt; | |
1619 try { | |
1620 continuationBpt = await addBreakOnActivation(continuation); | |
1621 } catch (e) { | |
1622 handleError(e); | |
1623 return result; | |
1624 } | |
1625 | |
1626 // Subscribe to the debugger event stream. | |
1627 Stream stream; | |
1628 try { | |
1629 stream = await vm.getEventStream(VM.kDebugStream); | |
1630 } catch (e) { | |
1631 handleError(e); | |
1632 return result; | |
1633 } | |
1634 | |
1635 Completer onResume = firstResume; | |
1636 subscription = stream.listen((ServiceEvent event) async { | |
1637 if ((event.kind == ServiceEvent.kPauseBreakpoint) && | |
1638 (event.breakpoint == continuationBpt)) { | |
1639 // We are stopped before state-machine dispatch: | |
1640 // 1) Remove the continuation breakpoint. | |
1641 // 2) step over. | |
1642 // reach user code. | |
1643 await removeBreakpoint(continuationBpt); | |
1644 onResume = secondResume; | |
1645 stepOver().catchError(handleError); | |
1646 } else if (event.kind == ServiceEvent.kResume) { | |
1647 // We've resumed. | |
1648 if (onResume == secondResume) { | |
1649 // This is our second resume, cancel our subscription to the debug | |
1650 // stream. | |
1651 subscription.cancel(); | |
1652 subscription = null; | |
1653 } | |
1654 // Complete onResume and clear it. | |
1655 if (onResume != null) { | |
1656 onResume.complete(this); | |
1657 onResume = null; | |
1658 } | |
1659 } | |
1660 }); | |
1661 | |
1662 // Call resume, which will eventually cause us to hit continuationBpt. | |
1663 resume().catchError(handleError); | |
1664 } | |
1665 return result; | |
1666 } | |
1667 | |
1668 Future setName(String newName) { | 1588 Future setName(String newName) { |
1669 return invokeRpc('setName', {'name': newName}); | 1589 return invokeRpc('setName', {'name': newName}); |
1670 } | 1590 } |
1671 | 1591 |
1672 Future setExceptionPauseMode(String mode) { | 1592 Future setExceptionPauseMode(String mode) { |
1673 return invokeRpc('setExceptionPauseMode', {'mode': mode}); | 1593 return invokeRpc('setExceptionPauseMode', {'mode': mode}); |
1674 } | 1594 } |
1675 | 1595 |
1676 Future<ServiceMap> getStack() { | 1596 Future<ServiceMap> getStack() { |
1677 return invokeRpc('getStack', {}); | 1597 return invokeRpc('getStack', {}); |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1907 ServiceEvent.connectionClosed(this.reason) : super._empty(null) { | 1827 ServiceEvent.connectionClosed(this.reason) : super._empty(null) { |
1908 kind = kConnectionClosed; | 1828 kind = kConnectionClosed; |
1909 } | 1829 } |
1910 | 1830 |
1911 @observable String kind; | 1831 @observable String kind; |
1912 @observable DateTime timestamp; | 1832 @observable DateTime timestamp; |
1913 @observable Breakpoint breakpoint; | 1833 @observable Breakpoint breakpoint; |
1914 @observable Frame topFrame; | 1834 @observable Frame topFrame; |
1915 @observable String extensionRPC; | 1835 @observable String extensionRPC; |
1916 @observable Instance exception; | 1836 @observable Instance exception; |
1917 @observable Instance asyncContinuation; | 1837 @observable bool atAsyncSuspension; |
1918 @observable bool atAsyncJump; | |
1919 @observable ServiceObject inspectee; | 1838 @observable ServiceObject inspectee; |
1920 @observable ByteData data; | 1839 @observable ByteData data; |
1921 @observable int count; | 1840 @observable int count; |
1922 @observable String reason; | 1841 @observable String reason; |
1923 @observable String exceptions; | 1842 @observable String exceptions; |
1924 @observable String bytesAsString; | 1843 @observable String bytesAsString; |
1925 @observable Map logRecord; | 1844 @observable Map logRecord; |
1926 @observable String extensionKind; | 1845 @observable String extensionKind; |
1927 @observable Map extensionData; | 1846 @observable Map extensionData; |
1928 | 1847 |
(...skipping 28 matching lines...) Expand all Loading... |
1957 breakpoint = pauseBpts[0]; | 1876 breakpoint = pauseBpts[0]; |
1958 } | 1877 } |
1959 } | 1878 } |
1960 if (map['extensionRPC'] != null) { | 1879 if (map['extensionRPC'] != null) { |
1961 extensionRPC = map['extensionRPC']; | 1880 extensionRPC = map['extensionRPC']; |
1962 } | 1881 } |
1963 topFrame = map['topFrame']; | 1882 topFrame = map['topFrame']; |
1964 if (map['exception'] != null) { | 1883 if (map['exception'] != null) { |
1965 exception = map['exception']; | 1884 exception = map['exception']; |
1966 } | 1885 } |
1967 if (map['_asyncContinuation'] != null) { | 1886 atAsyncSuspension = map['atAsyncSuspension'] != null; |
1968 asyncContinuation = map['_asyncContinuation']; | |
1969 atAsyncJump = map['_atAsyncJump']; | |
1970 } else { | |
1971 atAsyncJump = false; | |
1972 } | |
1973 if (map['inspectee'] != null) { | 1887 if (map['inspectee'] != null) { |
1974 inspectee = map['inspectee']; | 1888 inspectee = map['inspectee']; |
1975 } | 1889 } |
1976 if (map['_data'] != null) { | 1890 if (map['_data'] != null) { |
1977 data = map['_data']; | 1891 data = map['_data']; |
1978 } | 1892 } |
1979 if (map['chunkIndex'] != null) { | 1893 if (map['chunkIndex'] != null) { |
1980 chunkIndex = map['chunkIndex']; | 1894 chunkIndex = map['chunkIndex']; |
1981 } | 1895 } |
1982 if (map['chunkCount'] != null) { | 1896 if (map['chunkCount'] != null) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2033 | 1947 |
2034 // Either SourceLocation or UnresolvedSourceLocation. | 1948 // Either SourceLocation or UnresolvedSourceLocation. |
2035 @observable Location location; | 1949 @observable Location location; |
2036 | 1950 |
2037 // The breakpoint is in a file which is not yet loaded. | 1951 // The breakpoint is in a file which is not yet loaded. |
2038 @observable bool latent; | 1952 @observable bool latent; |
2039 | 1953 |
2040 // The breakpoint has been assigned to a final source location. | 1954 // The breakpoint has been assigned to a final source location. |
2041 @observable bool resolved; | 1955 @observable bool resolved; |
2042 | 1956 |
| 1957 // The breakpoint was synthetically created as part of an |
| 1958 // 'OverAsyncContinuation' resume request. |
| 1959 @observable bool isSyntheticAsyncContinuation; |
| 1960 |
2043 void _update(ObservableMap map, bool mapIsRef) { | 1961 void _update(ObservableMap map, bool mapIsRef) { |
2044 _loaded = true; | 1962 _loaded = true; |
2045 _upgradeCollection(map, owner); | 1963 _upgradeCollection(map, owner); |
2046 | 1964 |
2047 var newNumber = map['breakpointNumber']; | 1965 var newNumber = map['breakpointNumber']; |
2048 // number never changes. | 1966 // number never changes. |
2049 assert((number == null) || (number == newNumber)); | 1967 assert((number == null) || (number == newNumber)); |
2050 number = newNumber; | 1968 number = newNumber; |
2051 resolved = map['resolved']; | 1969 resolved = map['resolved']; |
2052 | 1970 |
2053 var oldLocation = location; | 1971 var oldLocation = location; |
2054 var newLocation = map['location']; | 1972 var newLocation = map['location']; |
2055 if (oldLocation is UnresolvedSourceLocation && | 1973 if (oldLocation is UnresolvedSourceLocation && |
2056 newLocation is SourceLocation) { | 1974 newLocation is SourceLocation) { |
2057 // Breakpoint has been resolved. Remove old breakpoint. | 1975 // Breakpoint has been resolved. Remove old breakpoint. |
2058 var oldScript = oldLocation.script; | 1976 var oldScript = oldLocation.script; |
2059 if (oldScript != null && oldScript.loaded) { | 1977 if (oldScript != null && oldScript.loaded) { |
2060 oldScript._removeBreakpoint(this); | 1978 oldScript._removeBreakpoint(this); |
2061 } | 1979 } |
2062 } | 1980 } |
2063 location = newLocation; | 1981 location = newLocation; |
2064 var newScript = location.script; | 1982 var newScript = location.script; |
2065 if (newScript != null && newScript.loaded) { | 1983 if (newScript != null && newScript.loaded) { |
2066 newScript._addBreakpoint(this); | 1984 newScript._addBreakpoint(this); |
2067 } | 1985 } |
2068 | 1986 |
| 1987 isSyntheticAsyncContinuation = map['isSyntheticAsyncContinuation'] != null; |
| 1988 |
2069 assert(resolved || location is UnresolvedSourceLocation); | 1989 assert(resolved || location is UnresolvedSourceLocation); |
2070 } | 1990 } |
2071 | 1991 |
2072 void remove() { | 1992 void remove() { |
2073 // Remove any references to this breakpoint. It has been removed. | 1993 // Remove any references to this breakpoint. It has been removed. |
2074 location.script._removeBreakpoint(this); | 1994 location.script._removeBreakpoint(this); |
2075 if ((isolate.pauseEvent != null) && | 1995 if ((isolate.pauseEvent != null) && |
2076 (isolate.pauseEvent.breakpoint != null) && | 1996 (isolate.pauseEvent.breakpoint != null) && |
2077 (isolate.pauseEvent.breakpoint.id == id)) { | 1997 (isolate.pauseEvent.breakpoint.id == id)) { |
2078 isolate.pauseEvent.breakpoint = null; | 1998 isolate.pauseEvent.breakpoint = null; |
2079 } | 1999 } |
2080 } | 2000 } |
2081 | 2001 |
2082 String toString() { | 2002 String toString() { |
2083 if (number != null) { | 2003 if (number != null) { |
2084 return 'Breakpoint ${number} at ${location})'; | 2004 if (isSyntheticAsyncContinuation) { |
| 2005 return 'Synthetic Async Continuation Breakpoint ${number}'; |
| 2006 } else { |
| 2007 return 'Breakpoint ${number} at ${location}'; |
| 2008 } |
2085 } else { | 2009 } else { |
2086 return 'Uninitialized breakpoint'; | 2010 return 'Uninitialized breakpoint'; |
2087 } | 2011 } |
2088 } | 2012 } |
2089 } | 2013 } |
2090 | 2014 |
2091 | 2015 |
2092 class LibraryDependency { | 2016 class LibraryDependency { |
2093 @reflectable final bool isImport; | 2017 @reflectable final bool isImport; |
2094 @reflectable final bool isDeferred; | 2018 @reflectable final bool isDeferred; |
(...skipping 1957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4052 var v = list[i]; | 3976 var v = list[i]; |
4053 if ((v is ObservableMap) && _isServiceMap(v)) { | 3977 if ((v is ObservableMap) && _isServiceMap(v)) { |
4054 list[i] = owner.getFromMap(v); | 3978 list[i] = owner.getFromMap(v); |
4055 } else if (v is ObservableList) { | 3979 } else if (v is ObservableList) { |
4056 _upgradeObservableList(v, owner); | 3980 _upgradeObservableList(v, owner); |
4057 } else if (v is ObservableMap) { | 3981 } else if (v is ObservableMap) { |
4058 _upgradeObservableMap(v, owner); | 3982 _upgradeObservableMap(v, owner); |
4059 } | 3983 } |
4060 } | 3984 } |
4061 } | 3985 } |
OLD | NEW |