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

Method extractFunction

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

* Extract a function

(node: SyntaxNode, nameOverride?: string)

Source from the content-addressed store, hash-verified

1528 * Extract a function
1529 */
1530 private extractFunction(node: SyntaxNode, nameOverride?: string): void {
1531 if (!this.extractor) return;
1532
1533 // If the language provides getReceiverType and this function has a receiver
1534 // (e.g., Rust function_item inside an impl block), extract as method instead
1535 if (this.extractor.getReceiverType?.(node, this.source)) {
1536 this.extractMethod(node);
1537 return;
1538 }
1539
1540 // nameOverride is supplied only for explicitly-named anonymous functions the
1541 // caller resolved itself (e.g. arrow values of exported-const object members
1542 // — SvelteKit actions). Inline-object arrows reached by the general walker
1543 // get no override, so they still fall through to the <anonymous> skip below.
1544 let name = nameOverride ?? extractName(node, this.source, this.extractor);
1545 // For arrow functions and function expressions assigned to variables,
1546 // resolve the name from the parent variable_declarator.
1547 // e.g. `export const useAuth = () => { ... }` — the arrow_function node
1548 // has no `name` field; the name lives on the variable_declarator.
1549 if (
1550 !nameOverride &&
1551 name === '<anonymous>' &&
1552 (node.type === 'arrow_function' || node.type === 'function_expression')
1553 ) {
1554 const parent = node.parent;
1555 if (parent?.type === 'variable_declarator') {
1556 const varName = getChildByField(parent, 'name');
1557 if (varName) {
1558 name = getNodeText(varName, this.source);
1559 }
1560 }
1561 }
1562 if (name === '<anonymous>') {
1563 // Don't emit a node for the anonymous wrapper itself, but still visit its
1564 // body: AMD/RequireJS and CommonJS module wrappers (`define([], function(){…})`,
1565 // `(function(){…})()`) hold named inner functions and calls that would
1566 // otherwise be lost — the dispatcher set skipChildren, so nothing else
1567 // descends into this subtree. (#528)
1568 const body = this.extractor.resolveBody?.(node, this.extractor.bodyField)
1569 ?? getChildByField(node, this.extractor.bodyField);
1570 if (body) {
1571 this.visitFunctionBody(body, '');
1572 }
1573 return;
1574 }
1575
1576 // Check for misparse artifacts (e.g. C++ macros causing "namespace detail" functions)
1577 // Skip the node but still visit the body for calls and structural nodes
1578 if (this.extractor.isMisparsedFunction?.(name, node)) {
1579 const body = this.extractor.resolveBody?.(node, this.extractor.bodyField)
1580 ?? getChildByField(node, this.extractor.bodyField);
1581 if (body) {
1582 this.visitFunctionBody(body, '');
1583 }
1584 return;
1585 }
1586
1587 const docstring = getPrecedingDocstring(node, this.source);

Callers 7

visitNodeMethod · 0.95
extractMethodMethod · 0.95
extractRtkEndpointsMethod · 0.95
extractPiniaSetupBodyMethod · 0.95
extractVariableMethod · 0.95

Calls 9

extractMethodMethod · 0.95
visitFunctionBodyMethod · 0.95
createNodeMethod · 0.95
extractDecoratorsForMethod · 0.95
getChildByFieldFunction · 0.90
getNodeTextFunction · 0.90
getPrecedingDocstringFunction · 0.90
extractNameFunction · 0.85

Tested by

no test coverage detected