(P: ParseState)
| 3523 | // [extglob_pattern, string, extglob_pattern]. Bare segments → extglob_pattern |
| 3524 | // if they have */?, else word. Stops at ) | space tab newline outside quotes. |
| 3525 | function parseCasePatternSegmented(P: ParseState): TsNode[] { |
| 3526 | const parts: TsNode[] = [] |
| 3527 | let segStart = P.L.b |
| 3528 | let segStartI = P.L.i |
| 3529 | const flushSeg = (): void => { |
| 3530 | if (P.L.i > segStartI) { |
| 3531 | const t = P.src.slice(segStartI, P.L.i) |
| 3532 | const type = /[*?]/.test(t) ? 'extglob_pattern' : 'word' |
| 3533 | parts.push(mk(P, type, segStart, P.L.b, [])) |
| 3534 | } |
| 3535 | } |
| 3536 | while (P.L.i < P.L.len) { |
| 3537 | const c = peek(P.L) |
| 3538 | if (c === '\\' && P.L.i + 1 < P.L.len) { |
| 3539 | advance(P.L) |
| 3540 | advance(P.L) |
| 3541 | continue |
| 3542 | } |
| 3543 | if (c === '"') { |
| 3544 | flushSeg() |
| 3545 | parts.push(parseDoubleQuoted(P)) |
| 3546 | segStart = P.L.b |
| 3547 | segStartI = P.L.i |
| 3548 | continue |
| 3549 | } |
| 3550 | if (c === "'") { |
| 3551 | flushSeg() |
| 3552 | const tok = nextToken(P.L, 'arg') |
| 3553 | parts.push(leaf(P, 'raw_string', tok)) |
| 3554 | segStart = P.L.b |
| 3555 | segStartI = P.L.i |
| 3556 | continue |
| 3557 | } |
| 3558 | if (c === ')' || c === '|' || c === ' ' || c === '\t' || c === '\n') break |
| 3559 | advance(P.L) |
| 3560 | } |
| 3561 | flushSeg() |
| 3562 | return parts |
| 3563 | } |
| 3564 | |
| 3565 | function parseFunction(P: ParseState, fnTok: Token): TsNode { |
| 3566 | const fnKw = leaf(P, 'function', fnTok) |
no test coverage detected