From 51e2406244ad3c5067c7b3261f1f1bda4069822e Mon Sep 17 00:00:00 2001 From: Milan Donef Date: Tue, 11 Feb 2025 11:04:39 +0100 Subject: [PATCH 1/3] chore! drop support for php < 8.1 and upgrade to phpstan 2.0 --- .github/workflows/main.yml | 6 +++--- Makefile | 10 +++++----- composer.json | 9 +++++---- phpstan.neon | 2 ++ .../Phpstan/GroupByMethodReturnTypeExtension.php | 9 +++++---- .../LateStaticBindingMethodReturnTypeExtension.php | 10 +++++----- ...taticBindingStaticMethodReturnTypeExtension.php | 14 +++++++------- tests/Bonami/Collection/Phpstan/MapTest.php | 1 + 8 files changed, 33 insertions(+), 28 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6c15006..cd336ef 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - php: ['7.3', '7.4', '8.0'] + php: ['8.1','8.2','8.3','8.4'] steps: - name: "Checkout" @@ -44,7 +44,7 @@ jobs: strategy: matrix: - php: ['7.3', '7.4', '8.0'] + php: ['8.1','8.2','8.3','8.4'] steps: - name: "Checkout" @@ -75,7 +75,7 @@ jobs: strategy: matrix: - php: ['8.0'] + php: ['8.1'] steps: - name: "Checkout" diff --git a/Makefile b/Makefile index 022c819..a0cee93 100644 --- a/Makefile +++ b/Makefile @@ -11,16 +11,16 @@ test: $(MAKE) fmt-check phpstan: - docker run -it --rm -v ${PWD}:/app -w /app php:7.3-cli-alpine php -d error_reporting=-1 -d memory_limit=-1 bin/phpstan --ansi analyse + docker run -it --rm -v ${PWD}:/app -w /app php:8.3-cli-alpine php -d error_reporting=-1 -d memory_limit=-1 bin/phpstan --ansi analyse phpstan-clear-cache: - docker run -it --rm -v ${PWD}:/app -w /app php:7.3-cli-alpine php -d error_reporting=-1 -d memory_limit=-1 bin/phpstan --ansi clear-result-cache + docker run -it --rm -v ${PWD}:/app -w /app php:8.3-cli-alpine php -d error_reporting=-1 -d memory_limit=-1 bin/phpstan --ansi clear-result-cache phpunit: - docker run -it --rm -v ${PWD}:/app -w /app php:7.3-cli-alpine php -d error_reporting=-1 bin/phpunit --colors=always -c phpunit.xml + docker run -it --rm -v ${PWD}:/app -w /app php:8.3-cli-alpine php -d error_reporting=-1 bin/phpunit --colors=always -c phpunit.xml fmt-check: - docker run -it --rm -v ${PWD}:/app -w /app php:7.3-cli-alpine php bin/phpcs --standard=./ruleset.xml --extensions=php --tab-width=4 -sp ./src ./tests + docker run -it --rm -v ${PWD}:/app -w /app php:8.3-cli-alpine php bin/phpcs --standard=./ruleset.xml --extensions=php --tab-width=4 -sp ./src ./tests fmt: - docker run -it --rm -v ${PWD}:/app -w /app php:7.3-cli-alpine php bin/phpcbf --standard=./ruleset.xml --extensions=php --tab-width=4 -sp ./src ./tests + docker run -it --rm -v ${PWD}:/app -w /app php:8.3-cli-alpine php bin/phpcbf --standard=./ruleset.xml --extensions=php --tab-width=4 -sp ./src ./tests diff --git a/composer.json b/composer.json index ed9a136..ef1d79a 100644 --- a/composer.json +++ b/composer.json @@ -1,4 +1,5 @@ { + "version": "0.5.0", "name": "bonami/phpstan-collections", "type": "phpstan-extension", "description": "Phpstan extension for bonami/collections library", @@ -10,8 +11,8 @@ } ], "require": { - "php": ">=7.3|^8.0", - "phpstan/phpstan": "^1.0" + "php": "^8.1", + "phpstan/phpstan": "^2.0" }, "require-dev": { "roave/security-advisories": "dev-latest", @@ -19,7 +20,7 @@ "phpunit/phpunit": "^9.4.2", "slevomat/coding-standard": "^6.4.1", "squizlabs/php_codesniffer": "^3.5.0", - "bonami/collections": "^0.4.5" + "bonami/collections": "0.6.0" }, "config": { "bin-dir": "bin", @@ -30,7 +31,7 @@ }, "extra": { "branch-alias": { - "dev-master": "0.4.x-dev" + "dev-master": "0.5.x-dev" }, "phpstan": { "includes": [ diff --git a/phpstan.neon b/phpstan.neon index 90931bc..0ee8d28 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,6 +2,8 @@ includes: - extension.neon - vendor/phpstan/phpstan/conf/bleedingEdge.neon parameters: + ignoreErrors: + - '~Doing instanceof PHPStan\\Type\\Generic\\GenericObjectType is error-prone and deprecated~' reportUnmatchedIgnoredErrors: true level: 9 paths: diff --git a/src/Bonami/Collection/Phpstan/GroupByMethodReturnTypeExtension.php b/src/Bonami/Collection/Phpstan/GroupByMethodReturnTypeExtension.php index 913e840..3c1a4c9 100644 --- a/src/Bonami/Collection/Phpstan/GroupByMethodReturnTypeExtension.php +++ b/src/Bonami/Collection/Phpstan/GroupByMethodReturnTypeExtension.php @@ -9,7 +9,6 @@ use PhpParser\Node\Expr\MethodCall; use PHPStan\Analyser\Scope; use PHPStan\Reflection\MethodReflection; -use PHPStan\Type\CallableType; use PHPStan\Type\ClosureType; use PHPStan\Type\DynamicMethodReturnTypeExtension; use PHPStan\Type\Generic\GenericObjectType; @@ -18,9 +17,10 @@ class GroupByMethodReturnTypeExtension implements DynamicMethodReturnTypeExtension { - /** @var string */ - private $class; + /** @var class-string */ + private string $class; + /** @param class-string $class */ public function __construct(string $class) { $this->class = $class; @@ -43,8 +43,9 @@ public function getTypeFromMethodCall( ): Type { $arg = $methodCall->args[0]; assert($arg instanceof Arg); + $closure = $scope->getType($arg->value); - assert($closure instanceof ClosureType || $closure instanceof CallableType); + assert($closure instanceof ClosureType); $listType = $scope->getType($methodCall->var); diff --git a/src/Bonami/Collection/Phpstan/LateStaticBindingMethodReturnTypeExtension.php b/src/Bonami/Collection/Phpstan/LateStaticBindingMethodReturnTypeExtension.php index 3162ce4..b575fb0 100644 --- a/src/Bonami/Collection/Phpstan/LateStaticBindingMethodReturnTypeExtension.php +++ b/src/Bonami/Collection/Phpstan/LateStaticBindingMethodReturnTypeExtension.php @@ -12,14 +12,14 @@ class LateStaticBindingMethodReturnTypeExtension implements DynamicMethodReturnTypeExtension { - /** @var string */ - private $class; + /** @var class-string */ + private string $class; /** @var array */ - private $methods; + private array $methods; /** - * @param string $class + * @param class-string $class * @param array $methods */ private function __construct(string $class, array $methods) @@ -29,7 +29,7 @@ private function __construct(string $class, array $methods) } /** - * @param string $class + * @param class-string $class * @param array $methods */ public static function forMethods(string $class, array $methods): self diff --git a/src/Bonami/Collection/Phpstan/LateStaticBindingStaticMethodReturnTypeExtension.php b/src/Bonami/Collection/Phpstan/LateStaticBindingStaticMethodReturnTypeExtension.php index 9e50026..8b96ed3 100644 --- a/src/Bonami/Collection/Phpstan/LateStaticBindingStaticMethodReturnTypeExtension.php +++ b/src/Bonami/Collection/Phpstan/LateStaticBindingStaticMethodReturnTypeExtension.php @@ -17,14 +17,14 @@ class LateStaticBindingStaticMethodReturnTypeExtension implements DynamicStaticMethodReturnTypeExtension { - /** @var string */ - private $class; + /** @var class-string */ + private string $class; /** @var array */ - private $methods; + private array $methods; /** - * @param string $class + * @param class-string $class * @param array $methods */ private function __construct(string $class, array $methods) @@ -34,7 +34,7 @@ private function __construct(string $class, array $methods) } /** - * @param string $class + * @param class-string $class * @param array $methods */ public static function forMethods(string $class, array $methods): self @@ -60,8 +60,8 @@ public function getTypeFromStaticMethodCall( $calledClassExpr = $methodCall->class; if ($calledClassExpr instanceof PropertyFetch) { $type = $scope->getType($calledClassExpr); - if ($type instanceof GenericClassStringType) { - return $type->getGenericType(); + if ($type->isClassString()->yes()) { + return $type->getClassStringObjectType(); } } diff --git a/tests/Bonami/Collection/Phpstan/MapTest.php b/tests/Bonami/Collection/Phpstan/MapTest.php index 04a8222..06b77d4 100644 --- a/tests/Bonami/Collection/Phpstan/MapTest.php +++ b/tests/Bonami/Collection/Phpstan/MapTest.php @@ -12,6 +12,7 @@ class MapTest extends TestCase public function testFromAssociativeArrayReturnType(): void { $genericList = Map::fromAssociativeArray([1 => new Foo()]); + // @phpstan-ignore-next-line $this->requireMapOfFoo($genericList); self::assertInstanceOf(Map::class, $genericList); From e198de522ebe93c89130ac70c815571194503515 Mon Sep 17 00:00:00 2001 From: Jan Machala Date: Thu, 20 Mar 2025 19:25:53 +0100 Subject: [PATCH 2/3] refactor: use call site variance instead of supression --- tests/Bonami/Collection/Phpstan/MapTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/Bonami/Collection/Phpstan/MapTest.php b/tests/Bonami/Collection/Phpstan/MapTest.php index 06b77d4..42125ba 100644 --- a/tests/Bonami/Collection/Phpstan/MapTest.php +++ b/tests/Bonami/Collection/Phpstan/MapTest.php @@ -12,7 +12,6 @@ class MapTest extends TestCase public function testFromAssociativeArrayReturnType(): void { $genericList = Map::fromAssociativeArray([1 => new Foo()]); - // @phpstan-ignore-next-line $this->requireMapOfFoo($genericList); self::assertInstanceOf(Map::class, $genericList); @@ -188,7 +187,7 @@ public function testSortValuesReturnType(): void self::assertInstanceOf(FooMap::class, $concreteList); } - /** @phpstan-param Map $list */ + /** @phpstan-param Map $list */ public function requireMapOfFoo(Map $list): void { } From 28feec2ef928fe91ab7060a61e3b0111507e43f4 Mon Sep 17 00:00:00 2001 From: Jan Machala Date: Thu, 20 Mar 2025 19:30:26 +0100 Subject: [PATCH 3/3] chore: update GH pipeline --- .github/workflows/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cd336ef..1e43cd9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,7 +26,7 @@ jobs: extensions: "json, dom, mbstring" - name: "Cache dependencies" - uses: "actions/cache@v1.1.2" + uses: "actions/cache@v4" with: path: "~/.composer/cache" key: "php-${{ matrix.php }}-composer-cache-${{ hashFiles('**/composer.json') }}" @@ -57,7 +57,7 @@ jobs: extensions: "json, dom, mbstring" - name: "Cache dependencies" - uses: "actions/cache@v1.1.2" + uses: "actions/cache@v4" with: path: "~/.composer/cache" key: "php-${{ matrix.php }}-composer-cache-${{ hashFiles('**/composer.json') }}" @@ -91,7 +91,7 @@ jobs: run: "composer validate" - name: "Cache dependencies" - uses: "actions/cache@v1.1.2" + uses: "actions/cache@v4" with: path: "~/.composer/cache" key: "php-${{ matrix.php }}-composer-cache-${{ hashFiles('**/composer.json') }}"