Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Set of additional PHPStan rules

*PHPMD rules*
- check for boolean argument flag
- more coming soon ...
- maximum number of parameters (default 10)

## Installation

Expand All @@ -19,4 +19,12 @@ Edit your phpstan configuration file and add
```
includes:
- vendor/pmarki/phpstan-rules/extension.neon
```

Additional configuration:
```
parameters:
pmarki:
excessiveParameterListRule:
maxNumberOfParameters: 10
```
21 changes: 20 additions & 1 deletion extension.neon
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,23 @@ services:
-
class: PMarki\PHPStanRules\Rules\BooleanArgumentFlagRule
tags:
- phpstan.rules.rule
- phpstan.rules.rule
-
class: PMarki\PHPStanRules\Rules\ExcessiveParameterListRule
arguments:
maxNumberOfParameters: %pmarki.excessiveParameterListRule.maxNumberOfParameters%
tags:
- phpstan.rules.rule

parameters:
pmarki:
excessiveParameterListRule:
maxNumberOfParameters: 10

parametersSchema:
pmarki: structure([
excessiveParameterListRule: structure([
maxNumberOfParameters: int(),
])
])

60 changes: 60 additions & 0 deletions src/Rules/ExcessiveParameterListRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace PMarki\PHPStanRules\Rules;

use PhpParser\Node;
use PhpParser\Node\FunctionLike;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
use PMarki\PHPStanRules\Utils\Ancestors;

/**
* @implements Rule<FunctionLike>
*/
class ExcessiveParameterListRule implements Rule
{
public function __construct(
private readonly Ancestors $ancestors,
private readonly int $maxNumberOfParameters,
) {
}

public function getNodeType(): string
{
return FunctionLike::class;
}

/**
* @return array<int, \PHPStan\Rules\RuleError>
*/
public function processNode(Node $node, Scope $scope): array
{
if (!$node instanceof FunctionLike) {
return [];
}

if ($node->name instanceof Node\Identifier && $this->ancestors->methodInherited($node->name->name, $scope)) {
return [];
}

$numberOfParams = count($node->getParams());
if ($numberOfParams > $this->maxNumberOfParameters) {
return [
RuleErrorBuilder::message(
sprintf(
'Too many parameters in function declaration, expected %s, found %s.',
$this->maxNumberOfParameters,
$numberOfParams,
)
)->tip('Create a new object to wrap the numerous parameters.')
->identifier('extraExcessiveParameterList')
->build(),
];
}

return [];
}
}
51 changes: 51 additions & 0 deletions tests/ExcessiveParameterListRuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace PMarki\PHPStanRules\Tests;

use PHPStan\Rules\Rule;
use PHPStan\Testing\RuleTestCase;
use PMarki\PHPStanRules\Rules\ExcessiveParameterListRule;
use PMarki\PHPStanRules\Utils\Ancestors;

class ExcessiveParameterListRuleTest extends RuleTestCase
{
private const MAX_NUMBER_OF_PARAMS = 10;
private const TIP = "\n 💡 Create a new object to wrap the numerous parameters.";

public function testExcessiveParameterListRule(): void
{
$this->analyse(
[
__DIR__ . '/fixtures/ExcessiveParameterListRule.php',
],
[
[
sprintf(
"Too many parameters in function declaration, expected %s, found 11.%s",
self::MAX_NUMBER_OF_PARAMS,
self::TIP,
),
6,
],
[
sprintf(
"Too many parameters in function declaration, expected %s, found 11.%s",
self::MAX_NUMBER_OF_PARAMS,
self::TIP,
),
34,
],
],
);
}

protected function getRule(): Rule
{
return new ExcessiveParameterListRule(
new Ancestors(),
self::MAX_NUMBER_OF_PARAMS,
);
}
}
59 changes: 59 additions & 0 deletions tests/fixtures/ExcessiveParameterListRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
namespace ExcessiveParameterListRule;

class ExcessiveParameterListRule
{
private function tooLong(
$a1,
$a2,
$a3,
$a4,
$a5,
$a6,
$a7,
$a8,
$a9,
$a10,
$a11,
) {}

private function good(
$a1,
$a2,
$a3,
$a4,
$a5,
$a6,
$a7,
$a8,
$a9,
$a10,
) {}
}

function tooLong(
$a1,
$a2,
$a3,
$a4,
$a5,
$a6,
$a7,
$a8,
$a9,
$a10,
$a11,
) {}

function good(
$a1,
$a2,
$a3,
$a4,
$a5,
$a6,
$a7,
$a8,
$a9,
$a10,
) {}