From 4de827f55f54059dc5618260f4dbb6f0d8088252 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Sun, 18 Feb 2024 00:12:50 +0800 Subject: [PATCH] Add support for readonly constructor properties --- file.php | 8 +++ ...onstructor_property_promotion_readonly.php | 50 +++++++++++++++++++ tests/moodlecheck_rules_test.php | 27 ++++++++++ 3 files changed, 85 insertions(+) create mode 100644 tests/fixtures/phpdoc_constructor_property_promotion_readonly.php diff --git a/file.php b/file.php index 26e214c..e3c07ee 100644 --- a/file.php +++ b/file.php @@ -423,8 +423,16 @@ public function &get_functions() { $argtokens = array_values($argtokens); for ($j = 0; $j < count($argtokens); $j++) { + if (version_compare(PHP_VERSION, '8.1.0') >= 0) { + // T_READONLY introduced in PHP 8.1. + if ($argtokens[$j][0] === T_READONLY) { + continue; + } + } switch ($argtokens[$j][0]) { // Skip any whitespace, or argument visibility. + case T_COMMENT: + case T_DOC_COMMENT: case T_WHITESPACE: case T_PUBLIC: case T_PROTECTED: diff --git a/tests/fixtures/phpdoc_constructor_property_promotion_readonly.php b/tests/fixtures/phpdoc_constructor_property_promotion_readonly.php new file mode 100644 index 0000000..252e70e --- /dev/null +++ b/tests/fixtures/phpdoc_constructor_property_promotion_readonly.php @@ -0,0 +1,50 @@ +. + +namespace local_moodlecheck; + +use cm_info; +use stdClass; + +/** + * A fixture to verify phpdoc tags used in constructor property promotion. + * + * @package local_moodlecheck + * @copyright 2023 Andrew Lyons + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class constructor_property_promotion { + /** + * An example of a constructor using constructor property promotion. + * + * @param stdClass|cm_info $cm The course module data + * @param string $name The name + * @param int|float $size The size + * @param null|string $description The description + * @param ?string $content The content + */ + public function __construct( + private stdClass|cm_info $cm, + /** @var string The name of the course module */ + public readonly string $name, + /** @var float|int The size */ + public readonly float|int $size, + /** @var null|string The description */ + protected readonly ?string $description = null, + protected ?string $content = null + ) { + } +} diff --git a/tests/moodlecheck_rules_test.php b/tests/moodlecheck_rules_test.php index eaf9253..9c68f5f 100644 --- a/tests/moodlecheck_rules_test.php +++ b/tests/moodlecheck_rules_test.php @@ -219,6 +219,33 @@ public function test_phpdoc_constructor_property_promotion(): void { $this->assertStringNotContainsString('constructor_property_promotion::__construct has incomplete parameters list', $result); } + /** + * Verify that constructor property promotion supports readonly properties. + * + * @covers ::local_moodlecheck_functionarguments + * @requires PHP >= 8.1 + */ + public function test_phpdoc_constructor_property_promotion_readonly(): void { + global $PAGE; + $output = $PAGE->get_renderer('local_moodlecheck'); + $path = new local_moodlecheck_path( + 'local/moodlecheck/tests/fixtures/phpdoc_constructor_property_promotion_readonly.php', + null + ); + $result = $output->display_path($path, 'xml'); + + // Convert results to XML Objext. + $xmlresult = new \DOMDocument(); + $xmlresult->loadXML($result); + + // Let's verify we have received a xml with file top element and 8 children. + $xpath = new \DOMXpath($xmlresult); + $found = $xpath->query("//file/error"); + + $this->assertCount(0, $found); + $this->assertStringNotContainsString('constructor_property_promotion::__construct has incomplete parameters list', $result); + } + /** * Verify that constructor property promotion is supported. *