| 110 | } |
| 111 | |
| 112 | func prepareRangeContainsErrorFunction(errors []*ast.Diagnostic, originalRange core.TextRange) func(r core.TextRange) bool { |
| 113 | if len(errors) == 0 { |
| 114 | return rangeHasNoErrors |
| 115 | } |
| 116 | |
| 117 | // pick only errors that fall in range |
| 118 | sorted := core.Filter(errors, func(d *ast.Diagnostic) bool { |
| 119 | return originalRange.Overlaps(d.Loc()) |
| 120 | }) |
| 121 | if len(sorted) == 0 { |
| 122 | return rangeHasNoErrors |
| 123 | } |
| 124 | slices.SortStableFunc(sorted, func(a *ast.Diagnostic, b *ast.Diagnostic) int { return a.Pos() - b.Pos() }) |
| 125 | |
| 126 | index := 0 |
| 127 | return func(r core.TextRange) bool { |
| 128 | // in current implementation sequence of arguments [r1, r2...] is monotonically increasing. |
| 129 | // 'index' tracks the index of the most recent error that was checked. |
| 130 | for true { |
| 131 | if index >= len(sorted) { |
| 132 | // all errors in the range were already checked -> no error in specified range |
| 133 | return false |
| 134 | } |
| 135 | |
| 136 | err := sorted[index] |
| 137 | |
| 138 | if r.End() <= err.Pos() { |
| 139 | // specified range ends before the error referred by 'index' - no error in range |
| 140 | return false |
| 141 | } |
| 142 | |
| 143 | if r.Overlaps(err.Loc()) { |
| 144 | // specified range overlaps with error range |
| 145 | return true |
| 146 | } |
| 147 | |
| 148 | index++ |
| 149 | } |
| 150 | return false // unreachable |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | type formatSpanWorker struct { |
| 155 | originalRange core.TextRange |