diff --git a/.github/workflows/downgraded_release.yaml b/.github/workflows/downgraded_release.yaml index b1e3cc1..41d2e69 100644 --- a/.github/workflows/downgraded_release.yaml +++ b/.github/workflows/downgraded_release.yaml @@ -20,12 +20,12 @@ jobs: - uses: "ramsey/composer-install@v2" - # downgrade /src to PHP 7.2 - - run: vendor/bin/rector process src --config build/rector-downgrade-php-72.php --ansi + # downgrade /src to PHP 7.4 + - run: vendor/bin/rector process src --config build/rector-downgrade-php-74.php --ansi - run: vendor/bin/ecs check src --fix --ansi - # copy PHP 7.2 composer - - run: cp build/composer-php-72.json composer.json + # copy PHP 7.4 composer + - run: cp build/composer-php-74.json composer.json # clear the dev files - run: rm -rf build .github tests stubs ecs.php phpstan.neon phpunit.xml composer-dependency-analyser.php @@ -42,7 +42,7 @@ jobs: run: | # separate a "git add" to add untracked (new) files too git add --all - git commit -m "release PHP 7.2 downgraded" + git commit -m "release PHP 7.4 downgraded" # force push tag, so there is only 1 version git tag "${GITHUB_REF#refs/tags/}" --force diff --git a/build/composer-php-72.json b/build/composer-php-74.json similarity index 88% rename from build/composer-php-72.json rename to build/composer-php-74.json index 1a5c4ac..f59c61f 100644 --- a/build/composer-php-72.json +++ b/build/composer-php-74.json @@ -5,8 +5,8 @@ "license": "MIT", "keywords": ["static analysis", "phpstan-extension"], "require": { - "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.10.19", + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.0.3", "webmozart/assert": "^1.11" }, "autoload": { diff --git a/build/rector-downgrade-php-72.php b/build/rector-downgrade-php-74.php similarity index 73% rename from build/rector-downgrade-php-72.php rename to build/rector-downgrade-php-74.php index 5550cff..b98900a 100644 --- a/build/rector-downgrade-php-72.php +++ b/build/rector-downgrade-php-74.php @@ -6,5 +6,5 @@ use Rector\Set\ValueObject\DowngradeLevelSetList; return static function (RectorConfig $rectorConfig): void { - $rectorConfig->sets([DowngradeLevelSetList::DOWN_TO_PHP_72]); + $rectorConfig->sets([DowngradeLevelSetList::DOWN_TO_PHP_74]); }; diff --git a/composer.json b/composer.json index 9bf8bce..b2a5d63 100644 --- a/composer.json +++ b/composer.json @@ -6,21 +6,20 @@ "keywords": ["static analysis", "phpstan-extension"], "require": { "php": "^8.2", - "phpstan/phpstan": "^1.12", + "phpstan/phpstan": "^2.0.3", "webmozart/assert": "^1.11", - "nikic/php-parser": "^4.19" + "nikic/php-parser": "^5.3" }, "require-dev": { "phpstan/extension-installer": "^1.4", "tracy/tracy": "^2.10", - "symplify/easy-coding-standard": "^12.3", - "rector/rector": "^1.2.5", - "phpunit/phpunit": "^10.5", - "tomasvotruba/class-leak": "^0.2.11", - "tomasvotruba/type-coverage": "^0.3", + "symplify/easy-coding-standard": "^12.4", + "rector/rector": "^2.0.0", + "phpunit/phpunit": "^11.5", + "tomasvotruba/class-leak": "^1.2", "symplify/easy-ci": "^12.1", - "shipmonk/composer-dependency-analyser": "^1.7", - "symplify/phpstan-rules": "^13.0" + "symplify/phpstan-rules": "^14.0", + "shipmonk/composer-dependency-analyser": "^1.7" }, "autoload": { "psr-4": { diff --git a/phpstan.neon b/phpstan.neon index af9b5c9..0606285 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,10 +2,10 @@ includes: - config/extension.neon parameters: - type_coverage: - return_type: 99 - param_type: 99 - property_type: 99 +# type_coverage: +# return_type: 99 +# param_type: 99 +# property_type: 99 level: 8 @@ -21,7 +21,14 @@ parameters: - identifier: missingType.generics - # overly detailed + # removes important type knowledge - - message: '#testRule\(\) has parameter (.*?) with no value type specified in iterable type array#' - path: tests/Rules + identifier: phpstanApi.instanceofType + + # not useful - we need to check reflection instance + - + path: src/MethodTypeDetector.php + identifier: phpstanApi.instanceofAssumption + - + path: src/MethodTypeDetector.php + identifier: phpstanApi.class diff --git a/src/ClassMethodCallReferenceResolver.php b/src/ClassMethodCallReferenceResolver.php index 3d06980..5901455 100644 --- a/src/ClassMethodCallReferenceResolver.php +++ b/src/ClassMethodCallReferenceResolver.php @@ -38,8 +38,12 @@ public function resolve(MethodCall $methodCall, Scope $scope): array } $methodCallReferences = []; - foreach ($callerType->getReferencedClasses() as $className) { - $methodCallReferences[] = new MethodCallReference($className, $methodCall->name->toString(), $isLocal); + foreach ($callerType->getReferencedClasses() as $referencedClass) { + $methodCallReferences[] = new MethodCallReference( + $referencedClass, + $methodCall->name->toString(), + $isLocal + ); } return $methodCallReferences; diff --git a/src/Collectors/Callable_/AttributeCallableCollector.php b/src/Collectors/Callable_/AttributeCallableCollector.php index cb50861..176bb3b 100644 --- a/src/Collectors/Callable_/AttributeCallableCollector.php +++ b/src/Collectors/Callable_/AttributeCallableCollector.php @@ -8,7 +8,6 @@ use PhpParser\Node\Attribute; use PhpParser\Node\AttributeGroup; use PhpParser\Node\Expr\Array_; -use PhpParser\Node\Expr\ArrayItem; use PhpParser\Node\Scalar\String_; use PHPStan\Analyser\Scope; use PHPStan\Collectors\Collector; @@ -84,14 +83,6 @@ private function matchClassAndMethodExprs(Attribute $attribute): ?ClassAndMethod return null; } - if (! $array->items[0] instanceof ArrayItem) { - return null; - } - - if (! $array->items[1] instanceof ArrayItem) { - return null; - } - $classArrayItem = $array->items[0]->value; $methodArrayItem = $array->items[1]->value; diff --git a/src/Collectors/Callable_/CallableTypeCollector.php b/src/Collectors/Callable_/CallableTypeCollector.php index e356af8..358f90d 100644 --- a/src/Collectors/Callable_/CallableTypeCollector.php +++ b/src/Collectors/Callable_/CallableTypeCollector.php @@ -6,6 +6,7 @@ use PhpParser\Node; use PhpParser\Node\Expr; +use PhpParser\Node\Expr\Array_; use PHPStan\Analyser\Scope; use PHPStan\Collectors\Collector; use PHPStan\Reflection\ClassReflection; @@ -26,7 +27,7 @@ public function __construct( public function getNodeType(): string { - return Expr\Array_::class; + return Array_::class; } /** @@ -51,21 +52,23 @@ public function processNode(Node $node, Scope $scope): ?array return null; } - $typeAndMethodNames = $callableType->findTypeAndMethodNames(); - if ($typeAndMethodNames === []) { - return null; - } - $classMethodReferences = []; - foreach ($typeAndMethodNames as $typeAndMethodName) { - if ($typeAndMethodName->isUnknown()) { + foreach ($callableType->getConstantArrays() as $constantArray) { + $typeAndMethodNames = $constantArray->findTypeAndMethodNames(); + if ($typeAndMethodNames === []) { continue; } - $objectClassNames = $typeAndMethodName->getType() - ->getObjectClassNames(); - foreach ($objectClassNames as $objectClassName) { - $classMethodReferences[] = $objectClassName . '::' . $typeAndMethodName->getMethod(); + foreach ($typeAndMethodNames as $typeAndMethodName) { + if ($typeAndMethodName->isUnknown()) { + continue; + } + + $objectClassNames = $typeAndMethodName->getType() + ->getObjectClassNames(); + foreach ($objectClassNames as $objectClassName) { + $classMethodReferences[] = $objectClassName . '::' . $typeAndMethodName->getMethod(); + } } } diff --git a/src/Collectors/FormTypeClassCollector.php b/src/Collectors/FormTypeClassCollector.php index 088e1b4..6f39981 100644 --- a/src/Collectors/FormTypeClassCollector.php +++ b/src/Collectors/FormTypeClassCollector.php @@ -5,7 +5,7 @@ namespace TomasVotruba\UnusedPublic\Collectors; use PhpParser\Node; -use PhpParser\Node\Expr\ArrayItem; +use PhpParser\Node\ArrayItem; use PhpParser\Node\Scalar\String_; use PHPStan\Analyser\Scope; use PHPStan\Collectors\Collector; diff --git a/tests/Rules/LocalOnlyPublicClassMethodRule/Fixture/SkipPublicCallbackMethod.php b/tests/Rules/LocalOnlyPublicClassMethodRule/Fixture/SkipPublicCallbackMethod.php index dd0b61d..48b30c0 100644 --- a/tests/Rules/LocalOnlyPublicClassMethodRule/Fixture/SkipPublicCallbackMethod.php +++ b/tests/Rules/LocalOnlyPublicClassMethodRule/Fixture/SkipPublicCallbackMethod.php @@ -18,5 +18,6 @@ private function run() function doFoo() { - call_user_func([SkipPublicCallbackMethod::class, 'runHere']); + $object = new SkipPublicCallbackMethod(); + call_user_func([$object, 'runHere']); } diff --git a/tests/Rules/LocalOnlyPublicClassMethodRule/LocalOnlyPublicClassMethodRuleTest.php b/tests/Rules/LocalOnlyPublicClassMethodRule/LocalOnlyPublicClassMethodRuleTest.php index 7389ca4..5e9b504 100644 --- a/tests/Rules/LocalOnlyPublicClassMethodRule/LocalOnlyPublicClassMethodRuleTest.php +++ b/tests/Rules/LocalOnlyPublicClassMethodRule/LocalOnlyPublicClassMethodRuleTest.php @@ -23,6 +23,10 @@ final class LocalOnlyPublicClassMethodRuleTest extends RuleTestCase { + /** + * @param string[] $filePaths + * @param list $expectedErrorMessagesWithLines + */ #[DataProvider('provideData')] public function testRule(array $filePaths, array $expectedErrorMessagesWithLines): void { diff --git a/tests/Rules/RelativeUnusedPublicClassMethodRule/RelativeUnusedPublicClassMethodRuleTest.php b/tests/Rules/RelativeUnusedPublicClassMethodRule/RelativeUnusedPublicClassMethodRuleTest.php index fb44283..97e654e 100644 --- a/tests/Rules/RelativeUnusedPublicClassMethodRule/RelativeUnusedPublicClassMethodRuleTest.php +++ b/tests/Rules/RelativeUnusedPublicClassMethodRule/RelativeUnusedPublicClassMethodRuleTest.php @@ -21,6 +21,10 @@ final class RelativeUnusedPublicClassMethodRuleTest extends RuleTestCase { + /** + * @param string[] $filePaths + * @param list $expectedErrorMessagesWithLines + */ #[DataProvider('provideData')] public function testRule(array $filePaths, array $expectedErrorMessagesWithLines): void { diff --git a/tests/Rules/UnusedPublicClassConstRule/UnusedPublicClassConstRuleTest.php b/tests/Rules/UnusedPublicClassConstRule/UnusedPublicClassConstRuleTest.php index f001b59..05643c0 100644 --- a/tests/Rules/UnusedPublicClassConstRule/UnusedPublicClassConstRuleTest.php +++ b/tests/Rules/UnusedPublicClassConstRule/UnusedPublicClassConstRuleTest.php @@ -21,6 +21,10 @@ final class UnusedPublicClassConstRuleTest extends RuleTestCase { + /** + * @param string[] $filePaths + * @param list $expectedErrorMessagesWithLines + */ #[DataProvider('provideData')] #[DataProvider('provideDataFromBladeTemplates')] public function testRule(array $filePaths, array $expectedErrorMessagesWithLines): void diff --git a/tests/Rules/UnusedPublicClassMethodRule/TemplatePathsTest.php b/tests/Rules/UnusedPublicClassMethodRule/TemplatePathsTest.php index f09b0d7..bf13895 100644 --- a/tests/Rules/UnusedPublicClassMethodRule/TemplatePathsTest.php +++ b/tests/Rules/UnusedPublicClassMethodRule/TemplatePathsTest.php @@ -17,6 +17,10 @@ final class TemplatePathsTest extends RuleTestCase { + /** + * @param string[] $filePaths + * @param list $expectedErrorMessagesWithLines + */ #[DataProvider('provideDataWithTwigTemplates')] #[DataProvider('provideDataWithBladeTemplates')] public function testRule(array $filePaths, array $expectedErrorMessagesWithLines): void diff --git a/tests/Rules/UnusedPublicClassMethodRule/UnusedPublicClassMethodRuleTest.php b/tests/Rules/UnusedPublicClassMethodRule/UnusedPublicClassMethodRuleTest.php index 7a6a454..ccddfa5 100644 --- a/tests/Rules/UnusedPublicClassMethodRule/UnusedPublicClassMethodRuleTest.php +++ b/tests/Rules/UnusedPublicClassMethodRule/UnusedPublicClassMethodRuleTest.php @@ -28,6 +28,10 @@ final class UnusedPublicClassMethodRuleTest extends RuleTestCase { + /** + * @param string[] $filePaths + * @param list $expectedErrorMessagesWithLines + */ #[DataProvider('provideData')] #[DataProvider('provideDataTests')] #[DataProvider('provideDataSymfony')] diff --git a/tests/Rules/UnusedPublicPropertyRule/UnusedPublicPropertyRuleTest.php b/tests/Rules/UnusedPublicPropertyRule/UnusedPublicPropertyRuleTest.php index e995167..21cb4b2 100644 --- a/tests/Rules/UnusedPublicPropertyRule/UnusedPublicPropertyRuleTest.php +++ b/tests/Rules/UnusedPublicPropertyRule/UnusedPublicPropertyRuleTest.php @@ -23,6 +23,10 @@ final class UnusedPublicPropertyRuleTest extends RuleTestCase { + /** + * @param string[] $filePaths + * @param list $expectedErrorMessagesWithLines + */ #[DataProvider('provideData')] public function testRule(array $filePaths, array $expectedErrorMessagesWithLines): void {