changedRangesComparedTo method

List<TreeSitterRange> changedRangesComparedTo(
  1. TreeSitterTree other
)

Compares this edited tree with other using Tree-sitter's structural changed-range algorithm. As upstream requires, call edit first so this tree's coordinates describe the same document as other.

Implementation

List<TreeSitterRange> changedRangesComparedTo(TreeSitterTree other) {
  _checkNotDisposed();
  other._checkNotDisposed();
  var oldGenerated = _comparisonGeneratedTree;
  final newGenerated = other.generatedTree;
  if (oldGenerated == null || newGenerated == null) {
    throw UnsupportedError(
      'Tree-to-tree changed ranges require generated Tree-sitter tables.',
    );
  }
  if (!_comparisonEncodingEditsExact && source != other.source) {
    oldGenerated = oldGenerated.edit(_singleEdit(source, other.source));
  }
  final ranges = generatedChangedRanges(
    oldGenerated,
    newGenerated.rootNode,
    newIncludedRanges: newGenerated.includedRanges,
    newRootTotalEndByte: newGenerated.rootTotalEndByte,
    newRootTotalEndPoint: newGenerated.rootTotalEndPoint,
  );
  if (other._inputEncoding == TreeSitterInputEncoding.utf16LittleEndian ||
      other._inputEncoding == TreeSitterInputEncoding.utf16BigEndian) {
    final index = _SourceByteIndex(other.source);
    return List.unmodifiable([
      for (final range in ranges)
        if (index.utf16OffsetOfByte(range.startByte) case final startOffset)
          if (index.utf16OffsetOfByte(range.endByte) case final endOffset)
            TreeSitterRange(
              startByte: startOffset * 2,
              endByte: endOffset * 2,
              startPoint: _utf16PointAt(other.source, startOffset),
              endPoint: _utf16PointAt(other.source, endOffset),
            ),
    ]);
  }
  final decodedMap = other._decodedInputMap;
  if (other._inputEncoding == TreeSitterInputEncoding.custom &&
      decodedMap != null) {
    return List.unmodifiable([
      for (final range in ranges)
        TreeSitterRange(
          startByte: decodedMap.encodedByteForDecodedByte(
            range.startByte,
            end: false,
          ),
          endByte: decodedMap.encodedByteForDecodedByte(
            range.endByte,
            end: true,
          ),
          startPoint: decodedMap.encodedPointForDecodedByte(
            range.startByte,
            end: false,
          ),
          endPoint: decodedMap.encodedPointForDecodedByte(
            range.endByte,
            end: true,
          ),
        ),
    ]);
  }
  return List.unmodifiable([
    for (final range in ranges)
      TreeSitterRange(
        startByte: range.startByte,
        endByte: range.endByte,
        startPoint: TreeSitterPoint(
          range.startPoint.row,
          range.startPoint.column,
        ),
        endPoint: TreeSitterPoint(range.endPoint.row, range.endPoint.column),
      ),
  ]);
}