(P: ParseState)
| 3980 | // (with paren counting for @(a|b)); $(...)/${}/quoted → proper node types. |
| 3981 | // Multiple parts become flat children of binary_expression per tree-sitter. |
| 3982 | function parseTestExtglobRhs(P: ParseState): TsNode[] { |
| 3983 | skipBlanks(P.L) |
| 3984 | const parts: TsNode[] = [] |
| 3985 | let segStart = P.L.b |
| 3986 | let segStartI = P.L.i |
| 3987 | let parenDepth = 0 |
| 3988 | const flushSeg = () => { |
| 3989 | if (P.L.i > segStartI) { |
| 3990 | const text = P.src.slice(segStartI, P.L.i) |
| 3991 | // Pure number stays number; everything else is extglob_pattern |
| 3992 | const type = /^\d+$/.test(text) ? 'number' : 'extglob_pattern' |
| 3993 | parts.push(mk(P, type, segStart, P.L.b, [])) |
| 3994 | } |
| 3995 | } |
| 3996 | while (P.L.i < P.L.len) { |
| 3997 | const c = peek(P.L) |
| 3998 | if (c === '\\' && P.L.i + 1 < P.L.len) { |
| 3999 | advance(P.L) |
| 4000 | advance(P.L) |
| 4001 | continue |
| 4002 | } |
| 4003 | if (c === '\n') break |
| 4004 | if (parenDepth === 0) { |
| 4005 | if (c === ']' && peek(P.L, 1) === ']') break |
| 4006 | if (c === ' ' || c === '\t') { |
| 4007 | let j = P.L.i |
| 4008 | while (j < P.L.len && (P.L.src[j] === ' ' || P.L.src[j] === '\t')) j++ |
| 4009 | const nc = P.L.src[j] ?? '' |
| 4010 | const nc1 = P.L.src[j + 1] ?? '' |
| 4011 | if ( |
| 4012 | (nc === ']' && nc1 === ']') || |
| 4013 | (nc === '&' && nc1 === '&') || |
| 4014 | (nc === '|' && nc1 === '|') |
| 4015 | ) { |
| 4016 | break |
| 4017 | } |
| 4018 | advance(P.L) |
| 4019 | continue |
| 4020 | } |
| 4021 | } |
| 4022 | // $ " ' must be parsed even inside @( ) extglob parens — parseDollarLike |
| 4023 | // consumes matching ) so parenDepth stays consistent. |
| 4024 | if (c === '$') { |
| 4025 | const c1 = peek(P.L, 1) |
| 4026 | if ( |
| 4027 | c1 === '(' || |
| 4028 | c1 === '{' || |
| 4029 | isIdentStart(c1) || |
| 4030 | SPECIAL_VARS.has(c1) |
| 4031 | ) { |
| 4032 | flushSeg() |
| 4033 | const exp = parseDollarLike(P) |
| 4034 | if (exp) parts.push(exp) |
| 4035 | segStart = P.L.b |
| 4036 | segStartI = P.L.i |
| 4037 | continue |
| 4038 | } |
| 4039 | } |
no test coverage detected