fix dynamic static calls on object targets (#87)

master
yavon007 1 month ago committed by GitHub
parent b356636853
commit cbd100f906
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 7
      phpunit/code/call-cache-sites.php
  2. 4
      phpunit/src/CallCacheCodegenTest.php
  3. 5
      src/Parser/MethodCallTrait.php
  4. 34
      tests/compiler/static/static-call-dynamic-object-method.phpt

@ -38,6 +38,13 @@ function call_cache_static_sites(mixed $class, mixed $method): array
];
}
function call_cache_stable_object_static_method(mixed $method): int
{
$object = new CallCacheStaticTarget();
return $object::$method(8);
}
class CallCacheScopedTarget
{
private function hidden(): int

@ -26,9 +26,9 @@ final class CallCacheCodegenTest extends BaseTest
self::assertIsString($code);
self::assertIsString($extension);
self::assertSame(1, substr_count($code, 'typephp_call_cached('));
self::assertSame(3, substr_count($code, 'php::callStaticMethod('));
self::assertSame(4, substr_count($code, 'php::callStaticMethod('));
self::assertStringNotContainsString('php::concat({', $code);
self::assertSame(8, substr_count($code, 'php::VarList{'));
self::assertSame(9, substr_count($code, 'php::VarList{'));
self::assertStringNotContainsString('std::array<php::Variant', $code);
self::assertStringNotContainsString('php::ArgList{', $code);
self::assertSame(2, substr_count($code, 'typephp_call_method_cached('));

@ -1099,7 +1099,10 @@ trait MethodCallTrait
}
if (!$this->isNameExpr($expr->class)) {
if ($this->isVarExpr($expr->class) && $this->isStableObject($class)) {
if ($this->isVarExpr($expr->class)
&& $this->isStableObject($class)
&& $this->isIdExpr($expr->name)
) {
$class = $this->getObjectType($class);
goto _do_call;
}

@ -0,0 +1,34 @@
--TEST--
Dynamic static method name on object target uses the runtime method value
--FILE--
<?php
class DynamicObjectStaticTarget
{
public static function reward(string $value): string
{
return 'base:' . $value;
}
}
class DynamicObjectStaticChild extends DynamicObjectStaticTarget
{
public static function reward(string $value): string
{
return 'child:' . $value;
}
}
function main(): void
{
$method = 'reward';
$target = new DynamicObjectStaticTarget();
$child = new DynamicObjectStaticChild();
var_dump($target::$method('first'));
var_dump($child::$method(value: 'second'));
}
?>
--EXPECT--
string(10) "base:first"
string(12) "child:second"
Loading…
Cancel
Save