batchIncrementalParse<Tok, Syn> function

IncrementalResult<Tok, Syn> batchIncrementalParse<Tok, Syn>(
  1. GreenNode<Tok, Syn> previousTree,
  2. String previousSource,
  3. List<TextEdit> edits,
  4. ReparseableParsers<Tok, Syn> parsers, {
  5. IncrementalConfig config = const IncrementalConfig(),
})

Batch several edits into one incremental update.

edits must be sorted by start offset and non-overlapping. They are combined into a single super-edit over the union of their ranges (via the new source they jointly produce), then run through incrementalParse. If the combined range exceeds half the new document, falls straight to full reparse.

Implementation

IncrementalResult<Tok, Syn> batchIncrementalParse<Tok, Syn>(
  GreenNode<Tok, Syn> previousTree,
  String previousSource,
  List<TextEdit> edits,
  ReparseableParsers<Tok, Syn> parsers, {
  IncrementalConfig config = const IncrementalConfig(),
}) {
  if (edits.isEmpty) {
    return IncrementalResult(previousTree, IncrementalStrategy.tokenLevel);
  }
  if (edits.length == 1) {
    return incrementalParse(
      previousTree,
      previousSource,
      edits.first,
      parsers,
      config: config,
    );
  }

  var newSource = previousSource;
  for (final edit in edits) {
    newSource = edit.apply(newSource);
  }
  var minStart = edits.first.startOffset;
  var maxEnd = edits.first.endOffset + edits.first.lengthDelta;
  for (final e in edits) {
    if (e.startOffset < minStart) minStart = e.startOffset;
    final end = e.endOffset + e.lengthDelta;
    if (end > maxEnd) maxEnd = end;
  }

  if (maxEnd - minStart > newSource.length ~/ 2) {
    return _fullReparse(newSource, parsers);
  }

  final combined = TextEdit(
    minStart,
    edits.last.endOffset,
    newSource.substring(minStart, minStart + (maxEnd - minStart)),
  );
  return incrementalParse(
    previousTree,
    previousSource,
    combined,
    parsers,
    config: config,
  );
}