Summary
A class that a PHP method only instantiates gets no edge. new Foo(...) parses as
object_creation_expression, but _PHP_CONFIG.call_types does not list that node type,
so the construction site is never dispatched in walk_calls.
This is the same gap that #2997 reported for C#, fixed in #2998 by adding
object_creation_expression to the C# config. Java has had it since #1373. PHP never caught up.
Repro (graphify 0.9.50, tree_sitter_php 0.24.1)
Four files, graphify extract . --code-only:
// src/Foo.php, src/Bar.php, src/Baz.php (namespace App)
class Foo { public function __construct(public int $x = 0) {} }
class Bar { public function __construct(public int $y = 0) {} }
class Baz { public static function create(): self { return new self(); } }
// src/Caller.php
class Caller
{
public function run(Bus $bus): void
{
$a = new Foo(1); // new in assignment
$bus->dispatch(new Bar(2)); // new as argument
$c = Baz::create(); // static call
}
}
| position |
edge emitted |
new Foo(1) in assignment |
none |
new Bar(2) as argument |
none |
Baz::create() |
run --calls--> Baz |
Only the static call produces an edge. Neither new site produces calls, references,
or any other relation — the classes exist as nodes, they are simply unreachable from the
constructing method.
Root cause
graphify/extract.py, _PHP_CONFIG:
call_types=frozenset({"function_call_expression", "member_call_expression",
"scoped_call_expression", "class_constant_access_expression"}),
object_creation_expression is absent. Confirmed against the grammar:
object_creation_expression -> new Foo(1)
object_creation_expression -> new Bar(2)
Impact on a real codebase
Symfony/DDD application, 615 PHP files, 4324 nodes / 10957 edges:
505 new X( sites across 178 distinct classes emit no edge.
The practical effect is worst on message-bus code, where construction is the control flow.
Of 22 $bus->dispatch(new SomeCommand(...)) sites, 0/22 have a calls/references edge
to the command they construct. Asking the graph "what happens when
AttachRecordToMessageEmailCommand is dispatched" returns the handler's neighbourhood
(repositories, value objects, unrelated domain events) but never the one command it chains to
— and there is no signal that the edge set is incomplete.
Related
#1682 covers instance/member call resolution in PHP ($this->prop->method()), which has a
different root cause (member calls are deliberately dropped to avoid false positives). This
report is only about the construction site itself, where the callee type is written literally
at the call site and needs no inference.
Summary
A class that a PHP method only instantiates gets no edge.
new Foo(...)parses asobject_creation_expression, but_PHP_CONFIG.call_typesdoes not list that node type,so the construction site is never dispatched in
walk_calls.This is the same gap that #2997 reported for C#, fixed in #2998 by adding
object_creation_expressionto the C# config. Java has had it since #1373. PHP never caught up.Repro (graphify 0.9.50, tree_sitter_php 0.24.1)
Four files,
graphify extract . --code-only:new Foo(1)in assignmentnew Bar(2)as argumentBaz::create()run --calls--> BazOnly the static call produces an edge. Neither
newsite producescalls,references,or any other relation — the classes exist as nodes, they are simply unreachable from the
constructing method.
Root cause
graphify/extract.py,_PHP_CONFIG:object_creation_expressionis absent. Confirmed against the grammar:Impact on a real codebase
Symfony/DDD application, 615 PHP files, 4324 nodes / 10957 edges:
505
new X(sites across 178 distinct classes emit no edge.The practical effect is worst on message-bus code, where construction is the control flow.
Of 22
$bus->dispatch(new SomeCommand(...))sites, 0/22 have acalls/referencesedgeto the command they construct. Asking the graph "what happens when
AttachRecordToMessageEmailCommandis dispatched" returns the handler's neighbourhood(repositories, value objects, unrelated domain events) but never the one command it chains to
— and there is no signal that the edge set is incomplete.
Related
#1682 covers instance/member call resolution in PHP (
$this->prop->method()), which has adifferent root cause (member calls are deliberately dropped to avoid false positives). This
report is only about the construction site itself, where the callee type is written literally
at the call site and needs no inference.