Spaces:
Runtime error
Runtime error
/** @typedef {import('./types').Location} Location */ | |
/** | |
* @param {import('./types').Range} range | |
* @param {number} index | |
*/ | |
function rangeContains(range, index) { | |
return range.start <= index && index < range.end; | |
} | |
/** | |
* @param {string} source | |
* @param {import('./types').Options} [options] | |
*/ | |
export function getLocator(source, options = {}) { | |
const { offsetLine = 0, offsetColumn = 0 } = options; | |
let start = 0; | |
const ranges = source.split('\n').map((line, i) => { | |
const end = start + line.length + 1; | |
/** @type {import('./types').Range} */ | |
const range = { start, end, line: i }; | |
start = end; | |
return range; | |
}); | |
let i = 0; | |
/** | |
* @param {string | number} search | |
* @param {number} [index] | |
* @returns {Location | undefined} | |
*/ | |
function locator(search, index) { | |
if (typeof search === 'string') { | |
search = source.indexOf(search, index ?? 0); | |
} | |
if (search === -1) return undefined; | |
let range = ranges[i]; | |
const d = search >= range.end ? 1 : -1; | |
while (range) { | |
if (rangeContains(range, search)) { | |
return { | |
line: offsetLine + range.line, | |
column: offsetColumn + search - range.start, | |
character: search | |
}; | |
} | |
i += d; | |
range = ranges[i]; | |
} | |
} | |
return locator; | |
} | |
/** | |
* @param {string} source | |
* @param {string | number} search | |
* @param {import('./types').Options} [options] | |
* @returns {Location | undefined} | |
*/ | |
export function locate(source, search, options) { | |
return getLocator(source, options)(search, options && options.startIndex); | |
} | |