* Per-match line resolver over `src`, 1-based at `baseLine`. The inline * `src.slice(0, idx).split('\n').length` idiom is O(source-length) PER MATCH, * which goes quadratic on a match-dense source (a generated function full of * `.push(` calls re-scanned tens of thousands of times was most of the
(src: string, baseLine: number)
| 118 | * never produce a match — then answers each call with a binary search. |
| 119 | */ |
| 120 | function makeLineAt(src: string, baseLine: number): (idx: number) => number { |
| 121 | let nl: number[] | null = null; |
| 122 | return (idx: number) => { |
| 123 | if (!nl) { |
| 124 | nl = []; |
| 125 | for (let i = src.indexOf('\n'); i !== -1; i = src.indexOf('\n', i + 1)) nl.push(i); |
| 126 | } |
| 127 | // Count newlines strictly before idx. |
| 128 | let lo = 0; |
| 129 | let hi = nl.length; |
| 130 | while (lo < hi) { |
| 131 | const mid = (lo + hi) >> 1; |
| 132 | if (nl[mid]! < idx) lo = mid + 1; |
| 133 | else hi = mid; |
| 134 | } |
| 135 | return baseLine + lo; |
| 136 | }; |
| 137 | } |
| 138 | |
| 139 | function registrarField(src: string): string | null { |
| 140 | const m = src.match(/this\.(\w+)\.(?:add|push|set)\(/); |
no outgoing calls
no test coverage detected