Summary
The Apex extractor's method_re cannot match method signatures whose return type contains a comma, a space, or a dot. Every such method is silently dropped from the graph — no node, no edges, no warning.
The return type is matched by a single character class:
method_re = _re.compile(
rf"^{_ANNOTATION}\s*{_ACCESS}{_MOD}\s*(?:static\s+)?[\w<>\[\]]+\s+(\w+)\s*\([^)]*\)\s*(?:throws\s+\w+\s*)?\{{?",
_re.IGNORECASE,
)
[\w<>\[\]]+ permits word chars and angle/square brackets only, so:
Map<String, Object> — comma + space → never matches
Database.QueryLocator — dot → never matches
List<Map<String, Id>> — → never matches
These are extremely common in real Apex: every Database.Batchable implementation's start() returns Database.QueryLocator, and @AuraEnabled controller methods conventionally return Map<String, Object>.
Affected versions
Present since Apex support landed (7467c1b, 2026-06-07). Verified byte-identical in v0.8.39 and v0.9.53 / HEAD (33362d9), now in graphify/extractors/apex.py.
Minimal repro
Repro.cls:
public with sharing class Repro {
public static String simpleReturn() { return ''; }
public static Map<String, Object> commaGeneric() { return null; }
public Database.QueryLocator dottedReturn(Database.BatchableContext bc) { return null; }
private static List<Map<String, Id>> nestedGeneric() { return null; }
}
from graphify.extract import extract_apex
res = extract_apex(Path("Repro.cls"))
print(sorted(n["label"] for n in res["nodes"] if n["label"].startswith(".")))
Observed (v0.8.39 and v0.9.53):
Expected: all four methods.
Real-world impact
On a 455-file production Salesforce codebase, this dropped 512 method signatures (~25% of the API surface), including every batch-class start() entry point and every Map<String, Object> controller method.
Suggested fix
Replace the return-type token with a base token plus an optional generic group that admits commas/spaces/dots (and one nested level):
_RETTYPE = r"[\w.\[\]]+(?:\s*<[^;{}()=]*>)?"
method_re = _re.compile(
rf"^{_ANNOTATION}\s*{_ACCESS}{_MOD}\s*(?:static\s+)?{_RETTYPE}\s+(\w+)\s*\([^)]*\)\s*(?:throws\s+\w+\s*)?\{{?",
_re.IGNORECASE,
)
Excluding ;{}()= inside <...> keeps declarations-with-initializers (Map<Id, X> m = new Map<Id, X>();) and control-flow lines from matching. Scanned against the 455-file corpus above: the old pattern's match set is strictly contained in the new one (0 regressions), and all 512 newly matched lines are genuine method signatures.
Happy to submit a PR with this change plus a regression test.
Summary
The Apex extractor's
method_recannot match method signatures whose return type contains a comma, a space, or a dot. Every such method is silently dropped from the graph — no node, no edges, no warning.The return type is matched by a single character class:
[\w<>\[\]]+permits word chars and angle/square brackets only, so:Map<String, Object>— comma + space → never matchesDatabase.QueryLocator— dot → never matchesList<Map<String, Id>>— → never matchesThese are extremely common in real Apex: every
Database.Batchableimplementation'sstart()returnsDatabase.QueryLocator, and@AuraEnabledcontroller methods conventionally returnMap<String, Object>.Affected versions
Present since Apex support landed (7467c1b, 2026-06-07). Verified byte-identical in v0.8.39 and v0.9.53 / HEAD (33362d9), now in
graphify/extractors/apex.py.Minimal repro
Repro.cls:Observed (v0.8.39 and v0.9.53):
Expected: all four methods.
Real-world impact
On a 455-file production Salesforce codebase, this dropped 512 method signatures (~25% of the API surface), including every batch-class
start()entry point and everyMap<String, Object>controller method.Suggested fix
Replace the return-type token with a base token plus an optional generic group that admits commas/spaces/dots (and one nested level):
Excluding
;{}()=inside<...>keeps declarations-with-initializers (Map<Id, X> m = new Map<Id, X>();) and control-flow lines from matching. Scanned against the 455-file corpus above: the old pattern's match set is strictly contained in the new one (0 regressions), and all 512 newly matched lines are genuine method signatures.Happy to submit a PR with this change plus a regression test.