From f3a662cf3cbfba0e659a5962554951dee698e76b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Thu, 22 Jul 2021 09:22:53 +0200 Subject: [PATCH 1/3] Add support for generating readonly properties via stubs --- build/gen_stub.php | 6 +++++- ext/zend_test/test.stub.php | 1 + ext/zend_test/test_arginfo.h | 8 +++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/build/gen_stub.php b/build/gen_stub.php index dbb7cccf5ae1e..cfc27ebe749f3 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -1178,6 +1178,10 @@ private function getFlagsAsString(): string $flags .= "|ZEND_ACC_STATIC"; } + if ($this->flags & Class_::MODIFIER_READONLY) { + $flags .= "|ZEND_ACC_READONLY"; + } + return $flags; } } @@ -2303,7 +2307,7 @@ function initPhpParser() { } $isInitialized = true; - $version = "4.9.0"; + $version = "4.12.0"; $phpParserDir = __DIR__ . "/PHP-Parser-$version"; if (!is_dir($phpParserDir)) { installPhpParser($version, $phpParserDir); diff --git a/ext/zend_test/test.stub.php b/ext/zend_test/test.stub.php index 2c2aabc2b818c..105f3e7e9dce9 100644 --- a/ext/zend_test/test.stub.php +++ b/ext/zend_test/test.stub.php @@ -17,6 +17,7 @@ class _ZendTestClass implements _ZendTestInterface { public int $intProp = 123; public ?stdClass $classProp = null; public stdClass|Iterator|null $classUnionProp = null; + public readonly int $readonlyProp; public static function is_object(): int {} diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h index c0642e842a18c..9d636bafc871f 100644 --- a/ext/zend_test/test_arginfo.h +++ b/ext/zend_test/test_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 6efccee97845bb4176d25226cadaedbfc6de961d */ + * Stub hash: 2a1f8ff8205507259ba19bd379a07b390bc525cd */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -227,6 +227,12 @@ static zend_class_entry *register_class__ZendTestClass(zend_class_entry *class_e zend_declare_typed_property(class_entry, property_classUnionProp_name, &property_classUnionProp_default_value, ZEND_ACC_PUBLIC, NULL, property_classUnionProp_type); zend_string_release(property_classUnionProp_name); + zval property_readonlyProp_default_value; + ZVAL_UNDEF(&property_readonlyProp_default_value); + zend_string *property_readonlyProp_name = zend_string_init("readonlyProp", sizeof("readonlyProp") - 1, 1); + zend_declare_typed_property(class_entry, property_readonlyProp_name, &property_readonlyProp_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(property_readonlyProp_name); + return class_entry; } From 87306201ef369a08b0a3710942e5fd80cadd4ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Thu, 22 Jul 2021 10:35:58 +0200 Subject: [PATCH 2/3] Use emulative lexer on PHP <8.1 --- Zend/tests/type_declarations/typed_properties_095.phpt | 4 ++++ build/gen_stub.php | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Zend/tests/type_declarations/typed_properties_095.phpt b/Zend/tests/type_declarations/typed_properties_095.phpt index 434fd46750641..a03bcf9555276 100644 --- a/Zend/tests/type_declarations/typed_properties_095.phpt +++ b/Zend/tests/type_declarations/typed_properties_095.phpt @@ -70,6 +70,8 @@ object(_ZendTestClass)#1 (3) { } ["classUnionProp"]=> NULL + ["readonlyProp"]=> + uninitialized(int) } int(123) Cannot assign string to property _ZendTestClass::$intProp of type int @@ -82,6 +84,8 @@ object(Test)#4 (3) { } ["classUnionProp"]=> NULL + ["readonlyProp"]=> + uninitialized(int) } int(123) Cannot assign string to property _ZendTestClass::$staticIntProp of type int diff --git a/build/gen_stub.php b/build/gen_stub.php index cfc27ebe749f3..7502fad4ed1d0 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -1810,7 +1810,9 @@ function handleStatements(FileInfo $fileInfo, array $stmts, PrettyPrinterAbstrac } function parseStubFile(string $code): FileInfo { - $lexer = new PhpParser\Lexer(); + $minCompatiblePhpVersionId = 80100; // PHP 8.1 + + $lexer = PHP_VERSION_ID >= $minCompatiblePhpVersionId ? new PhpParser\Lexer() : new PhpParser\Lexer\Emulative(); $parser = new PhpParser\Parser\Php7($lexer); $nodeTraverser = new PhpParser\NodeTraverser; $nodeTraverser->addVisitor(new PhpParser\NodeVisitor\NameResolver); From 999d02a57cb3e88aa070982c46ba077485f478a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Thu, 22 Jul 2021 10:47:02 +0200 Subject: [PATCH 3/3] Always use the emulative lexer --- build/gen_stub.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build/gen_stub.php b/build/gen_stub.php index 7502fad4ed1d0..efac19fe4233b 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -1810,9 +1810,7 @@ function handleStatements(FileInfo $fileInfo, array $stmts, PrettyPrinterAbstrac } function parseStubFile(string $code): FileInfo { - $minCompatiblePhpVersionId = 80100; // PHP 8.1 - - $lexer = PHP_VERSION_ID >= $minCompatiblePhpVersionId ? new PhpParser\Lexer() : new PhpParser\Lexer\Emulative(); + $lexer = new PhpParser\Lexer\Emulative(); $parser = new PhpParser\Parser\Php7($lexer); $nodeTraverser = new PhpParser\NodeTraverser; $nodeTraverser->addVisitor(new PhpParser\NodeVisitor\NameResolver);