applyPatches function

String applyPatches(
  1. SourceFile sourceFile,
  2. Iterable<Patch> patches
)

Returns the result of applying all of the patches (insertions/deletions/replacements) to the contents of sourceFile.

Throws an Exception if any two of the given patches overlap.

Implementation

String applyPatches(SourceFile sourceFile, Iterable<Patch> patches) {
  final buffer = StringBuffer();
  final sortedPatches =
      patches.map((p) => SourcePatch.from(p, sourceFile)).toList()..sort();

  var lastEdgeOffset = 0;
  late Patch prev;
  for (final patch in sortedPatches) {
    if (patch.startOffset < lastEdgeOffset) {
      throw Exception('Codemod terminated due to overlapping patch.\n'
          'Previous patch:\n'
          '  $prev\n'
          '  Updated text: ${prev.updatedText}\n'
          'Overlapping patch:\n'
          '  $patch\n'
          '  Updated text: ${patch.updatedText}\n');
    }

    // Write unmodified text from end of last patch to beginning of this patch
    buffer.write(sourceFile.getText(lastEdgeOffset, patch.startOffset));
    // Write the patched text (and do nothing with the original text, which is
    // effectively the same as replacing it)
    buffer.write(patch.updatedText);

    lastEdgeOffset = patch.endOffset;
    prev = patch;
  }

  buffer.write(sourceFile.getText(lastEdgeOffset));
  return buffer.toString();
}