@@ -1560,6 +1560,12 @@ if (!self.deferred_loader) {
1560
1560
* application.
1561
1561
*/
1562
1562
hotReloadEnd ( ) {
1563
+ // Clear RTI subtype caches before initializing libraries.
1564
+ // These needs to be done before hot reload completes (and any new
1565
+ // libraries initialize) in case subtype hierarchies updated.
1566
+ let dartRtiLibrary = this . importLibrary ( 'dart:_rti' ) ;
1567
+ dartRtiLibrary . resetRtiSubtypeCaches ( ) ;
1568
+
1563
1569
// On a hot reload, we reuse the existing library objects to ensure all
1564
1570
// references remain valid and continue to be unique. We track in
1565
1571
// `previouslyLoaded` which libraries already exist in the system, so we
@@ -1622,8 +1628,309 @@ if (!self.deferred_loader) {
1622
1628
}
1623
1629
}
1624
1630
1631
+ // This is closed-upon to avoid exposing it through the `dartDevEmbedder`.
1625
1632
const libraryManager = new LibraryManager ( ) ;
1626
1633
1634
+ function dartDebuggerLibrary ( ) {
1635
+ return libraryManager . initializeAndLinkLibrary ( 'dart:_debugger' ) ;
1636
+ }
1637
+
1638
+ function dartDeveloperLibrary ( ) {
1639
+ return libraryManager . initializeAndLinkLibrary ( 'dart:developer' )
1640
+ }
1641
+
1642
+ function dartRuntimeLibrary ( ) {
1643
+ return libraryManager . initializeAndLinkLibrary ( 'dart:_runtime' ) ;
1644
+ }
1645
+
1646
+ /**
1647
+ * Common debugging APIs that may be useful for metadata, invocations,
1648
+ * developer extensions, bootstrapping, and more.
1649
+ */
1650
+ // TODO(56966): A number of APIs in this class consume and return Dart
1651
+ // objects, nested or otherwise. We should replace them with some kind of
1652
+ // metadata instead so users don't accidentally rely on the object's
1653
+ // representation. For now, we warn users to not do so in the APIs below.
1654
+ class Debugger {
1655
+ /**
1656
+ * Returns a JavaScript array of all class names in a Dart library.
1657
+ *
1658
+ * @param {string } libraryUri URI of the Dart library.
1659
+ * @returns {Array<string> } Array containing the class names in the library.
1660
+ */
1661
+ getClassesInLibrary ( libraryUri ) {
1662
+ return dartRuntimeLibrary ( ) . getLibraryMetadata ( libraryUri , libraryManager . libraries ) ;
1663
+ }
1664
+
1665
+ /**
1666
+ * Returns a JavaScript object containing metadata of a class in a given
1667
+ * Dart library.
1668
+ *
1669
+ * The object will be formatted as such:
1670
+ * ```
1671
+ * {
1672
+ * 'className': <dart class name>,
1673
+ * 'superClassName': <super class name, if any>
1674
+ * 'superClassLibraryId': <super class library ID, if any>
1675
+ * 'fields': {
1676
+ * <name>: {
1677
+ * 'isConst': <true if the member is const>,
1678
+ * 'isFinal': <true if the member is final>,
1679
+ * 'isStatic': <true if the member is final>,
1680
+ * 'className': <class name for a field type>,
1681
+ * 'classLibraryId': <library id for a field type>,
1682
+ * }
1683
+ * },
1684
+ * 'methods': {
1685
+ * <name>: {
1686
+ * 'isConst': <true if the member is const>,
1687
+ * 'isStatic': <true if the member is static>,
1688
+ * 'isSetter" <true if the member is a setter>,
1689
+ * 'isGetter" <true if the member is a getter>,
1690
+ * }
1691
+ * },
1692
+ * }
1693
+ * ```
1694
+ *
1695
+ * @param {string } libraryUri URI of the Dart library that the class is in.
1696
+ * @param {string } name Name of the Dart class.
1697
+ * @param {any } objectInstance Optional instance of the Dart class that's
1698
+ * needed to determine the type of any generic members.
1699
+ * @returns {Object<String, any> } Object containing the metadata in the
1700
+ * above format.
1701
+ */
1702
+ getClassMetadata ( libraryUri , name , objectInstance ) {
1703
+ return dartRuntimeLibrary ( ) . getClassMetadata ( libraryUri , name , objectInstance , libraryManager . libraries ) ;
1704
+ }
1705
+
1706
+ /**
1707
+ * Returns a JavaScript object containing metadata about a Dart value.
1708
+ *
1709
+ * The object will be formatted as such:
1710
+ * ```
1711
+ * {
1712
+ * 'className': <dart class name>,
1713
+ * 'libraryId': <library URI for the object type>,
1714
+ * 'runtimeKind': <kind of the object for display purposes>,
1715
+ * 'length': <length of the object if applicable>,
1716
+ * 'typeName': <name of the type represented if object is a Type>,
1717
+ * }
1718
+ * ```
1719
+ *
1720
+ * @param {Object } value Dart value for which metadata is computed.
1721
+ * @returns {Object<String, any> } Object containing the metadata in the
1722
+ * above format.
1723
+ */
1724
+ getObjectMetadata ( value ) {
1725
+ return dartRuntimeLibrary ( ) . getObjectMetadata ( value ) ;
1726
+ }
1727
+
1728
+ /**
1729
+ * Returns the name of the given function. If it's bound to an object of
1730
+ * class `C`, returns `C.<name>` instead.
1731
+ *
1732
+ * @param {Object } fun Dart function for which the name is returned.
1733
+ * @returns {string } Name of the given function in the above format.
1734
+ */
1735
+ getFunctionName ( fun ) {
1736
+ return dartRuntimeLibrary ( ) . getFunctionMetadata ( fun ) ;
1737
+ }
1738
+
1739
+ /**
1740
+ * Returns an array of all the field names in the Dart object.
1741
+ *
1742
+ * @param {Object } object Dart object whose field names are collected.
1743
+ * @returns {Array<string> } Array of field names.
1744
+ */
1745
+ getObjectFieldNames ( object ) {
1746
+ return dartRuntimeLibrary ( ) . getObjectFieldNames ( object ) ;
1747
+ }
1748
+
1749
+ /**
1750
+ * If given a Dart `Set`, `List`, or `Map`, returns a sub-range array of at
1751
+ * most the given number of elements starting at the given offset. If given
1752
+ * any other Dart value, returns the original value. Any Dart values
1753
+ * returned from this API should be treated as opaque pointers and should
1754
+ * not be interacted with.
1755
+ *
1756
+ * @param {Object } object Dart object for which the sub-range is computed.
1757
+ * @param {number } offset Integer index at which the sub-range should start.
1758
+ * @param {number } count Integer number of values in the sub-range.
1759
+ * @returns {any } Either the sub-range or the original object.
1760
+ */
1761
+ getSubRange ( object , offset , count ) {
1762
+ return dartRuntimeLibrary ( ) . getSubRange ( object , offset , count ) ;
1763
+ }
1764
+
1765
+ /**
1766
+ * Returns a JavaScript object containing the entries for a given Dart `Map`
1767
+ * that will be formatted as:
1768
+ *
1769
+ * ```
1770
+ * {
1771
+ * 'keys': [ <key>, ...],
1772
+ * 'values': [ <value>, ...],
1773
+ * }
1774
+ * ```
1775
+ *
1776
+ * Any Dart values returned from this API should be treated as opaque
1777
+ * pointers and should not be interacted with.
1778
+ *
1779
+ * @param {Object } map Dart `Map` whose entries will be copied.
1780
+ * @returns {Object<String, Array> } Object containing the entries in
1781
+ * the above format.
1782
+ */
1783
+ getMapElements ( map ) {
1784
+ return dartRuntimeLibrary ( ) . getMapElements ( map ) ;
1785
+ }
1786
+
1787
+ /**
1788
+ * Returns a JavaScript object containing the entries for a given Dart `Set`
1789
+ * that will be formatted as:
1790
+ *
1791
+ * ```
1792
+ * {
1793
+ * 'entries': [ <entry>, ...],
1794
+ * }
1795
+ * ```
1796
+ *
1797
+ * Any Dart values returned from this API should be treated as opaque
1798
+ * pointers and should not be interacted with.
1799
+ *
1800
+ * @param {Object } set Dart `Set` whose entries will be copied.
1801
+ * @returns {Object<String, Array } Object containing the entries in the
1802
+ * above format.
1803
+ */
1804
+ getSetElements ( set ) {
1805
+ return dartRuntimeLibrary ( ) . getSetElements ( set ) ;
1806
+ }
1807
+
1808
+ /**
1809
+ * Returns a JavaScript object containing metadata for a given Dart `Record`
1810
+ * that will be formatted as:
1811
+ *
1812
+ * ```
1813
+ * {
1814
+ * 'positionalCount': <number of positional elements>,
1815
+ * 'named': [ <name>, ...],
1816
+ * 'values': [ <positional value>, ..., <named value>, ... ],
1817
+ * }
1818
+ * ```
1819
+ *
1820
+ * Any Dart values returned from this API should be treated as opaque
1821
+ * pointers and should not be interacted with.
1822
+ *
1823
+ * @param {Object } record Dart `Record` whose metadata will be computed.
1824
+ * @returns {Object<String, any> } Object containing the metadata in the
1825
+ * above format.
1826
+ */
1827
+ getRecordFields ( record ) {
1828
+ return dartRuntimeLibrary ( ) . getRecordFields ( record ) ;
1829
+ }
1830
+
1831
+ /**
1832
+ * Returns a JavaScript object containing metadata for a given Dart
1833
+ * `Record`'s runtime type that will be formatted as:
1834
+ *
1835
+ * ```
1836
+ * {
1837
+ * 'positionalCount': <number of positional types>,
1838
+ * 'named': [ <name>, ...],
1839
+ * 'types': [ <positional type>, ..., <named type>, ... ],
1840
+ * }
1841
+ * ```
1842
+ *
1843
+ * Any Dart values returned from this API should be treated as opaque
1844
+ * pointers and should not be interacted with.
1845
+ *
1846
+ * @param {Object } recordType Dart `Type` of a `Record` whose metadata will
1847
+ * be computed.
1848
+ * @returns {Object<String, any> } Object containing the metadata in the
1849
+ * above format.
1850
+ */
1851
+ getRecordTypeFields ( recordType ) {
1852
+ return dartRuntimeLibrary ( ) . getRecordTypeFields ( recordType ) ;
1853
+ }
1854
+
1855
+ /**
1856
+ * Given a Dart instance, calls the method with the given name in that
1857
+ * instance and returns the result.
1858
+ *
1859
+ * Any Dart values returned from this API should be treated as opaque
1860
+ * pointers and should not be interacted with.
1861
+ *
1862
+ * @param {Object } instance Dart instance whose method will be called.
1863
+ * @param {string } name Name of the method.
1864
+ * @param {Array } args Array of arguments passed to the method.
1865
+ * @returns {any } Result of calling the method.
1866
+ */
1867
+ callInstanceMethod ( instance , name , args ) {
1868
+ return dartRuntimeLibrary ( ) . dsendRepl ( instance , name , args ) ;
1869
+ }
1870
+
1871
+ /**
1872
+ * Given a Dart library URI, calls the method with the given name in that
1873
+ * library and returns the result.
1874
+ *
1875
+ * Any Dart values returned from this API should be treated as opaque
1876
+ * pointers and should not be interacted with.
1877
+ *
1878
+ * @param {any } libraryUri Dart library URI in which the method exists.
1879
+ * @param {string } name Name of the method.
1880
+ * @param {Array } args Array of arguments passed to the method.
1881
+ * @returns {any } Result of calling the method.
1882
+ */
1883
+ callLibraryMethod ( libraryUri , name , args ) {
1884
+ let library = libraryManager . initializeAndLinkLibrary ( libraryUri ) ;
1885
+ return library [ name ] . apply ( library , args ) ;
1886
+ }
1887
+
1888
+ /**
1889
+ * Register the DDC Chrome DevTools custom formatter into the global
1890
+ * `devtoolsFormatters` property.
1891
+ */
1892
+ registerDevtoolsFormatter ( ) {
1893
+ dartDebuggerLibrary ( ) . registerDevtoolsFormatter ( ) ;
1894
+ }
1895
+
1896
+ /**
1897
+ * Invoke a registered extension with the given name and encoded map.
1898
+ *
1899
+ * @param {String } methodName The name of the registered extension.
1900
+ * @param {String } encodedJson The encoded string map that will be passed as
1901
+ * a parameter to the invoked method.
1902
+ * @returns {Promise } Promise that will await the invocation of the
1903
+ * extension.
1904
+ */
1905
+ invokeExtension ( methodName , encodedJson ) {
1906
+ return dartDeveloperLibrary ( ) . invokeExtension ( methodName , encodedJson ) ;
1907
+ }
1908
+
1909
+ /**
1910
+ * Returns a JavaScript array containing the names of the extensions
1911
+ * registered in `dart:developer`.
1912
+ *
1913
+ * @returns {Array<string> } Array containing the extension names.
1914
+ */
1915
+ get extensionNames ( ) {
1916
+ return dartDeveloperLibrary ( ) . _extensions . keys . toList ( ) ;
1917
+ }
1918
+
1919
+ /**
1920
+ * Returns a Dart stack trace string given an error caught in JS. If the
1921
+ * error is a Dart error or JS `Error`, we use the built-in stack. If the
1922
+ * error is neither, we try to construct a stack trace if possible.
1923
+ *
1924
+ * @param {any } error The error for which a stack trace will be produced.
1925
+ * @returns {String } The stringified stack trace.
1926
+ */
1927
+ stackTrace ( error ) {
1928
+ return dartRuntimeLibrary ( ) . stackTrace ( error ) . toString ( ) ;
1929
+ }
1930
+ }
1931
+
1932
+ const debugger_ = new Debugger ( ) ;
1933
+
1627
1934
/** The API for embedding a Dart application in the page at development time
1628
1935
* that supports stateful hot reloading.
1629
1936
*/
@@ -1701,16 +2008,16 @@ if (!self.deferred_loader) {
1701
2008
* Immediately triggers a hot restart of the application losing all state
1702
2009
* and running the main method again.
1703
2010
*/
1704
- hotRestart ( ) {
1705
- self . $dartReloadModifiedModules (
2011
+ async hotRestart ( ) {
2012
+ await self . $dartReloadModifiedModules (
1706
2013
libraryManager . savedEntryPointLibraryName ,
1707
2014
( ) => { libraryManager . hotRestart ( ) ; } ) ;
1708
2015
}
1709
2016
1710
2017
1711
2018
/**
1712
2019
* @return {Number } The current hot reload generation of the running
1713
- * application.
2020
+ * application.
1714
2021
*/
1715
2022
get hotReloadGeneration ( ) {
1716
2023
return libraryManager . hotReloadGeneration ;
@@ -1723,6 +2030,14 @@ if (!self.deferred_loader) {
1723
2030
get hotRestartGeneration ( ) {
1724
2031
return libraryManager . hotRestartGeneration ;
1725
2032
}
2033
+
2034
+ /**
2035
+ * @return {Debugger } Common debugging APIs that may be useful for metadata,
2036
+ * invocations, developer extensions, bootstrapping, and more.
2037
+ */
2038
+ get debugger ( ) {
2039
+ return debugger_ ;
2040
+ }
1726
2041
}
1727
2042
1728
2043
self . dartDevEmbedder = new DartDevEmbedder ( ) ;
0 commit comments