MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / extractVariable

Method extractVariable

src/extraction/tree-sitter.ts:2544–2888  ·  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

2542 * Captures the variable name and first 100 chars of initializer in signature for searchability.
2543 */
2544 private extractVariable(node: SyntaxNode): void {
2545 if (!this.extractor) return;
2546
2547 // Different languages have different variable declaration structures
2548 // TypeScript/JavaScript: lexical_declaration contains variable_declarator children
2549 // Python: assignment has left (identifier) and right (value)
2550 // Go: var_declaration, short_var_declaration, const_declaration
2551
2552 const isConst = this.extractor.isConst?.(node) ?? false;
2553 const kind: NodeKind = isConst ? 'constant' : 'variable';
2554 const docstring = getPrecedingDocstring(node, this.source);
2555 const isExported = this.extractor.isExported?.(node, this.source) ?? false;
2556
2557 // Extract variable declarators based on language
2558 if (this.language === 'typescript' || this.language === 'javascript' ||
2559 this.language === 'tsx' || this.language === 'jsx' || this.language === 'cfscript' ||
2560 this.language === 'arkts') {
2561 // Handle lexical_declaration and variable_declaration
2562 // These contain one or more variable_declarator children
2563 for (let i = 0; i < node.namedChildCount; i++) {
2564 const child = node.namedChild(i);
2565 if (child?.type === 'variable_declarator') {
2566 const nameNode = getChildByField(child, 'name');
2567 const valueNode = getChildByField(child, 'value');
2568
2569 if (nameNode) {
2570 // Skip destructured patterns (e.g., `let { x, y } = $props()` in Svelte)
2571 // These produce ugly multi-line names like "{ class: className }".
2572 // EXCEPT `export const { useGetXQuery } = someApi` — the RTK Query
2573 // generated hooks: real exported symbols destructured off a createApi
2574 // result. Mint a node per binding matching the hook convention (gated
2575 // on a bare-identifier RHS so ordinary destructures stay skipped).
2576 if (nameNode.type === 'object_pattern' || nameNode.type === 'array_pattern') {
2577 if (nameNode.type === 'object_pattern' && valueNode?.type === 'identifier') {
2578 this.extractRtkHookBindings(nameNode, isExported);
2579 }
2580 continue;
2581 }
2582 const name = getNodeText(nameNode, this.source);
2583 // Arrow functions / function expressions: extract as function instead of variable
2584 if (valueNode && (valueNode.type === 'arrow_function' || valueNode.type === 'function_expression')) {
2585 this.extractFunction(valueNode);
2586 continue;
2587 }
2588
2589 // Capture first 100 chars of initializer for context (stored in signature for searchability)
2590 const initValue = valueNode ? getNodeText(valueNode, this.source).slice(0, 100) : undefined;
2591 const initSignature = initValue ? `= ${initValue}${initValue.length >= 100 ? '...' : ''}` : undefined;
2592
2593 // React HOC-wrapped components (`forwardRef`/`memo`/`styled`) — see
2594 // reactComponentHoc. The initializer is a call / tagged-template (not
2595 // a bare arrow), so without this the const is a plain `constant`,
2596 // which the JSX-render synthesizer and component resolution both skip
2597 // → `<Button/>` usages get no edge and callers/impact return empty
2598 // (the whole shadcn/ui design-system pattern, #841). PascalCase-gated
2599 // to the component naming convention so a memoization util
2600 // (`const cache = memo(fn)`) stays a constant.
2601 if (valueNode && /^[A-Z]/.test(name)) {

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