From b8e2033e3c39d8565aa3e9d2a76ef9ffc5d55448 Mon Sep 17 00:00:00 2001 From: nikhil2004 Date: Wed, 23 Sep 2026 14:46:00 +0530 Subject: [PATCH] fix(php): prevent closure fallback leak and support fluent routing prefixes --- graphify/extractors/engine.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/graphify/extractors/engine.py b/graphify/extractors/engine.py index 574bd5c38..0768ec96f 100644 --- a/graphify/extractors/engine.py +++ b/graphify/extractors/engine.py @@ -3500,6 +3500,21 @@ def _php_get_route_name(closure_node, src: bytes) -> str | None: if path_text is not None and path_text.startswith("/"): prefixes.append(path_text) + # Process any fluent method chain prefixes on the same statement + fluent = call.child_by_field_name("object") + while fluent is not None and fluent.type == "member_call_expression": + f_args = fluent.child_by_field_name("arguments") + if f_args: + for c in f_args.children: + if c.type == "argument": + for cc in c.children: + if cc.type in ("string", "encapsed_string"): + f_path = _read_text(cc, src).strip("'\"") + if f_path.startswith("/"): + prefixes.append(f_path) + break + fluent = fluent.child_by_field_name("object") + curr = call.parent continue @@ -4995,7 +5010,7 @@ def _extract_generic( func_name = _read_text(name_node, source) if name_node else None if not func_name: - if t in ("anonymous_function", "arrow_function"): + if config.ts_module == "tree_sitter_php" and t in ("anonymous_function", "arrow_function"): route_name = _php_get_route_name(node, source) if route_name: func_name = route_name