@@ -1162,22 +1162,110 @@ export function getFirstTokenBetween(
11621162
11631163/**
11641164 * Get the first tokens between two non-overlapping nodes.
1165- * @param nodeOrToken1 - Node before the desired token range.
1166- * @param nodeOrToken2 - Node after the desired token range.
1165+ * @param left - Node or token before the desired token range.
1166+ * @param right - Node or token after the desired token range.
11671167 * @param countOptions? - Options object.
11681168 * If is a number, equivalent to `{ count: n }`.
11691169 * If is a function, equivalent to `{ filter: fn }`.
1170- * @returns Array of `Token`s between `nodeOrToken1 ` and `nodeOrToken2 `.
1170+ * @returns Array of `Token`s between `left ` and `right `.
11711171 */
1172- /* oxlint-disable no-unused-vars */
11731172export function getFirstTokensBetween (
1174- nodeOrToken1 : NodeOrToken | Comment ,
1175- nodeOrToken2 : NodeOrToken | Comment ,
1173+ left : NodeOrToken | Comment ,
1174+ right : NodeOrToken | Comment ,
11761175 countOptions ?: CountOptions | number | FilterFn | null ,
11771176) : Token [ ] {
1178- throw new Error ( '`sourceCode.getFirstTokensBetween` not implemented yet' ) ; // TODO
1177+ if ( tokens === null ) initTokens ( ) ;
1178+ debugAssertIsNonNull ( tokens ) ;
1179+ debugAssertIsNonNull ( comments ) ;
1180+
1181+ const count =
1182+ typeof countOptions === 'number'
1183+ ? countOptions
1184+ : typeof countOptions === 'object' && countOptions !== null
1185+ ? countOptions . count
1186+ : null ;
1187+
1188+ const filter =
1189+ typeof countOptions === 'function'
1190+ ? countOptions
1191+ : typeof countOptions === 'object' && countOptions !== null
1192+ ? countOptions . filter
1193+ : null ;
1194+
1195+ const includeComments =
1196+ typeof countOptions === 'object' &&
1197+ countOptions !== null &&
1198+ 'includeComments' in countOptions &&
1199+ countOptions . includeComments ;
1200+
1201+ let nodeTokens : Token [ ] | null = null ;
1202+ if ( includeComments ) {
1203+ if ( tokensWithComments === null ) initTokensWithComments ( ) ;
1204+ debugAssertIsNonNull ( tokensWithComments ) ;
1205+ nodeTokens = tokensWithComments ;
1206+ } else {
1207+ nodeTokens = tokens ;
1208+ }
1209+
1210+ // This range is not invariant over node order.
1211+ // The first argument must be the left node.
1212+ // Same as ESLint's implementation.
1213+ const rangeStart = left . range [ 1 ] ,
1214+ rangeEnd = right . range [ 0 ] ;
1215+
1216+ const tokensLength = nodeTokens . length ;
1217+
1218+ // Find the first token after `left`
1219+ let sliceStart = tokensLength ;
1220+ for ( let lo = 0 ; lo < sliceStart ; ) {
1221+ const mid = ( lo + sliceStart ) >> 1 ;
1222+ if ( nodeTokens [ mid ] . range [ 0 ] < rangeStart ) {
1223+ lo = mid + 1 ;
1224+ } else {
1225+ sliceStart = mid ;
1226+ }
1227+ }
1228+
1229+ // Find the first token at or after `right`
1230+ let sliceEnd = tokensLength ;
1231+ for ( let lo = sliceStart ; lo < sliceEnd ; ) {
1232+ const mid = ( lo + sliceEnd ) >> 1 ;
1233+ if ( nodeTokens [ mid ] . range [ 0 ] < rangeEnd ) {
1234+ lo = mid + 1 ;
1235+ } else {
1236+ sliceEnd = mid ;
1237+ }
1238+ }
1239+
1240+ let firstTokens : Token [ ] ;
1241+ if ( typeof filter !== 'function' ) {
1242+ if ( typeof count !== 'number' ) {
1243+ firstTokens = nodeTokens . slice ( sliceStart , sliceEnd ) ;
1244+ } else {
1245+ firstTokens = nodeTokens . slice ( sliceStart , min ( sliceStart + count , sliceEnd ) ) ;
1246+ }
1247+ } else {
1248+ if ( typeof count !== 'number' ) {
1249+ firstTokens = [ ] ;
1250+ for ( let i = sliceStart ; i < sliceEnd ; i ++ ) {
1251+ const token = nodeTokens [ i ] ;
1252+ if ( filter ( token ) ) {
1253+ firstTokens . push ( token ) ;
1254+ }
1255+ }
1256+ } else {
1257+ firstTokens = [ ] ;
1258+ for ( let i = sliceStart ; i < sliceEnd && firstTokens . length < count ; i ++ ) {
1259+ const token = nodeTokens [ i ] ;
1260+ if ( filter ( token ) ) {
1261+ firstTokens . push ( token ) ;
1262+ }
1263+ }
1264+ }
1265+ }
1266+
1267+ return firstTokens ;
11791268}
1180- /* oxlint-enable no-unused-vars */
11811269
11821270/**
11831271 * Get the last token between two non-overlapping nodes.
0 commit comments