fix(php): 修复静态属性晚绑定支持问题

- 修改 CompilerBase.php 中的静态属性处理逻辑,正确区分 self 和 static 关键字
- 为 native-property-full-name.php 添加 writeStatic 测试方法
- 更新 NativePropertyTest.php 中的编译方法返回值类型和测试用例
- 添加静态属性晚绑定功能的完整测试用例 static-prop-late-static-binding.phpt
pull/2/head
韩天峰 2 months ago
parent 91675ed366
commit cce6967acf
  1. 7
      phpunit/code/native-property-full-name.php
  2. 16
      phpunit/src/NativePropertyTest.php
  3. 5
      src/Php/CompilerBase.php
  4. 39
      tests/aot/static/static-prop-late-static-binding.phpt

@ -37,6 +37,12 @@ namespace NativePropSource\Target {
return static::$count;
}
public static function writeStatic(int $value): int
{
static::$count = $value;
return static::$count;
}
public static function readParent(): int
{
return parent::$count;
@ -64,6 +70,7 @@ namespace {
var_dump(\NativePropSource\Target\readStaticByUse());
var_dump(\NativePropSource\Target\Child::readSelf());
var_dump(\NativePropSource\Target\Child::readStatic());
var_dump(\NativePropSource\Target\Child::writeStatic(4));
var_dump(\NativePropSource\Target\Child::readParent());
}
}

@ -5,7 +5,7 @@ use PhpAot\Php\Exception\TestError;
class NativePropertyTest extends \BaseTest
{
private function compile(string $file): void
private function compile(string $file): string
{
global $translator;
@ -17,6 +17,7 @@ class NativePropertyTest extends \BaseTest
$compiler->convertFile($testFile);
$this->addToAssertionCount(1);
return ROOT_PATH . '/build/phpunit/code/' . basename($file, '.php') . '.cc';
}
public function testFindNativePropertyUsesFullClassNameAcrossBranches(): void
@ -28,6 +29,19 @@ class NativePropertyTest extends \BaseTest
}
}
public function testStaticStaticPropertyUsesDynamicCalledClassPath(): void
{
try {
$outputFile = $this->compile('native-property-full-name.php');
} catch (TestError $e) {
$this->fail($e->getMessage());
}
$code = file_get_contents($outputFile);
$this->assertStringContainsString('php::getStaticProperty(php_get_called_class(this_), "count")', $code);
$this->assertStringContainsString('php::getStaticProperty(php_get_called_class(this_), "count") = php::toInt(value)', $code);
}
public function testCannotAccessPrivateNativePropertyFromUnrelatedClass(): void
{
$this->exec('Cannot access private property `value` of class `NativePrivateOwner`', 'native-property-private-other-class.php');

@ -4723,7 +4723,10 @@ class CompilerBase extends \PhpAot\Core\Translator
if ($this->isNameExpr($expr->class) and $this->isIdExpr($expr->name)) {
$class = $this->parseIdentifier($expr->class);
$propertyName = $this->parseIdentifier($expr->name);
if ($class === 'self' || $class === 'static') {
if ($class === 'static') {
return null;
}
if ($class === 'self') {
if ($this->classDef->trait) {
return Symbol::getStaticProperty() . '(' . Symbol::getCalledCe() . ', ' . $this->getLiteralString($propertyName) . ')';
}

@ -0,0 +1,39 @@
--TEST--
Static native properties use late static binding for static::$prop
--FILE--
<?php
use native_types;
class StaticPropBase {
public static int $v = 1;
public static function get(): int {
return static::$v;
}
public static function set(int $v): void {
static::$v = $v;
}
}
class StaticPropChild extends StaticPropBase {
public static int $v = 2;
}
function main(): void {
var_dump(StaticPropBase::get());
var_dump(StaticPropChild::get());
StaticPropChild::set(9);
var_dump(StaticPropBase::$v);
var_dump(StaticPropChild::$v);
var_dump(StaticPropChild::get());
}
?>
--EXPECT--
int(1)
int(2)
int(1)
int(9)
int(9)
Loading…
Cancel
Save