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

Function extractQuoteContext

src/utils/bash/treeSitterAnalysis.ts:224–290  ·  view source on GitHub ↗
(
  rootNode: unknown,
  command: string,
)

Source from the content-addressed store, hash-verified

222 * sync path's extractHeredocs({ quotedOnly: true }).
223 */
224export function extractQuoteContext(
225 rootNode: unknown,
226 command: string,
227): QuoteContext {
228 // Single walk collects all quote span types at once.
229 const spans: QuoteSpans = { raw: [], ansiC: [], double: [], heredoc: [] }
230 collectQuoteSpans(rootNode as TreeSitterNode, spans, false)
231 const singleQuoteSpans = spans.raw
232 const ansiCSpans = spans.ansiC
233 const doubleQuoteSpans = spans.double
234 const quotedHeredocSpans = spans.heredoc
235 const allQuoteSpans = [
236 ...singleQuoteSpans,
237 ...ansiCSpans,
238 ...doubleQuoteSpans,
239 ...quotedHeredocSpans,
240 ]
241
242 // Build a set of positions that should be excluded for each output variant.
243 // For withDoubleQuotes: remove single-quoted spans entirely, plus the
244 // opening/closing `"` delimiters of double-quoted spans (but keep the
245 // content between them). This matches the regex extractQuotedContent()
246 // semantics where `"` toggles quote state but content is still emitted.
247 const singleQuoteSet = buildPositionSet([
248 ...singleQuoteSpans,
249 ...ansiCSpans,
250 ...quotedHeredocSpans,
251 ])
252 const doubleQuoteDelimSet = new Set<number>()
253 for (const [start, end] of doubleQuoteSpans) {
254 doubleQuoteDelimSet.add(start) // opening "
255 doubleQuoteDelimSet.add(end - 1) // closing "
256 }
257 let withDoubleQuotes = ''
258 for (let i = 0; i < command.length; i++) {
259 if (singleQuoteSet.has(i)) continue
260 if (doubleQuoteDelimSet.has(i)) continue
261 withDoubleQuotes += command[i]
262 }
263
264 // fullyUnquoted: remove all quoted content
265 const fullyUnquoted = removeSpans(command, allQuoteSpans)
266
267 // unquotedKeepQuoteChars: remove content but keep delimiter chars
268 const spansWithQuoteChars: Array<[number, number, string, string]> = []
269 for (const [start, end] of singleQuoteSpans) {
270 spansWithQuoteChars.push([start, end, "'", "'"])
271 }
272 for (const [start, end] of ansiCSpans) {
273 // ansi_c_string spans include the leading $; preserve it so this
274 // matches the regex path, which treats $ as unquoted preceding '.
275 spansWithQuoteChars.push([start, end, "$'", "'"])
276 }
277 for (const [start, end] of doubleQuoteSpans) {
278 spansWithQuoteChars.push([start, end, '"', '"'])
279 }
280 for (const [start, end] of quotedHeredocSpans) {
281 // Heredoc redirect spans have no inline quote delimiters — strip entirely.

Callers 1

analyzeCommandFunction · 0.85

Calls 7

collectQuoteSpansFunction · 0.85
buildPositionSetFunction · 0.85
removeSpansFunction · 0.85
replaceSpansKeepQuotesFunction · 0.85
addMethod · 0.45
hasMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected