Files
graphify/tests/fixtures/sample.php
T
Synvoya 51f805e953 fix(php): emit type references for promoted constructor properties
PHP 8 constructor property promotion (`__construct(private Repo $repo)`)
parses the promoted parameter as `property_promotion_parameter`, not
`simple_parameter`. The PHP parameter loop filtered on `simple_parameter`
only, so promoted params were skipped entirely: their type emitted no
`parameter_type` edge on the constructor, and — because a promoted param
is also a real class field — no `field` edge on the class either. A
non-promoted param in the same signature still emitted `parameter_type`,
so the type reference was silently dropped for exactly the promoted case.

The promoted param's type sits in the same direct named-child shape the
loop already reads for `simple_parameter`, so widening the filter to
accept `property_promotion_parameter` makes the existing type extraction
emit the `parameter_type` edge. Additionally, for a promoted param, emit
a `field`-context references edge on the class (mirroring the
`property_declaration` handler), guarded so it only fires when a parent
class is in scope and the target is not the class node itself. Normal
`simple_parameter` behaviour is unchanged.

Adds a promoted-property constructor to tests/fixtures/sample.php and
test_php_constructor_property_promotion_contexts asserting the promoted
type appears as both `field` and `parameter_type`, and that a
non-promoted param does not leak a field edge.
2026-07-01 16:36:49 +01:00

80 lines
1.3 KiB
PHP

<?php
namespace App\Http;
use App\Auth\Authenticator;
use App\Cache\CacheManager;
class ApiClient
{
private string $baseUrl;
private Authenticator $auth;
public function __construct(string $baseUrl)
{
$this->baseUrl = $baseUrl;
$this->auth = new Authenticator();
}
public function get(string $path): string
{
return $this->fetch($path, 'GET');
}
public function post(string $path, string $body): string
{
return $this->fetch($path, 'POST');
}
private function fetch(string $path, string $method): string
{
$token = $this->auth->getToken();
return $method . ' ' . $this->baseUrl . $path;
}
}
interface Loggable
{
public function log(): void;
}
trait HasName
{
public function getName(): string
{
return '';
}
}
class BaseProcessor {}
class Result {}
class DataProcessor extends BaseProcessor implements Loggable
{
use HasName;
private Result $current;
public function run(DataProcessor $input): Result
{
return new Result();
}
public function log(): void
{
}
}
class Service
{
public function __construct(private Result $result, string $label)
{
}
}
function parseResponse(string $raw): array
{
return json_decode($raw, true);
}