From e069e25f72fd9a124c75c769a364c235075a69e8 Mon Sep 17 00:00:00 2001 From: Odinn Adalsteinsson Date: Mon, 2 Dec 2024 11:17:47 +0100 Subject: [PATCH] chore: Upgraded to Larastan 3.0 and PHPStan 2.0 Upgrades dependencies and fixes code and baselines. --- .github/workflows/tests.yml | 37 ++++----------- .gitignore | 4 +- composer.json | 14 +++--- phpstan-baseline.neon | 47 +++++++++++++++---- .../ListenerShouldHaveVoidReturnTypeRule.php | 5 +- src/Rules/NoLocalQueryScopeRule.php | 12 ++--- .../ScopeShouldReturnQueryBuilderRule.php | 18 ++++--- tests/phpunit.xml | 25 +++------- 8 files changed, 78 insertions(+), 84 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4f1e09f..8cdce68 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -17,12 +17,12 @@ jobs: strategy: matrix: - php: [8.1] + php: [8.2] dependencies: [lowest] steps: - name: "Checkout" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" - name: "Install PHP with extensions" uses: "shivammathur/setup-php@v2" @@ -63,12 +63,12 @@ jobs: strategy: matrix: - php: [8.1] + php: [8.2] dependencies: [lowest] steps: - name: "Checkout" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" - name: "Install PHP with extensions" uses: "shivammathur/setup-php@v2" @@ -116,32 +116,13 @@ jobs: strategy: matrix: - php: [8.1, 8.2, 8.3, 8.4 ] - orchestra: [ "^7.47", "^8.13", "^9.0" ] + php: [ 8.2, 8.3, 8.4 ] + orchestra: [ "^9.0" ] dependencies: [ lowest, highest ] - exclude: - - php: "8.1" - orchestra: "^9.0" - dependencies: "highest" - - php: "8.1" - orchestra: "^9.0" - dependencies: "lowest" - - php: "8.4" - orchestra: "^7.47" - dependencies: "highest" - - php: "8.4" - orchestra: "^7.47" - dependencies: "lowest" - - php: "8.4" - orchestra: "^8.13" - dependencies: "highest" - - php: "8.4" - orchestra: "^8.13" - dependencies: "lowest" steps: - name: "Checkout" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" - name: "Install PHP with extensions" uses: "shivammathur/setup-php@v2" @@ -179,13 +160,13 @@ jobs: strategy: matrix: - php: [8.1] + php: [8.2] dependencies: - "lowest" steps: - name: "Checkout" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" - name: "Install PHP with extensions" uses: "shivammathur/setup-php@v2" diff --git a/.gitignore b/.gitignore index f5ef82a..ff6c459 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,6 @@ composer.lock vendor coverage .phpunit.result.cache -.idea \ No newline at end of file +.idea +tests/.phpunit.cache +tests/phpunit.xml.bak diff --git a/composer.json b/composer.json index 1682654..1b420d3 100644 --- a/composer.json +++ b/composer.json @@ -6,15 +6,15 @@ "MIT" ], "require": { - "php": "^8.0", - "larastan/larastan": "^2.9.12", - "phpstan/phpstan": "^1.12" + "php": "^8.2", + "larastan/larastan": "^3.0", + "phpstan/phpstan": "^2.0" }, "require-dev": { - "doctrine/coding-standard": "^12", - "phpstan/phpstan-phpunit": "^1.3", - "phpunit/phpunit": "^9.6 || ^10", - "orchestra/testbench": "^v7.47.0 || ^8.13.0 || ^9.0.9", + "doctrine/coding-standard": "^12.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.0", + "orchestra/testbench" : "^9.0", "roave/security-advisories": "dev-latest" }, "config": { diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index b56c035..c7d80e3 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,32 +1,61 @@ parameters: ignoreErrors: - - message: "#^Calling PHPStan\\\\Reflection\\\\Php\\\\PhpFunctionReflection\\:\\:getFileName\\(\\) is not covered by backward compatibility promise\\. The method might change in a minor PHPStan version\\.$#" + message: '#^Doing instanceof PHPStan\\Type\\Generic\\GenericObjectType is error\-prone and deprecated\.$#' + identifier: phpstanApi.instanceofType + count: 1 + path: src/Rules/NoDynamicWhereRule.php + + - + message: '#^Doing instanceof PHPStan\\Type\\ObjectType is error\-prone and deprecated\. Use Type\:\:isObject\(\) or Type\:\:getObjectClassNames\(\) instead\.$#' + identifier: phpstanApi.instanceofType + count: 3 + path: src/Rules/NoDynamicWhereRule.php + + - + message: '#^Asking about instanceof PHPStan\\Reflection\\Php\\PhpFunctionReflection is not covered by backward compatibility promise\. The class might change in a minor PHPStan version\.$#' + identifier: phpstanApi.class count: 1 path: src/Rules/NoGlobalLaravelFunctionRule.php - - message: "#^Calling PHPStan\\\\Reflection\\\\Php\\\\PhpFunctionReflection\\:\\:getName\\(\\) is not covered by backward compatibility promise\\. The method might change in a minor PHPStan version\\.$#" + message: '#^Calling PHPStan\\Reflection\\Php\\PhpFunctionReflection\:\:getFileName\(\) is not covered by backward compatibility promise\. The method might change in a minor PHPStan version\.$#' + identifier: phpstanApi.method count: 1 path: src/Rules/NoGlobalLaravelFunctionRule.php - - message: "#^Calling PHPStan\\\\Reflection\\\\Php\\\\PhpParameterFromParserNodeReflection\\:\\:getType\\(\\) is not covered by backward compatibility promise\\. The method might change in a minor PHPStan version\\.$#" - count: 3 + message: '#^Calling PHPStan\\Reflection\\Php\\PhpFunctionReflection\:\:getName\(\) is not covered by backward compatibility promise\. The method might change in a minor PHPStan version\.$#' + identifier: phpstanApi.method + count: 1 + path: src/Rules/NoGlobalLaravelFunctionRule.php + + - + message: '#^Calling PHPStan\\Reflection\\Php\\PhpParameterFromParserNodeReflection\:\:getType\(\) is not covered by backward compatibility promise\. The method might change in a minor PHPStan version\.$#' + identifier: phpstanApi.method + count: 1 path: src/Rules/NoLocalQueryScopeRule.php - - message: "#^Calling PHPStan\\\\Reflection\\\\Php\\\\PhpParameterFromParserNodeReflection\\:\\:getType\\(\\) is not covered by backward compatibility promise\\. The method might change in a minor PHPStan version\\.$#" - count: 3 + message: '#^Doing instanceof PHPStan\\Type\\ObjectType is error\-prone and deprecated\. Use Type\:\:isObject\(\) or Type\:\:getObjectClassNames\(\) instead\.$#' + identifier: phpstanApi.instanceofType + count: 1 + path: src/Rules/NoValidationInControllerRule.php + + - + message: '#^Calling PHPStan\\Reflection\\Php\\PhpParameterFromParserNodeReflection\:\:getType\(\) is not covered by backward compatibility promise\. The method might change in a minor PHPStan version\.$#' + identifier: phpstanApi.method + count: 1 path: src/Rules/ScopeShouldReturnQueryBuilderRule.php - - message: "#^Creating new PHPStan\\\\File\\\\FileHelper is not covered by backward compatibility promise\\. The class might change in a minor PHPStan version\\.$#" + message: '#^Creating new PHPStan\\File\\FileHelper is not covered by backward compatibility promise\. The class might change in a minor PHPStan version\.$#' + identifier: phpstanApi.constructor count: 1 path: tests/Rules/ListenerShouldHaveVoidReturnTypeRuleTest.php - - message: "#^Parameter \\#2 \\$listenerPaths of class Vural\\\\LarastanStrictRules\\\\Rules\\\\ListenerShouldHaveVoidReturnTypeRule constructor expects array\\, mixed given\\.$#" + message: '#^Parameter \#2 \$listenerPaths of class Vural\\LarastanStrictRules\\Rules\\ListenerShouldHaveVoidReturnTypeRule constructor expects array\, mixed given\.$#' + identifier: argument.type count: 1 path: tests/Rules/ListenerShouldHaveVoidReturnTypeRuleTest.php - diff --git a/src/Rules/ListenerShouldHaveVoidReturnTypeRule.php b/src/Rules/ListenerShouldHaveVoidReturnTypeRule.php index e7af1b5..5a49ae3 100644 --- a/src/Rules/ListenerShouldHaveVoidReturnTypeRule.php +++ b/src/Rules/ListenerShouldHaveVoidReturnTypeRule.php @@ -8,7 +8,6 @@ use PHPStan\Analyser\Scope; use PHPStan\File\FileHelper; use PHPStan\Node\InClassMethodNode; -use PHPStan\Reflection\ParametersAcceptorSelector; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleError; use PHPStan\Rules\RuleErrorBuilder; @@ -52,7 +51,7 @@ public function processNode(Node $node, Scope $scope): array } // handle method should except event as parameter - if (count(ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getParameters()) < 1) { + if (count($methodReflection->getParameters()) < 1) { return []; } @@ -72,7 +71,7 @@ public function processNode(Node $node, Scope $scope): array return []; } - if (! (new VoidType())->isSuperTypeOf(ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType())->yes()) { + if (! (new VoidType())->isSuperTypeOf($methodReflection->getReturnType())->yes()) { return [ RuleErrorBuilder::message("Listeners handle method should have 'void' return type.") ->identifier('larastanStrictRules.listenerShouldHaveVoidReturnType') diff --git a/src/Rules/NoLocalQueryScopeRule.php b/src/Rules/NoLocalQueryScopeRule.php index ad71b91..6b332d8 100644 --- a/src/Rules/NoLocalQueryScopeRule.php +++ b/src/Rules/NoLocalQueryScopeRule.php @@ -9,14 +9,12 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; use PHPStan\Node\InClassMethodNode; -use PHPStan\Reflection\ParametersAcceptorSelector; use PHPStan\Reflection\Php\PhpParameterFromParserNodeReflection; use PHPStan\Reflection\ReflectionProvider; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleError; use PHPStan\Rules\RuleErrorBuilder; use PHPStan\ShouldNotHappenException; -use PHPStan\Type\ObjectType; use function count; use function strpos; @@ -68,16 +66,16 @@ public function processNode(Node $node, Scope $scope): array return []; } - $parametersAcceptor = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants()); - /** @var PhpParameterFromParserNodeReflection $firstParameter */ - $firstParameter = $parametersAcceptor->getParameters()[0]; + $firstParameter = $methodReflection->getParameters()[0]; + + $parameterClassNames = $firstParameter->getType()->getObjectClassNames(); - if (! ($firstParameter->getType() instanceof ObjectType)) { + if (count($parameterClassNames) !== 1) { return []; } - if ($firstParameter->getType()->getClassName() !== Builder::class && ! $this->provider->getClass($firstParameter->getType()->getClassName())->isSubclassOf(Builder::class)) { + if ($parameterClassNames[0] !== Builder::class && ! $this->provider->getClass($parameterClassNames[0])->isSubclassOf(Builder::class)) { return []; } diff --git a/src/Rules/ScopeShouldReturnQueryBuilderRule.php b/src/Rules/ScopeShouldReturnQueryBuilderRule.php index 3465a19..05f6465 100644 --- a/src/Rules/ScopeShouldReturnQueryBuilderRule.php +++ b/src/Rules/ScopeShouldReturnQueryBuilderRule.php @@ -9,13 +9,11 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; use PHPStan\Node\InClassMethodNode; -use PHPStan\Reflection\ParametersAcceptorSelector; use PHPStan\Reflection\Php\PhpParameterFromParserNodeReflection; use PHPStan\Reflection\ReflectionProvider; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleError; use PHPStan\Rules\RuleErrorBuilder; -use PHPStan\Type\ObjectType; use function count; use function str_starts_with; @@ -67,22 +65,22 @@ public function processNode(Node $node, Scope $scope): array return []; } - $parametersAcceptor = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants()); - /** @var PhpParameterFromParserNodeReflection $firstParameter */ - $firstParameter = $parametersAcceptor->getParameters()[0]; + $firstParameter = $methodReflection->getParameters()[0]; + + $parameterClassNames = $firstParameter->getType()->getObjectClassNames(); - if (! ($firstParameter->getType() instanceof ObjectType)) { + if (count($parameterClassNames) < 1) { return []; } - if ($firstParameter->getType()->getClassName() !== Builder::class && ! $this->provider->getClass($firstParameter->getType()->getClassName())->isSubclassOf(Builder::class)) { + if ($parameterClassNames[0] !== Builder::class && ! $this->provider->getClass($parameterClassNames[0])->isSubclassOf(Builder::class)) { return []; } - $returnType = $parametersAcceptor->getReturnType(); + $returnTypeClassNames = $methodReflection->getReturnType()->getObjectClassNames(); - if (! ($returnType instanceof ObjectType)) { + if (count($returnTypeClassNames) !== 1) { return [ RuleErrorBuilder::message('Query scope should return query builder instance.') ->identifier('larastanStrictRules.scopeShouldReturnQueryBuilderRule') @@ -90,7 +88,7 @@ public function processNode(Node $node, Scope $scope): array ]; } - if ($returnType->getClassName() !== Builder::class && ! $this->provider->getClass($returnType->getClassName())->isSubclassOf(Builder::class)) { + if ($returnTypeClassNames[0] !== Builder::class && ! $this->provider->getClass($returnTypeClassNames[0])->isSubclassOf(Builder::class)) { return [ RuleErrorBuilder::message('Query scope should return query builder instance.') ->identifier('larastanStrictRules.scopeShouldReturnQueryBuilderRule') diff --git a/tests/phpunit.xml b/tests/phpunit.xml index c89d32f..c56f918 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -1,26 +1,13 @@ - - - - ../src - - + ./Rules + + + ../src + +