generatedChangedRanges function
List<GeneratedTreeSitterChangedRange>
generatedChangedRanges(
- GeneratedTreeSitterTree oldTree,
- GeneratedTreeSitterNode newRoot, {
- List<
TreeSitterTableRange> newIncludedRanges = const [], - int? newRootTotalEndByte,
- TreeSitterTablePoint? newRootTotalEndPoint,
- GeneratedChangedRangeTrace? trace,
Compares an edited old generated tree with a newly parsed tree and returns the minimal structurally changed generated-node ranges.
Implementation
List<GeneratedTreeSitterChangedRange> generatedChangedRanges(
GeneratedTreeSitterTree oldTree,
GeneratedTreeSitterNode newRoot, {
List<TreeSitterTableRange> newIncludedRanges = const [],
int? newRootTotalEndByte,
TreeSitterTablePoint? newRootTotalEndPoint,
GeneratedChangedRangeTrace? trace,
}) {
final includedRangeDifferences = generatedIncludedRangeDifferences(
oldTree.includedRanges,
newIncludedRanges,
trace: trace,
);
final results = <GeneratedTreeSitterChangedRange>[];
final oldIterator = _ChangedRangeIterator.old(oldTree, trace);
final newIterator = _ChangedRangeIterator.fresh(
newRoot,
oldTree.language,
trace,
rootTotalEndByte: newRootTotalEndByte,
rootTotalEndPoint: newRootTotalEndPoint,
);
var includedRangeDifferenceIndex = 0;
var position = oldIterator.startPosition();
var nextPosition = newIterator.startPosition();
if (position.byte < nextPosition.byte) {
generatedRangeArrayAdd(results, position, nextPosition, trace: trace);
position = nextPosition;
} else if (position.byte > nextPosition.byte) {
generatedRangeArrayAdd(results, nextPosition, position, trace: trace);
nextPosition = position;
}
do {
var comparison = oldIterator.compare(newIterator);
if (comparison == _IteratorComparison.matches &&
generatedRangeArrayIntersects(
includedRangeDifferences,
includedRangeDifferenceIndex,
position.byte,
oldIterator.endPosition().byte,
trace: trace,
)) {
comparison = _IteratorComparison.mayDiffer;
}
var isChanged = false;
switch (comparison) {
case _IteratorComparison.matches:
nextPosition = oldIterator.endPosition();
case _IteratorComparison.mayDiffer:
if (oldIterator.descend(position.byte)) {
if (!newIterator.descend(position.byte)) {
isChanged = true;
nextPosition = oldIterator.endPosition();
}
} else if (newIterator.descend(position.byte)) {
isChanged = true;
nextPosition = newIterator.endPosition();
} else {
nextPosition = _minimumLength(
oldIterator.endPosition(),
newIterator.endPosition(),
);
}
case _IteratorComparison.differs:
isChanged = true;
nextPosition = _minimumLength(
oldIterator.endPosition(),
newIterator.endPosition(),
);
}
while (!oldIterator.done &&
oldIterator.endPosition().byte <= nextPosition.byte) {
oldIterator.advance();
}
while (!newIterator.done &&
newIterator.endPosition().byte <= nextPosition.byte) {
newIterator.advance();
}
while (oldIterator.visibleDepth > newIterator.visibleDepth) {
oldIterator.ascend();
}
while (newIterator.visibleDepth > oldIterator.visibleDepth) {
newIterator.ascend();
}
if (isChanged) {
generatedRangeArrayAdd(results, position, nextPosition, trace: trace);
}
position = nextPosition;
while (includedRangeDifferenceIndex < includedRangeDifferences.length) {
if (includedRangeDifferences[includedRangeDifferenceIndex].endByte <=
position.byte) {
includedRangeDifferenceIndex++;
} else {
break;
}
}
} while (!oldIterator.done && !newIterator.done);
final oldSize = oldIterator.rootEnd;
final newSize = newIterator.rootEnd;
if (oldSize.byte < newSize.byte) {
generatedRangeArrayAdd(results, oldSize, newSize, trace: trace);
} else if (newSize.byte < oldSize.byte) {
generatedRangeArrayAdd(results, newSize, oldSize, trace: trace);
}
trace?.record('ts_subtree_get_changed_ranges', <Object?>[
for (final range in results) (range.startByte, range.endByte),
]);
return List.unmodifiable(results);
}