@@ -1439,22 +1439,111 @@ export function getLastTokenBetween(
14391439
14401440/**
14411441 * Get the last tokens between two non-overlapping nodes.
1442- * @param nodeOrToken1 - Node before the desired token range.
1443- * @param nodeOrToken2 - Node after the desired token range.
1442+ * @param left - Node or token before the desired token range.
1443+ * @param right - Node or token after the desired token range.
14441444 * @param countOptions? - Options object.
14451445 * If is a number, equivalent to `{ count: n }`.
14461446 * If is a function, equivalent to `{ filter: fn }`.
1447- * @returns Array of `Token`s between `nodeOrToken1 ` and `nodeOrToken2 `.
1447+ * @returns Array of `Token`s between `left ` and `right `.
14481448 */
1449- /* oxlint-disable no-unused-vars */
14501449export function getLastTokensBetween (
1451- nodeOrToken1 : NodeOrToken | Comment ,
1452- nodeOrToken2 : NodeOrToken | Comment ,
1450+ left : NodeOrToken | Comment ,
1451+ right : NodeOrToken | Comment ,
14531452 countOptions ?: CountOptions | number | FilterFn | null ,
14541453) : Token [ ] {
1455- throw new Error ( '`sourceCode.getLastTokensBetween` not implemented yet' ) ; // TODO
1454+ if ( tokens === null ) initTokens ( ) ;
1455+ debugAssertIsNonNull ( tokens ) ;
1456+ debugAssertIsNonNull ( comments ) ;
1457+
1458+ const count =
1459+ typeof countOptions === 'number'
1460+ ? countOptions
1461+ : typeof countOptions === 'object' && countOptions !== null
1462+ ? countOptions . count
1463+ : null ;
1464+
1465+ const filter =
1466+ typeof countOptions === 'function'
1467+ ? countOptions
1468+ : typeof countOptions === 'object' && countOptions !== null
1469+ ? countOptions . filter
1470+ : null ;
1471+
1472+ const includeComments =
1473+ typeof countOptions === 'object' &&
1474+ countOptions !== null &&
1475+ 'includeComments' in countOptions &&
1476+ countOptions . includeComments ;
1477+
1478+ let nodeTokens : Token [ ] | null = null ;
1479+ if ( includeComments ) {
1480+ if ( tokensWithComments === null ) initTokensWithComments ( ) ;
1481+ debugAssertIsNonNull ( tokensWithComments ) ;
1482+ nodeTokens = tokensWithComments ;
1483+ } else {
1484+ nodeTokens = tokens ;
1485+ }
1486+
1487+ // This range is not invariant over node order.
1488+ // The first argument must be the left node.
1489+ // Same as ESLint's implementation.
1490+ const rangeStart = left . range [ 1 ] ,
1491+ rangeEnd = right . range [ 0 ] ,
1492+ tokensLength = nodeTokens . length ;
1493+
1494+ // Binary search for first token past the beginning of the `between` range
1495+ let sliceStart = tokensLength ;
1496+ for ( let lo = 0 ; lo < sliceStart ; ) {
1497+ const mid = ( lo + sliceStart ) >> 1 ;
1498+ if ( nodeTokens [ mid ] . range [ 0 ] < rangeStart ) {
1499+ lo = mid + 1 ;
1500+ } else {
1501+ sliceStart = mid ;
1502+ }
1503+ }
1504+
1505+ // Binary search for first token past the end of the `between` range
1506+ let sliceEnd = tokensLength ;
1507+ for ( let lo = sliceStart ; lo < sliceEnd ; ) {
1508+ const mid = ( lo + sliceEnd ) >> 1 ;
1509+ if ( nodeTokens [ mid ] . range [ 0 ] < rangeEnd ) {
1510+ lo = mid + 1 ;
1511+ } else {
1512+ sliceEnd = mid ;
1513+ }
1514+ }
1515+
1516+ let tokensBetween : Token [ ] ;
1517+ // Fast path for the common case
1518+ if ( typeof filter !== 'function' ) {
1519+ if ( typeof count !== 'number' ) {
1520+ tokensBetween = nodeTokens . slice ( sliceStart , sliceEnd ) ;
1521+ } else {
1522+ tokensBetween = nodeTokens . slice ( max ( sliceStart , sliceEnd - count ) , sliceEnd ) ;
1523+ }
1524+ } else {
1525+ if ( typeof count !== 'number' ) {
1526+ tokensBetween = [ ] ;
1527+ for ( let i = sliceStart ; i < sliceEnd ; i ++ ) {
1528+ const token = nodeTokens [ i ] ;
1529+ if ( filter ( token ) ) {
1530+ tokensBetween . push ( token ) ;
1531+ }
1532+ }
1533+ } else {
1534+ tokensBetween = [ ] ;
1535+ // Count is the number of preceding tokens so we iterate in reverse
1536+ for ( let i = sliceEnd - 1 ; i >= sliceStart && tokensBetween . length < count ; i -- ) {
1537+ const token = nodeTokens [ i ] ;
1538+ if ( filter ( token ) ) {
1539+ tokensBetween . unshift ( token ) ;
1540+ }
1541+ }
1542+ }
1543+ }
1544+
1545+ return tokensBetween ;
14561546}
1457- /* oxlint-enable no-unused-vars */
14581547
14591548/**
14601549 * Get the token starting at the specified index.
0 commit comments