|
import { MappedCode } from '../utils/mapped_code.js'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function slice_source(code_slice, offset, { file_basename, filename, get_location }) { |
|
return { |
|
source: code_slice, |
|
get_location: (index) => get_location(index + offset), |
|
file_basename, |
|
filename |
|
}; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
function calculate_replacements(re, get_replacement, source) { |
|
|
|
|
|
|
|
const replacements = []; |
|
source.replace(re, (...match) => { |
|
replacements.push( |
|
get_replacement(...match).then((replacement) => { |
|
const matched_string = match[0]; |
|
const offset = match[match.length - 2]; |
|
return { offset, length: matched_string.length, replacement }; |
|
}) |
|
); |
|
return ''; |
|
}); |
|
return Promise.all(replacements); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
function perform_replacements(replacements, source) { |
|
const out = new MappedCode(); |
|
let last_end = 0; |
|
for (const { offset, length, replacement } of replacements) { |
|
const unchanged_prefix = MappedCode.from_source( |
|
slice_source(source.source.slice(last_end, offset), last_end, source) |
|
); |
|
out.concat(unchanged_prefix).concat(replacement); |
|
last_end = offset + length; |
|
} |
|
const unchanged_suffix = MappedCode.from_source( |
|
slice_source(source.source.slice(last_end), last_end, source) |
|
); |
|
return out.concat(unchanged_suffix); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function replace_in_code(regex, get_replacement, location) { |
|
const replacements = await calculate_replacements(regex, get_replacement, location.source); |
|
return perform_replacements(replacements, location); |
|
} |
|
|