Repository navigation
Delphi extractor drops the receiver call of a chained call expression and everything inside it #2547
Description
Summary
In a Delphi (Object Pascal) unit, a call whose receiver is itself a call - MD5FileSized(TMeta.ExtendedPath(APath)).IsSame(AKey) - contributes one edge: the outer method (IsSame). The receiver call (MD5FileSized) and the calls inside its arguments (TMeta.ExtendedPath) are missing from callees of the routine and from callers of each callee.
The same holds for the paren-less statement form MD5FileSized(…).Reset;. The tree is parsed correctly; the walk stops at the receiver.
Versions
codegraph --version: 1.6.2 (Windows x64 bundle).- Windows 10 Pro 10.0.19045.
Minimal reproduction
Chain.pas:
unit Chain;
interface
type
TKey = record
function IsSame(const AOther: TKey): Boolean;
procedure Reset;
end;
TMeta = class
class function ExtendedPath(const APath: string): string; static;
end;
function MD5FileSized(const APath: string): TKey;
function TargetIsTheSame(const APath: string; const AKey: TKey): Boolean;
procedure Stmt(const APath: string);
implementation
function TKey.IsSame(const AOther: TKey): Boolean;
begin
Result := True;
end;
procedure TKey.Reset;
begin
end;
class function TMeta.ExtendedPath(const APath: string): string;
begin
Result := APath;
end;
function MD5FileSized(const APath: string): TKey;
begin
end;
function TargetIsTheSame(const APath: string; const AKey: TKey): Boolean;
begin
Result := MD5FileSized(TMeta.ExtendedPath(APath)).IsSame(AKey);
end;
procedure Stmt(const APath: string);
begin
MD5FileSized(TMeta.ExtendedPath(APath)).Reset;
end;
end.Steps, in a directory holding only that file:
codegraph init -y .
codegraph callees TargetIsTheSame
codegraph callees Stmt
codegraph callers MD5FileSized
codegraph callers ExtendedPath
Observed (1.6.2):
● 10 nodes, 11 edges
Callees of "TargetIsTheSame" (1):
method IsSame
Callees of "Stmt" (1):
method Reset
Callers of "MD5FileSized" (0):
No callers found for "MD5FileSized"
Callers of "ExtendedPath" (0):
No callers found for "ExtendedPath"
Expected: TargetIsTheSame with the callees MD5FileSized, ExtendedPath, IsSame; Stmt with MD5FileSized, ExtendedPath, Reset; MD5FileSized and ExtendedPath each with two callers.
The grammar's tree is complete (tree-sitter-pascal.wasm shipped in 1.6.2):
assignment
identifier "Result"
exprCall
exprDot
exprCall
identifier "MD5FileSized"
exprArgs
exprCall
exprDot
identifier "TMeta"
identifier "ExtendedPath"
exprArgs
identifier "APath"
identifier "IsSame"
exprArgs
identifier "AKey"
extractPascalCall reads the receiver exprCall only to build the TFoo.GetInstance().DoIt name for a T/I-prefixed factory (#645/#608); it records neither the receiver call nor the calls in its arguments, and only the outer exprArgs are visited. extractPascalParenlessCall records the receiver call only on the same T/I gate.
Where it was found
A product's Result := MD5FileSized(TFSMetadata.ExtendedPath(APath)).IsSame(AContentKey);: callers TFSMetadata.ExtendedPath --limit 500 named 12 of the 13 routines that call it, the routine holding that line being the one left out; its callees listed IsSame alone.
Activity
stalexteam commentedon Oct 13, 2026
possible solution:
colbymchenry commentedon Oct 22, 2026
Thanks for the precise report and the tree dump!
#2787 is merged to
main. The receiver call of a chained call and the calls in its arguments are now indexed, soMD5FileSizedandTMeta.ExtendedPathlist both routines as callers, in both the expression and the statement form.Typecasts are handled too. A typecast receiver like
TButton(Sender).Caption, or a value cast likeF := TFoo(Obj), now counts as a use of the type rather than as creating one. The fix ships in the next release.fix(pascal): the receiver calls of a chained Delphi call are indexed (c…