Appearance
| 1 | namespace Source is | |
| 2 | use Collections; | |
| 3 | ||
| 4 | use Ghul.Pipes; | |
| 5 | ||
| 6 | // The pre-edit spans of the function bodies an incremental EDIT | |
| 7 | // re-walks. A symbol-use or definition entry inside one of these is | |
| 8 | // re-recorded fresh by the re-walk, so reconciliation discards it | |
| 9 | // rather than translating it. | |
| 10 | // | |
| 11 | // Function bodies neither nest nor overlap, so the spans sort by start | |
| 12 | // position and a binary search answers `contains`. | |
| 13 | class BODY_SPANS is | |
| 14 | _spans: LIST[LOCATION]; | |
| 15 | _prepared: bool; | |
| 16 | ||
| 17 | init() is | |
| 18 | _spans = LIST[LOCATION](); | |
| 19 | si | |
| 20 | ||
| 21 | // Internal locations are synthesised — their packed position is | |
| 22 | // (1,1) by construction and would otherwise drop any real symbol | |
| 23 | // declared at line 1 column 1 (a top-level namespace, the first | |
| 24 | // class in the file) when reconciliation calls `contains` with | |
| 25 | // file_name unchecked. | |
| 26 | add(span: LOCATION) is | |
| 27 | if !span.is_internal then | |
| 28 | _spans.add(span); | |
| 29 | _prepared = false; | |
| 30 | fi | |
| 31 | si | |
| 32 | ||
| 33 | // Is a (packed) position inside one of the re-walked bodies? | |
| 34 | contains(position: int) -> bool is | |
| 35 | _prepare(); | |
| 36 | ||
| 37 | // last span starting at or before `position` | |
| 38 | let lo mut = 0; | |
| 39 | let hi mut = _spans.count; | |
| 40 | ||
| 41 | while lo < hi do | |
| 42 | let mid = (lo + hi) / 2; | |
| 43 | ||
| 44 | if _spans[mid].start <= position then | |
| 45 | lo = mid + 1; | |
| 46 | else | |
| 47 | hi = mid; | |
| 48 | fi | |
| 49 | od | |
| 50 | ||
| 51 | return lo > 0 /\ _spans[lo - 1].contains(position); | |
| 52 | si | |
| 53 | ||
| 54 | _prepare() is | |
| 55 | if _prepared then | |
| 56 | return; | |
| 57 | fi | |
| 58 | ||
| 59 | _spans = LIST[LOCATION](_spans |> sort((a, b) => a.start - b.start)); | |
| 60 | _prepared = true; | |
| 61 | si | |
| 62 | si | |
| 63 | si |