MCPcopy Index your code
hub / github.com/claude-code-best/claude-code / parseCommand

Function parseCommand

src/utils/bash/bashParser.ts:991–1131  ·  view source on GitHub ↗

Parse a single command: simple, compound, or control structure.

(P: ParseState)

Source from the content-addressed store, hash-verified

989
990/** Parse a single command: simple, compound, or control structure. */
991function parseCommand(P: ParseState): TsNode | null {
992 skipBlanks(P.L)
993 const save = saveLex(P.L)
994 const t = nextToken(P.L, 'cmd')
995
996 if (t.type === 'EOF') {
997 restoreLex(P.L, save)
998 return null
999 }
1000
1001 // Negation — tree-sitter wraps just the command, redirects go outside.
1002 // `! cmd > out` → redirected_statement(negated_command(!, cmd), >out)
1003 if (t.type === 'OP' && t.value === '!') {
1004 const bang = leaf(P, '!', t)
1005 const inner = parseCommand(P)
1006 if (!inner) {
1007 restoreLex(P.L, save)
1008 return null
1009 }
1010 // If inner is a redirected_statement, hoist redirects outside negation
1011 if (inner.type === 'redirected_statement' && inner.children.length >= 2) {
1012 const cmd = inner.children[0]!
1013 const redirs = inner.children.slice(1)
1014 const neg = mk(P, 'negated_command', bang.startIndex, cmd.endIndex, [
1015 bang,
1016 cmd,
1017 ])
1018 const lastR = redirs[redirs.length - 1]!
1019 return mk(P, 'redirected_statement', neg.startIndex, lastR.endIndex, [
1020 neg,
1021 ...redirs,
1022 ])
1023 }
1024 return mk(P, 'negated_command', bang.startIndex, inner.endIndex, [
1025 bang,
1026 inner,
1027 ])
1028 }
1029
1030 if (t.type === 'OP' && t.value === '(') {
1031 const open = leaf(P, '(', t)
1032 const body = parseStatements(P, ')')
1033 const closeTok = nextToken(P.L, 'cmd')
1034 const close =
1035 closeTok.type === 'OP' && closeTok.value === ')'
1036 ? leaf(P, ')', closeTok)
1037 : mk(P, ')', open.endIndex, open.endIndex, [])
1038 const node = mk(P, 'subshell', open.startIndex, close.endIndex, [
1039 open,
1040 ...body,
1041 close,
1042 ])
1043 return maybeRedirect(P, node)
1044 }
1045
1046 if (t.type === 'OP' && t.value === '((') {
1047 const open = leaf(P, '((', t)
1048 const exprs = parseArithCommaList(P, '))', 'var')

Callers 4

parsePipelineFunction · 0.70
parseSimpleCommandFunction · 0.70
tryParseRedirectFunction · 0.70
parseFunctionFunction · 0.70

Calls 15

skipBlanksFunction · 0.85
saveLexFunction · 0.85
nextTokenFunction · 0.85
restoreLexFunction · 0.85
leafFunction · 0.85
parseStatementsFunction · 0.85
maybeRedirectFunction · 0.85
parseArithCommaListFunction · 0.85
parseTestExprFunction · 0.85
parseIfFunction · 0.85
parseWhileFunction · 0.85
parseForFunction · 0.85

Tested by

no test coverage detected