Skip to content

Commit 0aed79e

Browse files
committed
refactor: uses sortedLastIndex
1 parent 87468a2 commit 0aed79e

File tree

3 files changed

+43
-11
lines changed

3 files changed

+43
-11
lines changed

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@
5555
"@types/benchmark": "^2.1.1",
5656
"@types/eslint": "^9.0.0",
5757
"@types/eslint-visitor-keys": "^3.0.0",
58-
"@types/lodash": "^4.14.167",
5958
"@types/mocha": "^10.0.0",
6059
"@types/node": "^22.0.0",
6160
"@types/semver": "^7.3.10",

src/context.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { Comment, Locations, Position, Range, Token } from "./ast";
22
import type { CST, DocumentOptions } from "yaml";
33
import { ParseError } from ".";
44
import { parserOptionsToYAMLOption } from "./options";
5+
import { sortedLastIndex } from "./utils";
56

67
export class Context {
78
public readonly code: string;
@@ -120,16 +121,7 @@ class LinesAndColumns {
120121
}
121122

122123
public getLocFromIndex(index: number) {
123-
// The implementation is mostly inspired by ESLint's context.sourceCode.getLocFromIndex
124-
// See https://github.com/eslint/eslint/blob/f67d5e875324a9d899598b11807a9c7624021432/lib/languages/js/source-code/source-code.js#L657
125-
126-
// To figure out which line index is on, determine the last place at which index could
127-
// be inserted into lineStartIndices to keep the list sorted.
128-
const lastIndice = this.lineStartIndices.at(-1);
129-
const lineNumber =
130-
lastIndice != null && index >= lastIndice
131-
? this.lineStartIndices.length
132-
: this.lineStartIndices.findIndex((el) => index < el);
124+
const lineNumber = sortedLastIndex(this.lineStartIndices, index);
133125

134126
return {
135127
line: lineNumber,

src/utils.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,44 @@ function getTaggedValue(
205205
${tagText} ${text}`).toJSON();
206206
return value;
207207
}
208+
209+
/**
210+
* Find the insertion position (index) of an item in an array with items sorted
211+
* in ascending order; so that `splice(sortedIndex, 0, item)` would result in
212+
* maintaining the array's sort-ness. The array can contain duplicates.
213+
* If the item already exists in the array the index would be of the *last*
214+
* occurrence of the item.
215+
*
216+
* Runs in O(logN) time.
217+
*
218+
* MIT License | Copyright (c) 2018 remeda | https://remedajs.com/
219+
*
220+
* The implementation is copied from remeda package:
221+
* https://github.com/remeda/remeda/blob/878206eb3e8ec1c7f1300b1909b7aa629810c8bb/src/sortedLastIndex.ts
222+
* https://github.com/remeda/remeda/blob/878206eb3e8ec1c7f1300b1909b7aa629810c8bb/src/internal/binarySearchCutoffIndex.ts#L1
223+
*
224+
* @param data - The (ascending) sorted array.
225+
* @param item - The item to insert.
226+
* @returns Insertion index (In the range 0..data.length).
227+
* @signature
228+
* sortedLastIndex(data, item)
229+
* @example
230+
* sortedLastIndex(['a','a','b','c','c'], 'c') // => 5
231+
*/
232+
export function sortedLastIndex<T>(array: readonly T[], item: T): number {
233+
let lowIndex = 0;
234+
let highIndex = array.length;
235+
236+
while (lowIndex < highIndex) {
237+
const pivotIndex = (lowIndex + highIndex) >>> 1;
238+
const pivot = array[pivotIndex];
239+
240+
if (pivot <= item) {
241+
lowIndex = pivotIndex + 1;
242+
} else {
243+
highIndex = pivotIndex;
244+
}
245+
}
246+
247+
return highIndex;
248+
}

0 commit comments

Comments
 (0)