fix(php): match correct AST node names and scan nested closures

(cherry picked from commit ceb961a6b3)
This commit is contained in:
nikhil2004 authored and safishamsi committed 2026-09-23 19:42:04 +01:00
1 parent 435f5a88e9
commit 10f144de06
2 files changed
+19 -7

No files matched your search

+2 -2
View File
@@ -1459,7 +1459,7 @@ _PHP_CONFIG = LanguageConfig(
"enum_declaration",
"trait_declaration",
}),
function_types=frozenset({"function_definition", "method_declaration", "anonymous_function_creation_expression", "arrow_function"}),
function_types=frozenset({"function_definition", "method_declaration", "anonymous_function", "arrow_function"}),
import_types=frozenset({"namespace_use_clause"}),
# object_creation_expression joins the dispatch set so `new Foo(...)` links
# the constructing method to Foo (engine has a dedicated PHP branch: the
@@ -1477,7 +1477,7 @@ _PHP_CONFIG = LanguageConfig(
# enums wrap their members in an enum_declaration_list rather than a
# declaration_list, so the body walk needs it to reach enum methods/cases.
body_fallback_child_types=("declaration_list", "compound_statement", "enum_declaration_list"),
function_boundary_types=frozenset({"function_definition", "method_declaration", "anonymous_function_creation_expression", "arrow_function"}),
function_boundary_types=frozenset({"function_definition", "method_declaration", "anonymous_function", "arrow_function"}),
import_handler=_import_php,
)
+17 -5
View File
@@ -3471,7 +3471,7 @@ def _php_get_route_name(closure_node, src: bytes) -> str | None:
if curr.type == "argument":
arg_list = curr.parent
if arg_list is not None and arg_list.type == "argument_list":
if arg_list is not None and arg_list.type == "arguments":
call = arg_list.parent
if call is not None and call.type in ("member_call_expression", "function_call_expression", "scoped_call_expression"):
name_node = call.child_by_field_name("name")
@@ -3484,8 +3484,16 @@ def _php_get_route_name(closure_node, src: bytes) -> str | None:
for sibling in arg_list.children:
if sibling is curr:
break
if sibling.type in ("string", "encapsed_string"):
path_text = _read_text(sibling, src).strip("'\"")
target = sibling
if sibling.type == "argument":
for c in sibling.children:
if c.type in ("string", "encapsed_string"):
target = c
break
if target.type in ("string", "encapsed_string"):
path_text = _read_text(target, src).strip("'\"")
break
if verb is None:
@@ -3503,7 +3511,7 @@ def _php_get_route_name(closure_node, src: bytes) -> str | None:
curr = call.parent
continue
elif curr.type in ("anonymous_function_creation_expression", "arrow_function"):
elif curr.type in ("anonymous_function", "arrow_function"):
# Jump across the closure boundary to its containing argument
curr = curr.parent
continue
@@ -4992,7 +5000,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_creation_expression", "arrow_function"):
if t in ("anonymous_function", "arrow_function"):
route_name = _php_get_route_name(node, source)
if route_name:
func_name = route_name
@@ -5445,6 +5453,10 @@ def _extract_generic(
scope_parents=scope_parents,
lexical_nids_by_scope=lexical_nids_by_scope,
)
if config.ts_module == "tree_sitter_php":
# Manually walk the body to find nested closures, passing the
# body node itself so `walk()` visits its children.
walk(body, parent_class_nid=parent_class_nid)
if config.ts_module == "tree_sitter_kotlin":
# #2347: Kotlin anonymous objects (`object : Foo { … }`,
# node type `object_literal`). The function branch never