From 2c2c6d9ddb4366f56f4f6dd531a514f3e106bac6 Mon Sep 17 00:00:00 2001 From: Timm Friebe Date: Tue, 27 Aug 2024 22:18:53 +0200 Subject: [PATCH] Emit readonly classes natively in PHP 8.3 --- src/main/php/lang/ast/emit/PHP83.class.php | 2 +- src/main/php/lang/ast/emit/ReadonlyClasses.class.php | 6 ++++-- src/test/php/lang/ast/unittest/emit/ReadonlyTest.class.php | 7 ++++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/php/lang/ast/emit/PHP83.class.php b/src/main/php/lang/ast/emit/PHP83.class.php index f33ef341..7c7293b2 100755 --- a/src/main/php/lang/ast/emit/PHP83.class.php +++ b/src/main/php/lang/ast/emit/PHP83.class.php @@ -18,7 +18,7 @@ * @see https://wiki.php.net/rfc#php_83 */ class PHP83 extends PHP { - use RewriteBlockLambdaExpressions, RewriteProperties, ReadonlyClasses; + use RewriteBlockLambdaExpressions, RewriteProperties; public $targetVersion= 80300; diff --git a/src/main/php/lang/ast/emit/ReadonlyClasses.class.php b/src/main/php/lang/ast/emit/ReadonlyClasses.class.php index e24d11ab..073f30cc 100755 --- a/src/main/php/lang/ast/emit/ReadonlyClasses.class.php +++ b/src/main/php/lang/ast/emit/ReadonlyClasses.class.php @@ -33,9 +33,11 @@ protected function emitClass($result, $class) { } // Prevent dynamic members - $throw= new Code('throw new \\Error("Cannot create dynamic property ".__CLASS__."::".$name);'); $context= $result->codegen->enter(new InType($class)); - $context->virtual[null]= [$throw, $throw]; + $context->virtual[null]= [ + new Code(''), + new Code('throw new \\Error("Cannot create dynamic property ".__CLASS__."::".$name);') + ]; } return parent::emitClass($result, $class); diff --git a/src/test/php/lang/ast/unittest/emit/ReadonlyTest.class.php b/src/test/php/lang/ast/unittest/emit/ReadonlyTest.class.php index c65e4a66..1ee2ffb8 100755 --- a/src/test/php/lang/ast/unittest/emit/ReadonlyTest.class.php +++ b/src/test/php/lang/ast/unittest/emit/ReadonlyTest.class.php @@ -174,10 +174,11 @@ public function cannot_have_an_initial_value() { }'); } - #[Test, Expect(class: Error::class, message: '/Cannot create dynamic property .+fixture/')] - public function cannot_read_dynamic_members_from_readonly_classes() { + #[Test] + public function reading_dynamic_members_from_readonly_classes_causes_warning() { $t= $this->declare('readonly class %T { }'); - $t->newInstance()->fixture; + Assert::null($t->newInstance()->fixture); + \xp::gc(); } #[Test, Expect(class: Error::class, message: '/Cannot create dynamic property .+fixture/')]