Skip to content

Commit

Permalink
Add MissingClosureParameterTypehintRule (#18)
Browse files Browse the repository at this point in the history
* Add MissingClosureParameterTypehintRule

* Fix 7.1 compatibility
  • Loading branch information
Slamdunk authored Sep 2, 2019
1 parent 15589b5 commit ad85547
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ but don't use the result; likely an error of the transition from mutable DateTim
1. `SlamPhpStan\SymfonyProcessRule`: forbid calls to raw system functions well wrapped by
[`symfony/process`](https://github.com/symfony/process) component
1. `SlamPhpStan\UnusedVariableRule`: check for variable inside functions never used after initial assignment
1. `SlamPhpStan\MissingClosureParameterTypehintRule`: requires parameter typehints for closures; WARNING: no PhpDoc
allowed, see [`phpstan/phpstan-strict-rules#87`](https://github.com/phpstan/phpstan-strict-rules/issues/87)
1. `SlamPhpStan\StringToClassRule`: requires strings that refer to classes to be expressed with `::class` notation
1. `SlamPhpStan\GotoRule`: no goto allowed
1. `SlamPhpStan\ClassNotationRule`:
Expand Down
4 changes: 4 additions & 0 deletions conf/slam-rules.neon
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,7 @@ services:
class: SlamPhpStan\SymfonyProcessRule
tags:
- phpstan.rules.rule
-
class: SlamPhpStan\MissingClosureParameterTypehintRule
tags:
- phpstan.rules.rule
37 changes: 37 additions & 0 deletions lib/MissingClosureParameterTypehintRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace SlamPhpStan;

use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;

final class MissingClosureParameterTypehintRule implements Rule
{
public function getNodeType(): string
{
return \PhpParser\Node\Expr\Closure::class;
}

/**
* @param \PhpParser\Node\Expr\Closure $node
*
* @return string[] errors
*/
public function processNode(Node $node, Scope $scope): array
{
$messages = [];

foreach ($node->params as $index => $param) {
if (null !== $param->type || ! $param->var instanceof Node\Expr\Variable || ! \is_string($param->var->name)) {
continue;
}

$messages[] = \sprintf('Parameter #%d $%s of anonymous function has no typehint.', 1 + $index, $param->var->name);
}

return $messages;
}
}
39 changes: 39 additions & 0 deletions tests/MissingClosureParameterTypehintRuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace SlamPhpStan\Tests;

use PHPStan\Rules\Rule;
use PHPStan\Testing\RuleTestCase;
use SlamPhpStan\MissingClosureParameterTypehintRule;

/**
* @covers \SlamPhpStan\MissingClosureParameterTypehintRule
*/
final class MissingClosureParameterTypehintRuleTest extends RuleTestCase
{
protected function getRule(): Rule
{
return new MissingClosureParameterTypehintRule();
}

public function testClassConstant()
{
$this->analyse(
[
__DIR__ . '/TestAsset/MissingClosureParameterTypehintRule/fixture.php',
],
[
[
'Parameter #1 $class of anonymous function has no typehint.',
7,
],
[
'Parameter #2 $int of anonymous function has no typehint.',
8,
],
]
);
}
}
10 changes: 10 additions & 0 deletions tests/TestAsset/MissingClosureParameterTypehintRule/fixture.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace SlamPhpStan\Tests\TestAsset\MissingClosureParameterTypehintRule;

function foo($ref) {}

$foo1 = function ($class) {};
$foo2 = function (array $array, $int = null) {};
$foo3 = function (\stdClass $class) {};
$foo4 = function (?int $int) {};

0 comments on commit ad85547

Please sign in to comment.