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

Method extractPascalCall

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

* Extract function calls from a Pascal expression

(node: SyntaxNode)

Source from the content-addressed store, hash-verified

6473 * Extract function calls from a Pascal expression
6474 */
6475 private extractPascalCall(node: SyntaxNode): void {
6476 if (this.nodeStack.length === 0) return;
6477 const callerId = this.nodeStack[this.nodeStack.length - 1];
6478 if (!callerId) return;
6479
6480 // Get the callee name — first child is typically the identifier or exprDot
6481 const firstChild = node.namedChild(0);
6482 if (!firstChild) return;
6483
6484 let calleeName = '';
6485 if (firstChild.type === 'exprDot') {
6486 // Chained static-factory call: `TFoo.GetInstance().DoIt()` — the exprDot's
6487 // receiver is itself an `exprCall`, so the bare identifier list would
6488 // collapse to just `DoIt` and mis-resolve to a same-named method on an
6489 // unrelated class. Encode `TFoo.GetInstance().DoIt` so resolution infers
6490 // DoIt's class from what `TFoo.GetInstance` RETURNS (#645/#608). Only a
6491 // capitalized class-factory chain; a unary outer method.
6492 const innerCall = firstChild.namedChildren.find((c: SyntaxNode) => c.type === 'exprCall');
6493 const outerId = firstChild.namedChildren.filter((c: SyntaxNode) => c.type === 'identifier').pop();
6494 const method = outerId ? getNodeText(outerId, this.source) : '';
6495 if (innerCall && method && /^\w+$/.test(method)) {
6496 const innerFirst = innerCall.namedChild(0);
6497 let innerCallee = '';
6498 if (innerFirst?.type === 'exprDot') {
6499 innerCallee = innerFirst.namedChildren
6500 .filter((c: SyntaxNode) => c.type === 'identifier')
6501 .map((id: SyntaxNode) => getNodeText(id, this.source))
6502 .join('.');
6503 } else if (innerFirst?.type === 'identifier') {
6504 innerCallee = getNodeText(innerFirst, this.source);
6505 }
6506 // Gate on the Delphi type-naming convention — `TFoo` classes / `IFoo`
6507 // interfaces — so a class-factory chain re-encodes but a capitalized
6508 // VARIABLE/parameter chain (Pascal capitalizes locals too: `Curve.X().Y()`,
6509 // `Self.X().Y()`) stays bare and keeps its existing bare-name resolution.
6510 calleeName = innerCallee && /^[TI][A-Z]/.test(innerCallee)
6511 ? `${innerCallee}().${method}`
6512 : method;
6513 } else {
6514 // Qualified call: Obj.Method(...)
6515 const identifiers = firstChild.namedChildren.filter(
6516 (c: SyntaxNode) => c.type === 'identifier'
6517 );
6518 if (identifiers.length > 0) {
6519 calleeName = identifiers.map((id: SyntaxNode) => getNodeText(id, this.source)).join('.');
6520 }
6521 }
6522 } else if (firstChild.type === 'identifier') {
6523 calleeName = getNodeText(firstChild, this.source);
6524 }
6525
6526 if (calleeName) {
6527 this.unresolvedReferences.push({
6528 fromNodeId: callerId,
6529 referenceName: calleeName,
6530 referenceKind: 'calls',
6531 line: node.startPosition.row + 1,
6532 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