From de43cdac623fb8d5406fbb52b288b291c22b68be Mon Sep 17 00:00:00 2001 From: Jorg Sowa Date: Thu, 5 Nov 2026 14:02:20 +0100 Subject: [PATCH] Fix AST printing dropping readonly on promoted parameters --- NEWS | 2 ++ Zend/zend_ast.c | 3 ++ .../compile_to_ast/readonly_promoted.phpt | 28 +++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 ext/zend_test/tests/compile_to_ast/readonly_promoted.phpt diff --git a/NEWS b/NEWS index 6fde7abcbc48..1153d9d40600 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ PHP NEWS . Fixed AST printing of interface extends list as implements. (Jorg Sowa) . Fixed AST printing dropping fully qualified and namespace-relative prefixes of class names in implements, catch, and trait use lists. (Jorg Sowa) + . Fixed AST printing dropping readonly on promoted constructor parameters. + (Jorg Sowa) - Curl: . Fixed curl_reset() retaining CURLOPT_PRIVATE after reset. (lacatoire) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index dc40c15fc45e..14327ac77f33 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -2609,6 +2609,9 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio zend_ast_export_attributes(str, ast->child[3], indent, 0); } zend_ast_export_visibility(str, ast->attr, ZEND_MODIFIER_TARGET_CPP); + if (ast->attr & ZEND_ACC_READONLY) { + smart_str_appends(str, "readonly "); + } if (ast->child[0]) { zend_ast_export_type(str, ast->child[0], indent); smart_str_appendc(str, ' '); diff --git a/ext/zend_test/tests/compile_to_ast/readonly_promoted.phpt b/ext/zend_test/tests/compile_to_ast/readonly_promoted.phpt new file mode 100644 index 000000000000..c038ce47d21a --- /dev/null +++ b/ext/zend_test/tests/compile_to_ast/readonly_promoted.phpt @@ -0,0 +1,28 @@ +--TEST-- +AST can be recreated (readonly promoted constructor parameters) +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +class Foo { + public function __construct(public readonly int $publicReadonly, readonly int $implicitlyPublicReadonly, protected private(set) readonly array $asymmetricReadonly = [], #[Attr] private readonly ?string $attributedReadonly = null, public int $notReadonly = 1) { + } + +} + +echo zend_test_compile_to_ast(file_get_contents(__FILE__));