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

Method extractFunction

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

* Extract a function

(node: SyntaxNode, nameOverride?: string)

Source from the content-addressed store, hash-verified

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