Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion graphify/extractors/apex.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,13 @@ def add_edge(src: str, tgt: str, relation: str, line: int,
r"^\s*trigger\s+(\w+)\s+on\s+(\w+)\s*\(",
_re.IGNORECASE,
)
# Return type: base token (dotted names, arrays) plus an optional <...>
# generic group that may hold commas, spaces, and one nested level. A bare
# character class cannot match "Map<String, Object>" (comma, space) or
# "Database.QueryLocator" (dot), silently dropping those methods.
_RETTYPE = r"[\w.\[\]]+(?:\s*<[^;{}()=]*>)?"
method_re = _re.compile(
rf"^{_ANNOTATION}\s*{_ACCESS}{_MOD}\s*(?:static\s+)?[\w<>\[\]]+\s+(\w+)\s*\([^)]*\)\s*(?:throws\s+\w+\s*)?\{{?",
rf"^{_ANNOTATION}\s*{_ACCESS}{_MOD}\s*(?:static\s+)?{_RETTYPE}\s+(\w+)\s*\([^)]*\)\s*(?:throws\s+\w+\s*)?\{{?",
_re.IGNORECASE,
)
annotation_re = _re.compile(r"@(\w+)", _re.IGNORECASE)
Expand Down
12 changes: 12 additions & 0 deletions tests/fixtures/sample.cls
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ public with sharing class AccountService {
delete old;
}

public static Map<String, Object> getAccountSummary(Id accountId) {
return new Map<String, Object>{ 'id' => accountId };
}

public Database.QueryLocator start(Database.BatchableContext bc) {
return Database.getQueryLocator('SELECT Id FROM Account');
}

private static List<Map<String, Id>> buildNameIndex() {
return new List<Map<String, Id>>();
}

@isTest
static void testGetAccounts() {
List<Account> result = getAccounts('Customer');
Expand Down
12 changes: 12 additions & 0 deletions tests/test_languages.py
Original file line number Diff line number Diff line change
Expand Up @@ -3399,6 +3399,18 @@ def test_apex_method_extraction():
assert any("createAccounts" in l for l in labels)
assert any("deleteOldAccounts" in l for l in labels)


def test_apex_method_generic_and_dotted_return_types():
# Regression: return types containing commas/spaces (Map<String, Object>),
# dots (Database.QueryLocator), or nested generics (List<Map<String, Id>>)
# were silently dropped because the return type was matched by a single
# character class with no comma, space, or dot.
r = extract_apex(FIXTURES / "sample.cls")
labels = _labels(r)
assert any("getAccountSummary" in l for l in labels)
assert ".start()" in labels
assert any("buildNameIndex" in l for l in labels)

def test_apex_contains_and_method_relations():
r = extract_apex(FIXTURES / "sample.cls")
relations = _relations(r)
Expand Down