diff --git a/.github/workflows/code_analysis.yaml b/.github/workflows/code_analysis.yaml index 64e307d..9ca124e 100644 --- a/.github/workflows/code_analysis.yaml +++ b/.github/workflows/code_analysis.yaml @@ -40,7 +40,7 @@ jobs: - uses: shivammathur/setup-php@v2 with: - php-version: 8.2 + php-version: 8.3 coverage: none # composer install cache - https://github.com/ramsey/composer-install diff --git a/.github/workflows/downgraded_release.yaml b/.github/workflows/downgraded_release.yaml index be64f3e..4b424b3 100644 --- a/.github/workflows/downgraded_release.yaml +++ b/.github/workflows/downgraded_release.yaml @@ -16,7 +16,7 @@ jobs: - uses: "shivammathur/setup-php@v2" with: - php-version: 8.2 + php-version: 8.3 coverage: none - uses: "ramsey/composer-install@v2" diff --git a/.github/workflows/rector.yaml b/.github/workflows/rector.yaml deleted file mode 100644 index dfd4575..0000000 --- a/.github/workflows/rector.yaml +++ /dev/null @@ -1,47 +0,0 @@ -name: Rector - -on: - pull_request: null - - -jobs: - rector: - # Don't run on forks. - if: github.repository == 'tomasvotruba/cognitive-complexity' - - runs-on: ubuntu-latest - - steps: - - - uses: actions/checkout@v3 - with: - # Must be used to trigger workflow after push - token: ${{ secrets.ACCESS_TOKEN }} - - - - uses: shivammathur/setup-php@v2 - with: - php-version: 8.2 - coverage: none - - - uses: "ramsey/composer-install@v2" - - ## First run Rector - here can't be --dry-run !!! it would stop the job with it and not commit anything in the future - - run: vendor/bin/rector --ansi - - - run: vendor/bin/ecs check --fix --ansi - - # see https://github.com/EndBug/add-and-commit - - - # commit only to core contributors who have repository access - if: github.event.pull_request.head.repo.full_name == github.repository - uses: EndBug/add-and-commit@v7.5.0 - with: - # The arguments for the `git add` command (see the paragraph below for more info) - add: . - message: "[ci-review] Rector Rectify" - author_name: "GitHub Action" - author_email: "action@github.com" - env: - # to get push access - GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} diff --git a/README.md b/README.md index 664a2e1..245c263 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ How to keep **cognitive complexity on 1**? Read [Keep Cognitive Complexity Low w composer require tomasvotruba/cognitive-complexity --dev ``` -The package is available on PHP 7.4-8.1 versions in tagged releases. +The package is available on PHP 7.4+.
@@ -47,7 +47,7 @@ With [PHPStan extension installer](https://github.com/phpstan/extension-installe Enable each item on their own with simple configuration: -```neon +```yaml # phpstan.neon parameters: cognitive_complexity: @@ -68,7 +68,7 @@ That's why there is a rule to detect these dependency trees. It checks: Final number is compared and used as a final complexity: -```neon +```yaml # phpstan.neon parameters: cognitive_complexity: diff --git a/composer.json b/composer.json index 571479e..6cbcbbe 100644 --- a/composer.json +++ b/composer.json @@ -4,17 +4,20 @@ "description": "PHPStan rules to measure cognitive complexity of your classes and methods", "license": "MIT", "require": { - "php": "^8.2", + "php": "^8.3", "phpstan/phpstan": "^2.0", - "nikic/php-parser": "^5" + "nikic/php-parser": "^5.3" }, "require-dev": { - "phpstan/extension-installer": "^1.3", - "phpunit/phpunit": "^10.3", - "symplify/easy-coding-standard": "^12.0", - "rector/rector": "^2", - "tracy/tracy": "^2.9", - "php-parallel-lint/php-parallel-lint": "^1.3" + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpunit/phpunit": "^11.5", + "symplify/easy-coding-standard": "^12.5", + "rector/rector": "^2.0", + "tracy/tracy": "^2.10", + "php-parallel-lint/php-parallel-lint": "^1.4", + "tomasvotruba/type-coverage": "^2.0", + "tomasvotruba/unused-public": "^2.0" }, "autoload": { "psr-4": { diff --git a/ecs.php b/ecs.php index 053ecdb..12b47ec 100644 --- a/ecs.php +++ b/ecs.php @@ -3,15 +3,7 @@ declare(strict_types=1); use Symplify\EasyCodingStandard\Config\ECSConfig; -use Symplify\EasyCodingStandard\ValueObject\Set\SetList; -return static function (ECSConfig $ecsConfig): void { - $ecsConfig->paths([__DIR__ . '/src', __DIR__ . '/tests']); - - $ecsConfig->sets([ - SetList::COMMON, - SetList::PSR_12, - SetList::CLEAN_CODE, - SetList::SYMPLIFY, - ]); -}; +return ECSConfig::configure() + ->withPaths([__DIR__ . '/src', __DIR__ . '/tests']) + ->withPreparedSets(common: true, psr12: true, cleanCode: true, symplify: true); diff --git a/phpstan.neon b/phpstan.neon index a44594b..713b2b6 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -7,6 +7,11 @@ parameters: class: 50 function: 8 + unused_public: + methods: true + properties: true + constants: true + level: 8 paths: @@ -22,3 +27,6 @@ parameters: # skip as always string - '#Parameter \#1 \$currentWorkingDirectory of class PHPStan\\DependencyInjection\\ContainerFactory constructor expects string, string\|false given#' + + # used in tests + - '#Public constant "TomasVotruba\\CognitiveComplexity\\Rules\\(.*?)::ERROR_MESSAGE" is never used#' diff --git a/rector.php b/rector.php index 86cbf9f..9b8b0ab 100644 --- a/rector.php +++ b/rector.php @@ -3,30 +3,13 @@ declare(strict_types=1); use Rector\Config\RectorConfig; -use Rector\Set\ValueObject\LevelSetList; -use Rector\Set\ValueObject\SetList; -return static function (RectorConfig $rectorConfig): void { - $rectorConfig->paths([ - __DIR__ . '/src', - __DIR__ . '/tests', - ]); - - $rectorConfig->importNames(); - - $rectorConfig->sets([ - \Rector\PHPUnit\Set\PHPUnitSetList::PHPUNIT_100, - LevelSetList::UP_TO_PHP_82, - SetList::TYPE_DECLARATION, - SetList::PRIVATIZATION, - SetList::NAMING, - SetList::DEAD_CODE, - SetList::CODE_QUALITY, - SetList::CODING_STYLE, - ]); - - $rectorConfig->skip([ +return RectorConfig::configure() + ->withPaths([__DIR__ . '/src', __DIR__ . '/tests']) + ->withImportNames() + ->withPhpSets() + ->withPreparedSets(typeDeclarations: true, privatization: true, naming: true, deadCode: true, codeQuality: true, codingStyle: true) + ->withSkip([ '*/Fixture/*', '*/Source/*', ]); -}; diff --git a/src/ClassReflectionParser.php b/src/ClassReflectionParser.php index 55b3e17..bd99936 100644 --- a/src/ClassReflectionParser.php +++ b/src/ClassReflectionParser.php @@ -39,11 +39,6 @@ public function parse(ClassReflection $classReflection): ?Class_ return null; } - $foundClass = $this->nodeFinder->findFirstInstanceOf($stmts, Class_::class); - if (! $foundClass instanceof Class_) { - return null; - } - - return $foundClass; + return $this->nodeFinder->findFirstInstanceOf($stmts, Class_::class); } } diff --git a/src/Enum/RuleIdentifier.php b/src/Enum/RuleIdentifier.php new file mode 100644 index 0000000..ae3fd1e --- /dev/null +++ b/src/Enum/RuleIdentifier.php @@ -0,0 +1,14 @@ +> */ - private const BREAKING_NODE_TYPES = [Continue_::class, Goto_::class, Break_::class]; + private const array BREAKING_NODE_TYPES = [Continue_::class, Goto_::class, Break_::class]; /** * B1. Increments * * @var array> */ - private const INCREASING_NODE_TYPES = [ + private const array INCREASING_NODE_TYPES = [ If_::class, Else_::class, ElseIf_::class, diff --git a/src/NodeVisitor/NestingNodeVisitor.php b/src/NodeVisitor/NestingNodeVisitor.php index 19d9192..2888835 100644 --- a/src/NodeVisitor/NestingNodeVisitor.php +++ b/src/NodeVisitor/NestingNodeVisitor.php @@ -22,7 +22,7 @@ final class NestingNodeVisitor extends NodeVisitorAbstract /** * @var array> */ - private const NESTING_NODE_TYPES = [ + private const array NESTING_NODE_TYPES = [ If_::class, For_::class, While_::class, diff --git a/src/Rules/ClassDependencyTreeRule.php b/src/Rules/ClassDependencyTreeRule.php index 3353e51..77f6b23 100644 --- a/src/Rules/ClassDependencyTreeRule.php +++ b/src/Rules/ClassDependencyTreeRule.php @@ -16,6 +16,7 @@ use TomasVotruba\CognitiveComplexity\AstCognitiveComplexityAnalyzer; use TomasVotruba\CognitiveComplexity\ClassReflectionParser; use TomasVotruba\CognitiveComplexity\Configuration; +use TomasVotruba\CognitiveComplexity\Enum\RuleIdentifier; /** * @implements Rule @@ -24,10 +25,7 @@ */ final readonly class ClassDependencyTreeRule implements Rule { - /** - * @var string - */ - public const ERROR_MESSAGE = 'Dependency tree complexity %d is over %d. Refactor __construct() dependencies or split up.'; + public const string ERROR_MESSAGE = 'Dependency tree complexity %d is over %d. Refactor __construct() dependencies or split up.'; public function __construct( private AstCognitiveComplexityAnalyzer $astCognitiveComplexityAnalyzer, @@ -97,7 +95,7 @@ public function processNode(Node $node, Scope $scope): array $this->configuration->getMaxDependencyTreeComplexity() ); - return [RuleErrorBuilder::message($message)->identifier('complexity.dependencyTree')->build()]; + return [RuleErrorBuilder::message($message)->identifier(RuleIdentifier::DEPENDENCY_TREE)->build()]; } private function isTypeToAnalyse(ClassReflection $classReflection): bool diff --git a/src/Rules/ClassLikeCognitiveComplexityRule.php b/src/Rules/ClassLikeCognitiveComplexityRule.php index 4bbfb10..74b6acc 100644 --- a/src/Rules/ClassLikeCognitiveComplexityRule.php +++ b/src/Rules/ClassLikeCognitiveComplexityRule.php @@ -12,17 +12,14 @@ use PHPStan\Rules\RuleErrorBuilder; use TomasVotruba\CognitiveComplexity\AstCognitiveComplexityAnalyzer; use TomasVotruba\CognitiveComplexity\Configuration; +use TomasVotruba\CognitiveComplexity\Enum\RuleIdentifier; /** * @see \TomasVotruba\CognitiveComplexity\Tests\Rules\ClassLikeCognitiveComplexityRule\ClassLikeCognitiveComplexityRuleTest */ final readonly class ClassLikeCognitiveComplexityRule implements Rule { - /** - * @api used in tests - * @var string - */ - public const ERROR_MESSAGE = 'Class cognitive complexity is %d, keep it under %d'; + public const string ERROR_MESSAGE = 'Class cognitive complexity is %d, keep it under %d'; public function __construct( private AstCognitiveComplexityAnalyzer $astCognitiveComplexityAnalyzer, @@ -59,6 +56,6 @@ public function processNode(Node $node, Scope $scope): array $this->configuration->getMaxClassCognitiveComplexity() ); - return [RuleErrorBuilder::message($message)->identifier('complexity.classLike')->build()]; + return [RuleErrorBuilder::message($message)->identifier(RuleIdentifier::CLASS_LIKE_COMPLEXITY)->build()]; } } diff --git a/src/Rules/FunctionLikeCognitiveComplexityRule.php b/src/Rules/FunctionLikeCognitiveComplexityRule.php index e418fcb..038c67e 100644 --- a/src/Rules/FunctionLikeCognitiveComplexityRule.php +++ b/src/Rules/FunctionLikeCognitiveComplexityRule.php @@ -16,6 +16,7 @@ use PHPStan\Rules\RuleErrorBuilder; use TomasVotruba\CognitiveComplexity\AstCognitiveComplexityAnalyzer; use TomasVotruba\CognitiveComplexity\Configuration; +use TomasVotruba\CognitiveComplexity\Enum\RuleIdentifier; use TomasVotruba\CognitiveComplexity\Exception\ShouldNotHappenException; /** @@ -32,11 +33,7 @@ */ final readonly class FunctionLikeCognitiveComplexityRule implements Rule { - /** - * @api used in tests - * @var string - */ - public const ERROR_MESSAGE = 'Cognitive complexity for "%s" is %d, keep it under %d'; + public const string ERROR_MESSAGE = 'Cognitive complexity for "%s" is %d, keep it under %d'; public function __construct( private AstCognitiveComplexityAnalyzer $astCognitiveComplexityAnalyzer, @@ -75,7 +72,7 @@ public function processNode(Node $node, Scope $scope): array $this->configuration->getMaxFunctionCognitiveComplexity() ); - return [RuleErrorBuilder::message($message)->identifier('complexity.functionLike')->build()]; + return [RuleErrorBuilder::message($message)->identifier(RuleIdentifier::FUNCTION_COMPLEXITY)->build()]; } private function resolveFunctionName(FunctionLike $functionLike, Scope $scope): string diff --git a/tests/Rules/ClassDependencyTreeRule/ClassDependencyTreeRuleTest.php b/tests/Rules/ClassDependencyTreeRule/ClassDependencyTreeRuleTest.php index 62f3650..e7c5aa9 100644 --- a/tests/Rules/ClassDependencyTreeRule/ClassDependencyTreeRuleTest.php +++ b/tests/Rules/ClassDependencyTreeRule/ClassDependencyTreeRuleTest.php @@ -5,6 +5,7 @@ namespace TomasVotruba\CognitiveComplexity\Tests\Rules\ClassDependencyTreeRule; use Iterator; +use Override; use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; use PHPUnit\Framework\Attributes\DataProvider; @@ -30,6 +31,7 @@ public static function provideDataForTest(): Iterator /** * @return string[] */ + #[Override] public static function getAdditionalConfigFiles(): array { return [__DIR__ . '/config/configured_rule.neon']; diff --git a/tests/Rules/ClassLikeCognitiveComplexityRule/ClassLikeCognitiveComplexityRuleTest.php b/tests/Rules/ClassLikeCognitiveComplexityRule/ClassLikeCognitiveComplexityRuleTest.php index e153476..d20cf9a 100644 --- a/tests/Rules/ClassLikeCognitiveComplexityRule/ClassLikeCognitiveComplexityRuleTest.php +++ b/tests/Rules/ClassLikeCognitiveComplexityRule/ClassLikeCognitiveComplexityRuleTest.php @@ -5,6 +5,7 @@ namespace TomasVotruba\CognitiveComplexity\Tests\Rules\ClassLikeCognitiveComplexityRule; use Iterator; +use Override; use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; use PHPUnit\Framework\Attributes\DataProvider; @@ -33,6 +34,7 @@ public static function provideDataForTest(): Iterator /** * @return string[] */ + #[Override] public static function getAdditionalConfigFiles(): array { return [__DIR__ . '/config/configured_rule.neon']; diff --git a/tests/Rules/ClassLikeCognitiveComplexityRule/config/configured_rule.neon b/tests/Rules/ClassLikeCognitiveComplexityRule/config/configured_rule.neon index 9b1d4b9..2219d97 100644 --- a/tests/Rules/ClassLikeCognitiveComplexityRule/config/configured_rule.neon +++ b/tests/Rules/ClassLikeCognitiveComplexityRule/config/configured_rule.neon @@ -1,7 +1,6 @@ includes: - ../../../../config/extension.neon - parameters: cognitive_complexity: class: 50 diff --git a/tests/Rules/FunctionLikeCognitiveComplexityRule/FunctionLikeCognitiveComplexityRuleTest.php b/tests/Rules/FunctionLikeCognitiveComplexityRule/FunctionLikeCognitiveComplexityRuleTest.php index 9ed13ec..2d0a1b5 100644 --- a/tests/Rules/FunctionLikeCognitiveComplexityRule/FunctionLikeCognitiveComplexityRuleTest.php +++ b/tests/Rules/FunctionLikeCognitiveComplexityRule/FunctionLikeCognitiveComplexityRuleTest.php @@ -5,6 +5,7 @@ namespace TomasVotruba\CognitiveComplexity\Tests\Rules\FunctionLikeCognitiveComplexityRule; use Iterator; +use Override; use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; use PHPUnit\Framework\Attributes\DataProvider; @@ -48,6 +49,7 @@ public static function provideDataForTest(): Iterator /** * @return string[] */ + #[Override] public static function getAdditionalConfigFiles(): array { return [__DIR__ . '/config/configured_rule.neon'];