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

Method extractFunction

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

* Extract a function

(node: SyntaxNode, nameOverride?: string)

Source from the content-addressed store, hash-verified

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