MCPcopy Index your code
hub / github.com/codeaashu/claude-code / parseExpansionBody

Function parseExpansionBody

src/utils/bash/bashParser.ts:2555–2805  ·  view source on GitHub ↗
(P: ParseState)

Source from the content-addressed store, hash-verified

2553}
2554
2555function parseExpansionBody(P: ParseState): TsNode[] {
2556 const out: TsNode[] = []
2557 skipBlanks(P.L)
2558 // Bizarre cases: ${#!} ${!#} ${!##} ${!# } ${!## } all emit empty (expansion)
2559 // — both # and ! become anonymous nodes when only combined with each other
2560 // and optional trailing space before }. Note ${!##/} does NOT match (has
2561 // content after), so it parses normally as (special_variable_name)(regex).
2562 {
2563 const c0 = peek(P.L)
2564 const c1 = peek(P.L, 1)
2565 if (c0 === '#' && c1 === '!' && peek(P.L, 2) === '}') {
2566 advance(P.L)
2567 advance(P.L)
2568 return out
2569 }
2570 if (c0 === '!' && c1 === '#') {
2571 // ${!#} ${!##} with optional trailing space then }
2572 let j = 2
2573 if (peek(P.L, j) === '#') j++
2574 if (peek(P.L, j) === ' ') j++
2575 if (peek(P.L, j) === '}') {
2576 while (j-- > 0) advance(P.L)
2577 return out
2578 }
2579 }
2580 }
2581 // Optional # prefix for length
2582 if (peek(P.L) === '#') {
2583 const s = P.L.b
2584 advance(P.L)
2585 out.push(mk(P, '#', s, P.L.b, []))
2586 }
2587 // Optional ! prefix for indirect expansion: ${!varname} ${!prefix*} ${!prefix@}
2588 // Only when followed by an identifier — ${!} alone is special var $!
2589 // Also = ~ prefixes (zsh-style ${=var} ${~var})
2590 const pc = peek(P.L)
2591 if (
2592 (pc === '!' || pc === '=' || pc === '~') &&
2593 (isIdentStart(peek(P.L, 1)) || isDigit(peek(P.L, 1)))
2594 ) {
2595 const s = P.L.b
2596 advance(P.L)
2597 out.push(mk(P, pc, s, P.L.b, []))
2598 }
2599 skipBlanks(P.L)
2600 // Variable name
2601 if (isIdentStart(peek(P.L))) {
2602 const s = P.L.b
2603 while (isIdentChar(peek(P.L))) advance(P.L)
2604 out.push(mk(P, 'variable_name', s, P.L.b, []))
2605 } else if (isDigit(peek(P.L))) {
2606 const s = P.L.b
2607 while (isDigit(peek(P.L))) advance(P.L)
2608 out.push(mk(P, 'variable_name', s, P.L.b, []))
2609 } else if (SPECIAL_VARS.has(peek(P.L))) {
2610 const s = P.L.b
2611 advance(P.L)
2612 out.push(mk(P, 'special_variable_name', s, P.L.b, []))

Callers 1

parseDollarLikeFunction · 0.85

Calls 14

skipBlanksFunction · 0.85
advanceFunction · 0.85
mkFunction · 0.85
isIdentStartFunction · 0.85
isDigitFunction · 0.85
isIdentCharFunction · 0.85
parseArithExprFunction · 0.85
parseDoubleQuotedFunction · 0.85
parseExpansionRestFunction · 0.85
peekFunction · 0.70

Tested by

no test coverage detected