Repository: atom/atom
File: src/tree-sitter-language-mode.js (JavaScript)

Code before:
      const iterator = marker.languageLayer.buildHighlightIterator();
      if (
        iterator.seek(targetIndex, containingTags, containingTagStartIndices)
      ) {
        this.iterators.push(iterator);
      }
    }
    this.iterators.sort((a, b) => b.compare(a));
    return containingTags;
  }

  moveToSuccessor() {
    let leader = last(this.iterators);
    if (leader.moveToSuccessor()) {
      const leaderIndex = this.iterators.length - 1;
      let i = leaderIndex;
      while (i > 0 && this.iterators[i - 1].compare(leader) < 0) i--;
      if (i < leaderIndex) {
        this.iterators.splice(i, 0, this.iterators.pop());
        this.trackLayerDepth();
      }
    } else {
      this.iterators.pop();
      this.trackLayerDepth();
    }
  }

  trackLayerDepth() {
    let i = this.iterators.length - 1;
    let iterator = this.iterators[i];
    if (!iterator) return;
    const offset = iterator.getOffset();
    if (iterator.languageLayer.isOpaque) {
      this.opaqueLayerDepth = iterator.languageLayer.depth;
    }

    while (i > 0) {
      i--;
      iterator = this.iterators[i];
      if (iterator.startOffset > offset) break;
      if (iterator.languageLayer.isOpaque) {
        const { depth } = iterator.languageLayer;
        if (depth > this.opaqueLayerDepth) {
          this.opaqueLayerDepth = depth;
        }
      }
    }
  }

  getPosition() {
    const iterator = last(this.iterators);

Review comment (suggestion):
The main difference in `moveToSuccessor` is that like `seek`, I've updated it so that it can return `false`, meaning that the iterator has fallen off the end and should be removed.

Code after:
      const iterator = marker.languageLayer.buildHighlightIterator();
      if (
        iterator.seek(targetIndex, containingTags, containingTagStartIndices)
      ) {
        this.iterators.push(iterator);
      }
    }

    // Sort the iterators so that the last one in the array is the earliest
    // in the document, and represents the current position.
    this.iterators.sort((a, b) => b.compare(a));
    this.detectCoveredScope();

    return containingTags;
  }

  moveToSuccessor() {
    // Advance the earliest layer iterator to its next scope boundary.
    let leader = last(this.iterators);

    // Maintain the sorting of the iterators by their position in the document.
    if (leader.moveToSuccessor()) {
      const leaderIndex = this.iterators.length - 1;
      let i = leaderIndex;
      while (i > 0 && this.iterators[i - 1].compare(leader) < 0) i--;
      if (i < leaderIndex) {
        this.iterators.splice(i, 0, this.iterators.pop());
      }
    } else {
      // If the layer iterator was at the end of its syntax tree, then remove
      // it from the array.
      this.iterators.pop();
    }

    this.detectCoveredScope();
  }

  // Detect whether or not another more deeply-nested language layer has a
  // scope boundary at this same position. If so, the current language layer's
  // scope boundary should not be reported.
  detectCoveredScope() {
    const layerCount = this.iterators.length;
    if (layerCount > 1) {
      const first = this.iterators[layerCount - 1];
      const next = this.iterators[layerCount - 2];
      if (
        next.offset === first.offset &&
        next.atEnd === first.atEnd &&
        next.languageLayer.depth > first.languageLayer.depth
      ) {
        this.currentScopeIsCovered = true;