MCPcopy Create free account
hub / github.com/AnukarOP/claude-code-leaked / parseExpansionRest

Function parseExpansionRest

source code/utils/bash/bashParser.ts:2809–3033  ·  view source on GitHub ↗
(
  P: ParseState,
  nodeType: string,
  stopAtSlash: boolean,
)

Source from the content-addressed store, hash-verified

2807}
2808
2809function parseExpansionRest(
2810 P: ParseState,
2811 nodeType: string,
2812 stopAtSlash: boolean,
2813): TsNode | null {
2814 // Don't skipBlanks — `${var:- }` space IS the word. Stop at } or newline
2815 // (`${var:\n}` emits no word). stopAtSlash=true stops at `/` for pat/repl
2816 // split in ${var/pat/repl}. nodeType 'replword' is word-mode for the
2817 // replacement in `/` `//` — same as 'word' but `(` is NOT array.
2818 const start = P.L.b
2819 // Value-substitution RHS starting with `(` parses as array: ${var:-(x)} →
2820 // (expansion (variable_name) (array (word))). Only for 'word' context (not
2821 // pattern-matching operators which emit regex, and not 'replword' where `(`
2822 // is a regular char per grammar `_expansion_regex_replacement`).
2823 if (nodeType === 'word' && peek(P.L) === '(') {
2824 advance(P.L)
2825 const open = mk(P, '(', start, P.L.b, [])
2826 const elems: TsNode[] = [open]
2827 while (P.L.i < P.L.len) {
2828 skipBlanks(P.L)
2829 const c = peek(P.L)
2830 if (c === ')' || c === '}' || c === '\n' || c === '') break
2831 const wStart = P.L.b
2832 while (P.L.i < P.L.len) {
2833 const wc = peek(P.L)
2834 if (
2835 wc === ')' ||
2836 wc === '}' ||
2837 wc === ' ' ||
2838 wc === '\t' ||
2839 wc === '\n' ||
2840 wc === ''
2841 ) {
2842 break
2843 }
2844 advance(P.L)
2845 }
2846 if (P.L.b > wStart) elems.push(mk(P, 'word', wStart, P.L.b, []))
2847 else break
2848 }
2849 if (peek(P.L) === ')') {
2850 const cStart = P.L.b
2851 advance(P.L)
2852 elems.push(mk(P, ')', cStart, P.L.b, []))
2853 }
2854 while (peek(P.L) === '\n') advance(P.L)
2855 return mk(P, 'array', start, P.L.b, elems)
2856 }
2857 // REGEX mode: flat single-span scan. Quotes are opaque (skipped past so
2858 // `/` inside them doesn't break stopAtSlash), but NOT emitted as separate
2859 // nodes — the entire range becomes one regex node.
2860 if (nodeType === 'regex') {
2861 let braceDepth = 0
2862 while (P.L.i < P.L.len) {
2863 const c = peek(P.L)
2864 if (c === '\n') break
2865 if (braceDepth === 0) {
2866 if (c === '}') break

Callers 1

parseExpansionBodyFunction · 0.85

Calls 13

advanceFunction · 0.85
mkFunction · 0.85
skipBlanksFunction · 0.85
flushSegFunction · 0.85
parseDollarLikeFunction · 0.85
isIdentStartFunction · 0.85
isDigitFunction · 0.85
parseDoubleQuotedFunction · 0.85
parseProcessSubFunction · 0.85
parseBacktickFunction · 0.85
shiftMethod · 0.80
peekFunction · 0.70

Tested by

no test coverage detected