Spaces:
Build error
Build error
| import type { SourceMapSegment, ReverseSegment } from './sourcemap-segment'; | |
| import { COLUMN } from './sourcemap-segment'; | |
| export type MemoState = { | |
| lastKey: number; | |
| lastNeedle: number; | |
| lastIndex: number; | |
| }; | |
| export let found = false; | |
| /** | |
| * A binary search implementation that returns the index if a match is found. | |
| * If no match is found, then the left-index (the index associated with the item that comes just | |
| * before the desired index) is returned. To maintain proper sort order, a splice would happen at | |
| * the next index: | |
| * | |
| * ```js | |
| * const array = [1, 3]; | |
| * const needle = 2; | |
| * const index = binarySearch(array, needle, (item, needle) => item - needle); | |
| * | |
| * assert.equal(index, 0); | |
| * array.splice(index + 1, 0, needle); | |
| * assert.deepEqual(array, [1, 2, 3]); | |
| * ``` | |
| */ | |
| export function binarySearch( | |
| haystack: SourceMapSegment[] | ReverseSegment[], | |
| needle: number, | |
| low: number, | |
| high: number, | |
| ): number { | |
| while (low <= high) { | |
| const mid = low + ((high - low) >> 1); | |
| const cmp = haystack[mid][COLUMN] - needle; | |
| if (cmp === 0) { | |
| found = true; | |
| return mid; | |
| } | |
| if (cmp < 0) { | |
| low = mid + 1; | |
| } else { | |
| high = mid - 1; | |
| } | |
| } | |
| found = false; | |
| return low - 1; | |
| } | |
| export function upperBound( | |
| haystack: SourceMapSegment[] | ReverseSegment[], | |
| needle: number, | |
| index: number, | |
| ): number { | |
| for (let i = index + 1; i < haystack.length; index = i++) { | |
| if (haystack[i][COLUMN] !== needle) break; | |
| } | |
| return index; | |
| } | |
| export function lowerBound( | |
| haystack: SourceMapSegment[] | ReverseSegment[], | |
| needle: number, | |
| index: number, | |
| ): number { | |
| for (let i = index - 1; i >= 0; index = i--) { | |
| if (haystack[i][COLUMN] !== needle) break; | |
| } | |
| return index; | |
| } | |
| export function memoizedState(): MemoState { | |
| return { | |
| lastKey: -1, | |
| lastNeedle: -1, | |
| lastIndex: -1, | |
| }; | |
| } | |
| /** | |
| * This overly complicated beast is just to record the last tested line/column and the resulting | |
| * index, allowing us to skip a few tests if mappings are monotonically increasing. | |
| */ | |
| export function memoizedBinarySearch( | |
| haystack: SourceMapSegment[] | ReverseSegment[], | |
| needle: number, | |
| state: MemoState, | |
| key: number, | |
| ): number { | |
| const { lastKey, lastNeedle, lastIndex } = state; | |
| let low = 0; | |
| let high = haystack.length - 1; | |
| if (key === lastKey) { | |
| if (needle === lastNeedle) { | |
| found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle; | |
| return lastIndex; | |
| } | |
| if (needle >= lastNeedle) { | |
| // lastIndex may be -1 if the previous needle was not found. | |
| low = lastIndex === -1 ? 0 : lastIndex; | |
| } else { | |
| high = lastIndex; | |
| } | |
| } | |
| state.lastKey = key; | |
| state.lastNeedle = needle; | |
| return (state.lastIndex = binarySearch(haystack, needle, low, high)); | |
| } | |