From 713407c54766258fd0865e4f15cbde74d7ecf3a5 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sat, 18 May 2024 14:12:38 +0200 Subject: [PATCH 1/2] Update ComponentModel\Container stub for component-model 3.1.0 That version changes the return type to array when `$deep` argument is `false` (default): https://github.com/nette/component-model/commit/7f613eed7f5e57b6bde2d0be1bfdbb7e161620b3 It also deprecates the arguments but we cannot add deprecated annotation to those. https://github.com/nette/component-model/commit/4e0946a788b4ac42ea903b761c693ec7dd083a69 --- extension.neon | 6 +- src/Stubs/Nette/StubFilesExtensionLoader.php | 52 ++++++++++++++ stubs/ComponentModel/Container_3_1.stub | 21 ++++++ ...ontainerDynamicReturnTypeExtensionTest.php | 72 +++++++++++++++++++ .../Nette/data/componentModelContainer.php | 17 +++++ .../Nette/data/componentModelContainer31.php | 17 +++++ 6 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 src/Stubs/Nette/StubFilesExtensionLoader.php create mode 100644 stubs/ComponentModel/Container_3_1.stub create mode 100644 tests/Type/Nette/ComponentModelContainerDynamicReturnTypeExtensionTest.php create mode 100644 tests/Type/Nette/data/componentModelContainer.php create mode 100644 tests/Type/Nette/data/componentModelContainer31.php diff --git a/extension.neon b/extension.neon index 3f5c7a2..89c9979 100644 --- a/extension.neon +++ b/extension.neon @@ -10,7 +10,6 @@ parameters: - stubs/Application/UI/Presenter.stub - stubs/Caching/Cache.stub - stubs/ComponentModel/Component.stub - - stubs/ComponentModel/Container.stub - stubs/ComponentModel/IComponent.stub - stubs/ComponentModel/IContainer.stub - stubs/Database/ResultSet.stub @@ -147,3 +146,8 @@ services: class: PHPStan\Type\Nette\StringsLengthDynamicReturnTypeExtension tags: - phpstan.broker.dynamicStaticMethodReturnTypeExtension + + - + class: PHPStan\Stubs\Nette\StubFilesExtensionLoader + tags: + - phpstan.stubFilesExtension diff --git a/src/Stubs/Nette/StubFilesExtensionLoader.php b/src/Stubs/Nette/StubFilesExtensionLoader.php new file mode 100644 index 0000000..44c3b98 --- /dev/null +++ b/src/Stubs/Nette/StubFilesExtensionLoader.php @@ -0,0 +1,52 @@ + $filterType + * @phpstan-return ( + * $deep is false + * ? ($filterType is null ? array : array) + * : ($filterType is null ? \Iterator : \Iterator) + * ) + */ + public function getComponents(bool $deep = false, ?string $filterType = null): iterable + { + // nothing + } +} diff --git a/tests/Type/Nette/ComponentModelContainerDynamicReturnTypeExtensionTest.php b/tests/Type/Nette/ComponentModelContainerDynamicReturnTypeExtensionTest.php new file mode 100644 index 0000000..1466086 --- /dev/null +++ b/tests/Type/Nette/ComponentModelContainerDynamicReturnTypeExtensionTest.php @@ -0,0 +1,72 @@ + + */ + public function dataFileAsserts(): iterable + { + yield from self::gatherAssertTypes(__DIR__ . '/data/componentModelContainer' . self::getVersionSuffix() . '.php'); + } + + private static function getVersionSuffix(): string + { + $componentModelVersion = self::getInstalledVersion('nette/component-model'); + + if ($componentModelVersion === null) { + return ''; + } + + if (version_compare($componentModelVersion, '3.1.0', '>=')) { + return '31'; + } + + return ''; + } + + /** + * @dataProvider dataFileAsserts + * @param mixed ...$args + */ + public function testFileAsserts( + string $assertType, + string $file, + ...$args + ): void + { + $this->assertFileAsserts($assertType, $file, ...$args); + } + + public static function getAdditionalConfigFiles(): array + { + return [ + __DIR__ . '/phpstan.neon', + ]; + } + + private static function getInstalledVersion(string $package): ?string + { + if (!class_exists(InstalledVersions::class)) { + return null; + } + + try { + $installedVersion = InstalledVersions::getVersion($package); + } catch (OutOfBoundsException $e) { + return null; + } + + return $installedVersion; + } + +} diff --git a/tests/Type/Nette/data/componentModelContainer.php b/tests/Type/Nette/data/componentModelContainer.php new file mode 100644 index 0000000..f082254 --- /dev/null +++ b/tests/Type/Nette/data/componentModelContainer.php @@ -0,0 +1,17 @@ +', $someForm->getComponents(false)); +assertType('Iterator', $someForm->getComponents(false, Container::class)); +assertType('Iterator', $someForm->getComponents(true)); +assertType('Iterator', $someForm->getComponents(true, Container::class)); diff --git a/tests/Type/Nette/data/componentModelContainer31.php b/tests/Type/Nette/data/componentModelContainer31.php new file mode 100644 index 0000000..de0bf1c --- /dev/null +++ b/tests/Type/Nette/data/componentModelContainer31.php @@ -0,0 +1,17 @@ +', $someForm->getComponents(false)); +assertType('array', $someForm->getComponents(false, Container::class)); +assertType('Iterator', $someForm->getComponents(true)); +assertType('Iterator', $someForm->getComponents(true, Container::class)); From e870b54e93b8effa9ba08115c1ecaeb16a669eb4 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Mon, 13 Jul 2026 11:46:05 +0200 Subject: [PATCH 2/2] Update ComponentModel\Container stub for component-model 4.0.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That version changes the return type of `Container::getComponents` to properly typed array and removes support for extra arguments: https://github.com/nette/component-model/commit/c40aa8ed45324438100a4d931ed1fb8dc16b4f34 Let’s drop the stub on that version. --- src/Stubs/Nette/StubFilesExtensionLoader.php | 2 +- ...ModelContainerDynamicReturnTypeExtensionTest.php | 4 ++++ tests/Type/Nette/data/componentModelContainer40.php | 13 +++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tests/Type/Nette/data/componentModelContainer40.php diff --git a/src/Stubs/Nette/StubFilesExtensionLoader.php b/src/Stubs/Nette/StubFilesExtensionLoader.php index 44c3b98..1c47d27 100644 --- a/src/Stubs/Nette/StubFilesExtensionLoader.php +++ b/src/Stubs/Nette/StubFilesExtensionLoader.php @@ -27,7 +27,7 @@ public function getFiles(): array if (version_compare($componentModelVersion, '3.1.0', '<')) { $files[] = $path . '/ComponentModel/Container.stub'; - } else { + } elseif (version_compare($componentModelVersion, '4.0.0', '<')) { $files[] = $path . '/ComponentModel/Container_3_1.stub'; } diff --git a/tests/Type/Nette/ComponentModelContainerDynamicReturnTypeExtensionTest.php b/tests/Type/Nette/ComponentModelContainerDynamicReturnTypeExtensionTest.php index 1466086..73f25df 100644 --- a/tests/Type/Nette/ComponentModelContainerDynamicReturnTypeExtensionTest.php +++ b/tests/Type/Nette/ComponentModelContainerDynamicReturnTypeExtensionTest.php @@ -27,6 +27,10 @@ private static function getVersionSuffix(): string return ''; } + if (version_compare($componentModelVersion, '4.0.0', '>=')) { + return '40'; + } + if (version_compare($componentModelVersion, '3.1.0', '>=')) { return '31'; } diff --git a/tests/Type/Nette/data/componentModelContainer40.php b/tests/Type/Nette/data/componentModelContainer40.php new file mode 100644 index 0000000..f39b399 --- /dev/null +++ b/tests/Type/Nette/data/componentModelContainer40.php @@ -0,0 +1,13 @@ +', $someForm->getComponents());