(P: ParseState)
| 2213 | } |
| 2214 | |
| 2215 | function tryParseBraceExpr(P: ParseState): TsNode | null { |
| 2216 | // {N..M} where N, M are numbers or single chars |
| 2217 | const save = saveLex(P.L) |
| 2218 | if (peek(P.L) !== '{') return null |
| 2219 | const oStart = P.L.b |
| 2220 | advance(P.L) |
| 2221 | const oEnd = P.L.b |
| 2222 | // First part |
| 2223 | const p1Start = P.L.b |
| 2224 | while (isDigit(peek(P.L)) || isIdentStart(peek(P.L))) advance(P.L) |
| 2225 | const p1End = P.L.b |
| 2226 | if (p1End === p1Start || peek(P.L) !== '.' || peek(P.L, 1) !== '.') { |
| 2227 | restoreLex(P.L, save) |
| 2228 | return null |
| 2229 | } |
| 2230 | const dotStart = P.L.b |
| 2231 | advance(P.L) |
| 2232 | advance(P.L) |
| 2233 | const dotEnd = P.L.b |
| 2234 | const p2Start = P.L.b |
| 2235 | while (isDigit(peek(P.L)) || isIdentStart(peek(P.L))) advance(P.L) |
| 2236 | const p2End = P.L.b |
| 2237 | if (p2End === p2Start || peek(P.L) !== '}') { |
| 2238 | restoreLex(P.L, save) |
| 2239 | return null |
| 2240 | } |
| 2241 | const cStart = P.L.b |
| 2242 | advance(P.L) |
| 2243 | const cEnd = P.L.b |
| 2244 | const p1Text = sliceBytes(P, p1Start, p1End) |
| 2245 | const p2Text = sliceBytes(P, p2Start, p2End) |
| 2246 | const p1IsNum = /^\d+$/.test(p1Text) |
| 2247 | const p2IsNum = /^\d+$/.test(p2Text) |
| 2248 | // Valid brace expression: both numbers OR both single chars. Mixed = reject. |
| 2249 | if (p1IsNum !== p2IsNum) { |
| 2250 | restoreLex(P.L, save) |
| 2251 | return null |
| 2252 | } |
| 2253 | if (!p1IsNum && (p1Text.length !== 1 || p2Text.length !== 1)) { |
| 2254 | restoreLex(P.L, save) |
| 2255 | return null |
| 2256 | } |
| 2257 | const p1Type = p1IsNum ? 'number' : 'word' |
| 2258 | const p2Type = p2IsNum ? 'number' : 'word' |
| 2259 | return mk(P, 'brace_expression', oStart, cEnd, [ |
| 2260 | mk(P, '{', oStart, oEnd, []), |
| 2261 | mk(P, p1Type, p1Start, p1End, []), |
| 2262 | mk(P, '..', dotStart, dotEnd, []), |
| 2263 | mk(P, p2Type, p2Start, p2End, []), |
| 2264 | mk(P, '}', cStart, cEnd, []), |
| 2265 | ]) |
| 2266 | } |
| 2267 | |
| 2268 | function tryParseBraceLikeCat(P: ParseState): TsNode[] | null { |
| 2269 | // {a,b,c} or {} → split into word fragments like tree-sitter does |
no test coverage detected