@@ -1279,6 +1279,31 @@ impl SourceMapIndex {
12791279 pub fn x_metro_module_paths ( & self ) -> Option < & [ String ] > {
12801280 self . x_metro_module_paths . as_ref ( ) . map ( |x| & x[ ..] )
12811281 }
1282+
1283+ /// Adjusts all of the sections' offset rows by the given amount.
1284+ /// Returns a boolean indicating whether the adjustment was successful
1285+ /// (false indicating that not all of the sections could be adjusted
1286+ /// because we overflowed the u32, true if adjustment was successful).
1287+ /// If false is returned, then the sourcemap index is unchanged.
1288+ pub fn adjust_sections_offset_rows ( & mut self , amount : u32 ) -> bool {
1289+ let adjusted_rows: Vec < _ > = self
1290+ . sections
1291+ . iter ( )
1292+ // Filter map will filter out adjustments that overflow
1293+ . filter_map ( |section| section. offset . 0 . checked_add ( amount) )
1294+ . collect ( ) ;
1295+
1296+ if adjusted_rows. len ( ) != self . sections . len ( ) {
1297+ // We overflowed at least one section
1298+ return false ;
1299+ }
1300+
1301+ for ( section, adjustment) in self . sections . iter_mut ( ) . zip ( adjusted_rows) {
1302+ section. offset . 0 = adjustment;
1303+ }
1304+
1305+ true
1306+ }
12821307}
12831308
12841309impl SourceMapSection {
@@ -1344,7 +1369,7 @@ impl SourceMapSection {
13441369mod tests {
13451370 use std:: collections:: BTreeSet ;
13461371
1347- use super :: { DecodedMap , RewriteOptions , SourceMap , SourceMapIndex } ;
1372+ use super :: { DecodedMap , RewriteOptions , SourceMap , SourceMapIndex , SourceMapSection } ;
13481373 use debugid:: DebugId ;
13491374
13501375 #[ test]
@@ -1547,6 +1572,197 @@ mod tests {
15471572 ) ;
15481573 }
15491574
1575+ #[ test]
1576+ fn test_adjust_sections_offset_rows_basic ( ) {
1577+ // Create a sourcemap index with sections starting at (0, 0) and (10, 0)
1578+ let mut smi = SourceMapIndex :: new (
1579+ Some ( "test.js" . to_string ( ) ) ,
1580+ vec ! [
1581+ SourceMapSection :: new( ( 0 , 0 ) , None , None ) ,
1582+ SourceMapSection :: new( ( 10 , 0 ) , None , None ) ,
1583+ ] ,
1584+ ) ;
1585+
1586+ // Adjust by 1
1587+ assert ! ( smi. adjust_sections_offset_rows( 1 ) ) ;
1588+
1589+ // Check that the entire SourceMapIndex was adjusted correctly
1590+ assert_eq ! (
1591+ smi,
1592+ SourceMapIndex :: new(
1593+ Some ( "test.js" . to_string( ) ) ,
1594+ vec![
1595+ SourceMapSection :: new( ( 1 , 0 ) , None , None ) ,
1596+ SourceMapSection :: new( ( 11 , 0 ) , None , None ) ,
1597+ ] ,
1598+ )
1599+ ) ;
1600+ }
1601+
1602+ #[ test]
1603+ fn test_adjust_sections_offset_rows_zero ( ) {
1604+ // Create a sourcemap index with sections starting at (0, 0) and (10, 0)
1605+ let mut smi = SourceMapIndex :: new (
1606+ Some ( "test.js" . to_string ( ) ) ,
1607+ vec ! [
1608+ SourceMapSection :: new( ( 0 , 0 ) , None , None ) ,
1609+ SourceMapSection :: new( ( 10 , 0 ) , None , None ) ,
1610+ ] ,
1611+ ) ;
1612+
1613+ // Adjust by zero
1614+ assert ! ( smi. adjust_sections_offset_rows( 0 ) ) ;
1615+
1616+ // Check that the entire SourceMapIndex remained unchanged
1617+ assert_eq ! (
1618+ smi,
1619+ SourceMapIndex :: new(
1620+ Some ( "test.js" . to_string( ) ) ,
1621+ vec![
1622+ SourceMapSection :: new( ( 0 , 0 ) , None , None ) ,
1623+ SourceMapSection :: new( ( 10 , 0 ) , None , None ) ,
1624+ ] ,
1625+ )
1626+ ) ;
1627+ }
1628+
1629+ #[ test]
1630+ fn test_adjust_sections_offset_rows_multiple_sections ( ) {
1631+ // Create a sourcemap index with multiple sections
1632+ let mut smi = SourceMapIndex :: new (
1633+ Some ( "test.js" . to_string ( ) ) ,
1634+ vec ! [
1635+ SourceMapSection :: new( ( 0 , 0 ) , None , None ) ,
1636+ SourceMapSection :: new( ( 10 , 0 ) , None , None ) ,
1637+ SourceMapSection :: new( ( 20 , 10 ) , None , None ) ,
1638+ SourceMapSection :: new( ( 30 , 40 ) , None , None ) ,
1639+ ] ,
1640+ ) ;
1641+
1642+ // Adjust by 1
1643+ assert ! ( smi. adjust_sections_offset_rows( 1 ) ) ;
1644+
1645+ // Check that the entire SourceMapIndex was adjusted correctly
1646+ assert_eq ! (
1647+ smi,
1648+ SourceMapIndex :: new(
1649+ Some ( "test.js" . to_string( ) ) ,
1650+ vec![
1651+ SourceMapSection :: new( ( 1 , 0 ) , None , None ) ,
1652+ SourceMapSection :: new( ( 11 , 0 ) , None , None ) ,
1653+ SourceMapSection :: new( ( 21 , 10 ) , None , None ) ,
1654+ SourceMapSection :: new( ( 31 , 40 ) , None , None ) ,
1655+ ] ,
1656+ )
1657+ ) ;
1658+ }
1659+
1660+ #[ test]
1661+ fn test_adjust_sections_offset_rows_overflow ( ) {
1662+ // Create a sourcemap index with a section at u32::MAX
1663+ let mut smi = SourceMapIndex :: new (
1664+ Some ( "test.js" . to_string ( ) ) ,
1665+ vec ! [
1666+ SourceMapSection :: new( ( 0 , 0 ) , None , None ) ,
1667+ SourceMapSection :: new( ( u32 :: MAX , 0 ) , None , None ) ,
1668+ ] ,
1669+ ) ;
1670+
1671+ // Store the original state
1672+ let original_smi = smi. clone ( ) ;
1673+
1674+ // An adjustment of 1 would overflow
1675+ assert ! ( !smi. adjust_sections_offset_rows( 1 ) ) ;
1676+
1677+ // Verify the sourcemap index remains unchanged
1678+ assert_eq ! ( smi, original_smi) ;
1679+ }
1680+
1681+ #[ test]
1682+ fn test_adjust_sections_offset_rows_partial_overflow ( ) {
1683+ // Create a sourcemap index with multiple sections, one at u32::MAX
1684+ let mut smi = SourceMapIndex :: new (
1685+ Some ( "test.js" . to_string ( ) ) ,
1686+ vec ! [
1687+ SourceMapSection :: new( ( 0 , 0 ) , None , None ) ,
1688+ SourceMapSection :: new( ( 10 , 0 ) , None , None ) ,
1689+ SourceMapSection :: new( ( 20 , 0 ) , None , None ) ,
1690+ SourceMapSection :: new( ( u32 :: MAX , 0 ) , None , None ) ,
1691+ ] ,
1692+ ) ;
1693+
1694+ // Store the original state
1695+ let original_smi = smi. clone ( ) ;
1696+
1697+ // Try to adjust by an amount that would cause overflow for one section
1698+ assert ! ( !smi. adjust_sections_offset_rows( 1 ) ) ;
1699+
1700+ // Verify the sourcemap index remains unchanged
1701+ assert_eq ! ( smi, original_smi) ;
1702+ }
1703+
1704+ #[ test]
1705+ fn test_adjust_sections_offset_rows_large_amount ( ) {
1706+ // Create a sourcemap index with sections
1707+ let mut smi = SourceMapIndex :: new (
1708+ Some ( "test.js" . to_string ( ) ) ,
1709+ vec ! [
1710+ SourceMapSection :: new( ( 0 , 0 ) , None , None ) ,
1711+ SourceMapSection :: new( ( 10 , 0 ) , None , None ) ,
1712+ ] ,
1713+ ) ;
1714+
1715+ assert ! ( smi. adjust_sections_offset_rows( 1_000_000 ) ) ;
1716+
1717+ // Check that the entire SourceMapIndex was adjusted correctly
1718+ assert_eq ! (
1719+ smi,
1720+ SourceMapIndex :: new(
1721+ Some ( "test.js" . to_string( ) ) ,
1722+ vec![
1723+ SourceMapSection :: new( ( 1_000_000 , 0 ) , None , None ) ,
1724+ SourceMapSection :: new( ( 1_000_010 , 0 ) , None , None ) ,
1725+ ] ,
1726+ )
1727+ ) ;
1728+ }
1729+
1730+ #[ test]
1731+ fn adjust_sections_offset_rows_large_amount_overflow ( ) {
1732+ // Create a sourcemap index with a section at a positive amount
1733+ let mut smi = SourceMapIndex :: new (
1734+ Some ( "test.js" . to_string ( ) ) ,
1735+ vec ! [
1736+ SourceMapSection :: new( ( 0 , 0 ) , None , None ) ,
1737+ SourceMapSection :: new( ( 10 , 0 ) , None , None ) ,
1738+ ] ,
1739+ ) ;
1740+
1741+ // Store the original state
1742+ let original_smi = smi. clone ( ) ;
1743+
1744+ // An adjustment of u32::MAX would overflow
1745+ assert ! ( !smi. adjust_sections_offset_rows( u32 :: MAX ) ) ;
1746+
1747+ // Verify the sourcemap index remains unchanged
1748+ assert_eq ! ( smi, original_smi) ;
1749+ }
1750+
1751+ #[ test]
1752+ fn adjust_sections_offset_rows_no_sections ( ) {
1753+ // Create a sourcemap index with no sections
1754+ let mut smi = SourceMapIndex :: new ( Some ( "test.js" . to_string ( ) ) , vec ! [ ] ) ;
1755+
1756+ // An adjustment by 1 should return true and no-op
1757+ assert ! ( smi. adjust_sections_offset_rows( 1 ) ) ;
1758+
1759+ // The sourcemap index should remain unchanged
1760+ assert_eq ! (
1761+ smi,
1762+ SourceMapIndex :: new( Some ( "test.js" . to_string( ) ) , vec![ ] )
1763+ ) ;
1764+ }
1765+
15501766 mod prop {
15511767 //! This module exists to test the following property:
15521768 //!
0 commit comments