diff --git a/composer.json b/composer.json index 78fdfce6..164ac817 100644 --- a/composer.json +++ b/composer.json @@ -44,7 +44,7 @@ "phpbench/phpbench": "^1.2.7", "phpunit/phpunit": "^9.5.26", "psalm/plugin-phpunit": "^0.18.0", - "vimeo/psalm": "^4.29" + "vimeo/psalm": "^5.0" }, "suggest": { "laminas/laminas-eventmanager": "^3.2, to support aggregate hydrator usage", diff --git a/composer.lock b/composer.lock index 0ae0b8bc..1f8264a6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f3a63e600f101f092eeed47a2bdfa478", + "content-hash": "4cdb764ae345b6c4c869d55291fb6824", "packages": [ { "name": "laminas/laminas-stdlib", @@ -5098,24 +5098,24 @@ }, { "name": "vimeo/psalm", - "version": "4.30.0", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/vimeo/psalm.git", - "reference": "d0bc6e25d89f649e4f36a534f330f8bb4643dd69" + "reference": "4e177bf0c9f03c17d2fbfd83b7cc9c47605274d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/d0bc6e25d89f649e4f36a534f330f8bb4643dd69", - "reference": "d0bc6e25d89f649e4f36a534f330f8bb4643dd69", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/4e177bf0c9f03c17d2fbfd83b7cc9c47605274d8", + "reference": "4e177bf0c9f03c17d2fbfd83b7cc9c47605274d8", "shasum": "" }, "require": { "amphp/amp": "^2.4.2", "amphp/byte-stream": "^1.5", - "composer/package-versions-deprecated": "^1.8.0", + "composer/package-versions-deprecated": "^1.10.0", "composer/semver": "^1.4 || ^2.0 || ^3.0", - "composer/xdebug-handler": "^1.1 || ^2.0 || ^3.0", + "composer/xdebug-handler": "^2.0 || ^3.0", "dnoegel/php-xdg-base-dir": "^0.1.1", "ext-ctype": "*", "ext-dom": "*", @@ -5124,35 +5124,34 @@ "ext-mbstring": "*", "ext-simplexml": "*", "ext-tokenizer": "*", - "felixfbecker/advanced-json-rpc": "^3.0.3", - "felixfbecker/language-server-protocol": "^1.5", + "felixfbecker/advanced-json-rpc": "^3.1", + "felixfbecker/language-server-protocol": "^1.5.2", "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", "nikic/php-parser": "^4.13", "openlss/lib-array2xml": "^1.0", - "php": "^7.1|^8", - "sebastian/diff": "^3.0 || ^4.0", - "symfony/console": "^3.4.17 || ^4.1.6 || ^5.0 || ^6.0", - "symfony/polyfill-php80": "^1.25", - "webmozart/path-util": "^2.3" + "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0", + "sebastian/diff": "^4.0", + "symfony/console": "^4.1.6 || ^5.0 || ^6.0", + "symfony/filesystem": "^5.4 || ^6.0", + "symfony/polyfill-php80": "^1.25" }, "provide": { "psalm/psalm": "self.version" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.2", - "brianium/paratest": "^4.0||^6.0", + "bamarni/composer-bin-plugin": "^1.4", + "brianium/paratest": "^6.0", "ext-curl": "*", + "mockery/mockery": "^1.5", + "nunomaduro/mock-final-classes": "^1.1", "php-parallel-lint/php-parallel-lint": "^1.2", - "phpdocumentor/reflection-docblock": "^5", - "phpmyadmin/sql-parser": "5.1.0||dev-master", - "phpspec/prophecy": ">=1.9.0", - "phpstan/phpdoc-parser": "1.2.* || 1.6.4", - "phpunit/phpunit": "^9.0", - "psalm/plugin-phpunit": "^0.16", - "slevomat/coding-standard": "^7.0", - "squizlabs/php_codesniffer": "^3.5", - "symfony/process": "^4.3 || ^5.0 || ^6.0", - "weirdan/prophecy-shim": "^1.0 || ^2.0" + "phpstan/phpdoc-parser": "^1.6", + "phpunit/phpunit": "^9.5", + "psalm/plugin-mockery": "^1.1", + "psalm/plugin-phpunit": "^0.18", + "slevomat/coding-standard": "^8.4", + "squizlabs/php_codesniffer": "^3.6", + "symfony/process": "^4.4 || ^5.0 || ^6.0" }, "suggest": { "ext-curl": "In order to send data to shepherd", @@ -5168,17 +5167,14 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.x-dev", + "dev-master": "5.x-dev", + "dev-4.x": "4.x-dev", "dev-3.x": "3.x-dev", "dev-2.x": "2.x-dev", "dev-1.x": "1.x-dev" } }, "autoload": { - "files": [ - "src/functions.php", - "src/spl_object_id.php" - ], "psr-4": { "Psalm\\": "src/Psalm/" } @@ -5200,9 +5196,9 @@ ], "support": { "issues": "https://github.com/vimeo/psalm/issues", - "source": "https://github.com/vimeo/psalm/tree/4.30.0" + "source": "https://github.com/vimeo/psalm/tree/5.0.0" }, - "time": "2022-11-06T20:37:08+00:00" + "time": "2022-11-30T06:06:01+00:00" }, { "name": "webimpress/coding-standard", @@ -5366,57 +5362,6 @@ "source": "https://github.com/webmozarts/glob/tree/4.6.0" }, "time": "2022-05-24T19:45:58+00:00" - }, - { - "name": "webmozart/path-util", - "version": "2.3.0", - "source": { - "type": "git", - "url": "https://github.com/webmozart/path-util.git", - "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725", - "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "webmozart/assert": "~1.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\PathUtil\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", - "support": { - "issues": "https://github.com/webmozart/path-util/issues", - "source": "https://github.com/webmozart/path-util/tree/2.3.0" - }, - "abandoned": "symfony/filesystem", - "time": "2015-12-17T08:42:14+00:00" } ], "aliases": [], diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 27057490..4650c0d8 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,5 +1,5 @@ - + null === $this->eventManager @@ -39,7 +39,8 @@ array - + + $data $data @@ -112,12 +113,9 @@ - - $currentValue - - - $currentValue - + + $data + new $prototype() @@ -198,6 +196,9 @@ $value $value + + $properties = &self::$skippedPropertiesCache[$object::class] + @@ -232,18 +233,11 @@ $this->enumClass::from($value) - - $enumClass - - + $this->enumClass - - $value->value - T - class-string<T> string - + @@ -386,6 +380,10 @@ + + HydratorAwareTrait::class + HydratorAwareTrait::class + getHydrator getHydrator @@ -436,6 +434,9 @@ $property + + + $attributes['entities'] @@ -475,6 +476,16 @@ $property + + + 'not a real class' + + + + + 'not a real class' + + new CamelCaseToUnderscoreFilter() @@ -584,13 +595,11 @@ - - false - - + 5 + false true - + diff --git a/src/HydratorPluginManagerFactory.php b/src/HydratorPluginManagerFactory.php index d08fb243..01c81af7 100644 --- a/src/HydratorPluginManagerFactory.php +++ b/src/HydratorPluginManagerFactory.php @@ -45,7 +45,7 @@ public function __invoke(ContainerInterface $container, string $name, ?array $op )); } - $pluginManager = new HydratorPluginManager($container, $options ?: []); + $pluginManager = new HydratorPluginManager($container, $options ?? []); // If this is in a laminas-mvc application, the ServiceListener will inject // merged configuration during bootstrap. diff --git a/src/Iterator/HydratingArrayIterator.php b/src/Iterator/HydratingArrayIterator.php index 9097df14..f433fdc4 100644 --- a/src/Iterator/HydratingArrayIterator.php +++ b/src/Iterator/HydratingArrayIterator.php @@ -7,11 +7,18 @@ use ArrayIterator; use Laminas\Hydrator\HydratorInterface; +/** + * @template TKey of array-key + * @template TPrototype of object + * @template TInputData of array + * @template TIterator of ArrayIterator + * @template-extends HydratingIteratorIterator + */ class HydratingArrayIterator extends HydratingIteratorIterator { /** - * @param mixed[] $data Data being used to hydrate the $prototype - * @param string|object $prototype Object, or class name to use for prototype. + * @param array $data Data being used to hydrate the $prototype + * @param class-string|TPrototype $prototype */ public function __construct(HydratorInterface $hydrator, array $data, $prototype) { diff --git a/src/Iterator/HydratingIteratorInterface.php b/src/Iterator/HydratingIteratorInterface.php index d5bc226d..f0745056 100644 --- a/src/Iterator/HydratingIteratorInterface.php +++ b/src/Iterator/HydratingIteratorInterface.php @@ -7,6 +7,11 @@ use Iterator; use Laminas\Hydrator\HydratorInterface; +/** + * @template TKey + * @template TPrototype of object + * @template-extends Iterator + */ interface HydratingIteratorInterface extends Iterator { /** @@ -15,7 +20,7 @@ interface HydratingIteratorInterface extends Iterator * This prototype can be the name of the class or the object itself; * iteration will clone the object. * - * @param string|object $prototype + * @param class-string|TPrototype $prototype */ public function setPrototype($prototype): void; diff --git a/src/Iterator/HydratingIteratorIterator.php b/src/Iterator/HydratingIteratorIterator.php index a0f9e9fa..30e7e051 100644 --- a/src/Iterator/HydratingIteratorIterator.php +++ b/src/Iterator/HydratingIteratorIterator.php @@ -14,16 +14,25 @@ use function is_object; use function sprintf; +/** + * @template TKey + * @template TPrototype of object + * @template TInputData of array + * @template TIterator of Iterator + * @template-extends IteratorIterator + * @template-implements HydratingIteratorInterface + */ class HydratingIteratorIterator extends IteratorIterator implements HydratingIteratorInterface { /** @var HydratorInterface */ protected $hydrator; - /** @var object */ + /** @var TPrototype */ protected $prototype; /** - * @param string|object $prototype Object or class name to use for prototype. + * @param Iterator $data + * @param class-string|TPrototype $prototype */ public function __construct(HydratorInterface $hydrator, Iterator $data, $prototype) { @@ -62,7 +71,9 @@ public function setHydrator(HydratorInterface $hydrator): void } /** - * @return object Returns hydrated clone of $prototype + * @psalm-suppress ImplementedReturnTypeMismatch we are explicitly replacing the type of {@see parent::current()} + * with a hydrated value here, breaking LSP by design. + * @return TPrototype|null */ #[ReturnTypeWillChange] public function current() diff --git a/test/HydratorAwareTraitTest.php b/test/HydratorAwareTraitTest.php index 754c56f6..6b8cf3f4 100644 --- a/test/HydratorAwareTraitTest.php +++ b/test/HydratorAwareTraitTest.php @@ -15,7 +15,6 @@ class HydratorAwareTraitTest extends TestCase { public function testSetHydrator(): void { - /** @psalm-suppress InvalidScalarArgument False positive */ $object = $this->getObjectForTrait(HydratorAwareTrait::class); $this->assertSame(null, $object->getHydrator()); @@ -29,7 +28,6 @@ public function testSetHydrator(): void public function testGetHydrator(): void { - /** @psalm-suppress InvalidScalarArgument False positive */ $object = $this->getObjectForTrait(HydratorAwareTrait::class); $this->assertNull($object->getHydrator());