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

Method extractVariable

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

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