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

Method extractPascalCall

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

* Extract function calls from a Pascal expression

(node: SyntaxNode)

Source from the content-addressed store, hash-verified

6526 * Extract function calls from a Pascal expression
6527 */
6528 private extractPascalCall(node: SyntaxNode): void {
6529 if (this.nodeStack.length === 0) return;
6530 const callerId = this.nodeStack[this.nodeStack.length - 1];
6531 if (!callerId) return;
6532
6533 // Get the callee name — first child is typically the identifier or exprDot
6534 const firstChild = node.namedChild(0);
6535 if (!firstChild) return;
6536
6537 let calleeName = '';
6538 if (firstChild.type === 'exprDot') {
6539 // Chained static-factory call: `TFoo.GetInstance().DoIt()` — the exprDot's
6540 // receiver is itself an `exprCall`, so the bare identifier list would
6541 // collapse to just `DoIt` and mis-resolve to a same-named method on an
6542 // unrelated class. Encode `TFoo.GetInstance().DoIt` so resolution infers
6543 // DoIt's class from what `TFoo.GetInstance` RETURNS (#645/#608). Only a
6544 // capitalized class-factory chain; a unary outer method.
6545 const innerCall = firstChild.namedChildren.find((c: SyntaxNode) => c.type === 'exprCall');
6546 const outerId = firstChild.namedChildren.filter((c: SyntaxNode) => c.type === 'identifier').pop();
6547 const method = outerId ? getNodeText(outerId, this.source) : '';
6548 if (innerCall && method && /^\w+$/.test(method)) {
6549 const innerFirst = innerCall.namedChild(0);
6550 let innerCallee = '';
6551 if (innerFirst?.type === 'exprDot') {
6552 innerCallee = innerFirst.namedChildren
6553 .filter((c: SyntaxNode) => c.type === 'identifier')
6554 .map((id: SyntaxNode) => getNodeText(id, this.source))
6555 .join('.');
6556 } else if (innerFirst?.type === 'identifier') {
6557 innerCallee = getNodeText(innerFirst, this.source);
6558 }
6559 // Gate on the Delphi type-naming convention — `TFoo` classes / `IFoo`
6560 // interfaces — so a class-factory chain re-encodes but a capitalized
6561 // VARIABLE/parameter chain (Pascal capitalizes locals too: `Curve.X().Y()`,
6562 // `Self.X().Y()`) stays bare and keeps its existing bare-name resolution.
6563 calleeName = innerCallee && /^[TI][A-Z]/.test(innerCallee)
6564 ? `${innerCallee}().${method}`
6565 : method;
6566 } else {
6567 // Qualified call: Obj.Method(...)
6568 const identifiers = firstChild.namedChildren.filter(
6569 (c: SyntaxNode) => c.type === 'identifier'
6570 );
6571 if (identifiers.length > 0) {
6572 calleeName = identifiers.map((id: SyntaxNode) => getNodeText(id, this.source)).join('.');
6573 }
6574 }
6575 } else if (firstChild.type === 'identifier') {
6576 calleeName = getNodeText(firstChild, this.source);
6577 }
6578
6579 if (calleeName) {
6580 this.unresolvedReferences.push({
6581 fromNodeId: callerId,
6582 referenceName: calleeName,
6583 referenceKind: 'calls',
6584 line: node.startPosition.row + 1,
6585 column: node.startPosition.column,

Callers 3

visitPascalNodeMethod · 0.95
visitPascalBlockMethod · 0.95

Calls 3

visitPascalBlockMethod · 0.95
getNodeTextFunction · 0.90
joinMethod · 0.45

Tested by

no test coverage detected