MCPcopy
hub / github.com/colbymchenry/codegraph / extractVariable

Method extractVariable

src/extraction/tree-sitter.ts:2411–2754  ·  view source on GitHub ↗

* Extract a variable declaration (const, let, var, etc.) * * Extracts top-level and module-level variable declarations. * Captures the variable name and first 100 chars of initializer in signature for searchability.

(node: SyntaxNode)

Source from the content-addressed store, hash-verified

2409 * Captures the variable name and first 100 chars of initializer in signature for searchability.
2410 */
2411 private extractVariable(node: SyntaxNode): void {
2412 if (!this.extractor) return;
2413
2414 // Different languages have different variable declaration structures
2415 // TypeScript/JavaScript: lexical_declaration contains variable_declarator children
2416 // Python: assignment has left (identifier) and right (value)
2417 // Go: var_declaration, short_var_declaration, const_declaration
2418
2419 const isConst = this.extractor.isConst?.(node) ?? false;
2420 const kind: NodeKind = isConst ? 'constant' : 'variable';
2421 const docstring = getPrecedingDocstring(node, this.source);
2422 const isExported = this.extractor.isExported?.(node, this.source) ?? false;
2423
2424 // Extract variable declarators based on language
2425 if (this.language === 'typescript' || this.language === 'javascript' ||
2426 this.language === 'tsx' || this.language === 'jsx') {
2427 // Handle lexical_declaration and variable_declaration
2428 // These contain one or more variable_declarator children
2429 for (let i = 0; i < node.namedChildCount; i++) {
2430 const child = node.namedChild(i);
2431 if (child?.type === 'variable_declarator') {
2432 const nameNode = getChildByField(child, 'name');
2433 const valueNode = getChildByField(child, 'value');
2434
2435 if (nameNode) {
2436 // Skip destructured patterns (e.g., `let { x, y } = $props()` in Svelte)
2437 // These produce ugly multi-line names like "{ class: className }".
2438 // EXCEPT `export const { useGetXQuery } = someApi` — the RTK Query
2439 // generated hooks: real exported symbols destructured off a createApi
2440 // result. Mint a node per binding matching the hook convention (gated
2441 // on a bare-identifier RHS so ordinary destructures stay skipped).
2442 if (nameNode.type === 'object_pattern' || nameNode.type === 'array_pattern') {
2443 if (nameNode.type === 'object_pattern' && valueNode?.type === 'identifier') {
2444 this.extractRtkHookBindings(nameNode, isExported);
2445 }
2446 continue;
2447 }
2448 const name = getNodeText(nameNode, this.source);
2449 // Arrow functions / function expressions: extract as function instead of variable
2450 if (valueNode && (valueNode.type === 'arrow_function' || valueNode.type === 'function_expression')) {
2451 this.extractFunction(valueNode);
2452 continue;
2453 }
2454
2455 // Capture first 100 chars of initializer for context (stored in signature for searchability)
2456 const initValue = valueNode ? getNodeText(valueNode, this.source).slice(0, 100) : undefined;
2457 const initSignature = initValue ? `= ${initValue}${initValue.length >= 100 ? '...' : ''}` : undefined;
2458
2459 // React HOC-wrapped components (`forwardRef`/`memo`/`styled`) — see
2460 // reactComponentHoc. The initializer is a call / tagged-template (not
2461 // a bare arrow), so without this the const is a plain `constant`,
2462 // which the JSX-render synthesizer and component resolution both skip
2463 // → `<Button/>` usages get no edge and callers/impact return empty
2464 // (the whole shadcn/ui design-system pattern, #841). PascalCase-gated
2465 // to the component naming convention so a memoization util
2466 // (`const cache = memo(fn)`) stays a constant.
2467 if (valueNode && /^[A-Z]/.test(name)) {
2468 const hoc = this.reactComponentHoc(valueNode);

Callers 1

visitNodeMethod · 0.95

Calls 15

extractFunctionMethod · 0.95
reactComponentHocMethod · 0.95
createNodeMethod · 0.95
findPiniaSetupFnMethod · 0.95
looksLikeVueStoreFileMethod · 0.95

Tested by

no test coverage detected