diff --git a/phpunit/code/native-property-full-name.php b/phpunit/code/native-property-full-name.php index af197a4a..e954ccbb 100644 --- a/phpunit/code/native-property-full-name.php +++ b/phpunit/code/native-property-full-name.php @@ -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()); } } diff --git a/phpunit/src/NativePropertyTest.php b/phpunit/src/NativePropertyTest.php index 6f32781e..b01b6b80 100644 --- a/phpunit/src/NativePropertyTest.php +++ b/phpunit/src/NativePropertyTest.php @@ -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'); diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 8755a759..3257b200 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.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) . ')'; } diff --git a/tests/aot/static/static-prop-late-static-binding.phpt b/tests/aot/static/static-prop-late-static-binding.phpt new file mode 100644 index 00000000..573bdfa3 --- /dev/null +++ b/tests/aot/static/static-prop-late-static-binding.phpt @@ -0,0 +1,39 @@ +--TEST-- +Static native properties use late static binding for static::$prop +--FILE-- + +--EXPECT-- +int(1) +int(2) +int(1) +int(9) +int(9)