Skip to content

Commit

Permalink
Merge pull request #33 from localheinz/feature/closure-no-parameter-w…
Browse files Browse the repository at this point in the history
…ith-nullable-type-declaration

Enhancement: Implement Closures\NoParameterWithNullableTypeDeclarationRule
  • Loading branch information
localheinz committed Nov 24, 2018
2 parents 161caaa + f5263d6 commit 3e9ca63
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ For a full diff see [`0.2.0...master`](https://github.com/localheinz/phpstan-rul
* added `Methods\NoParameterWithNullDefaultValueRule`, which reports an
error when a method declared on an anonymous class, a class, or an interface
has a parameter with `null` as default value ([#32](https://github.com/localheinz/phpstan-rules/pull/32)), by [@localheinz](https://github.com/localheinz)
* added `Closures\NoParameterWithNullableTypeDeclarationRule`, which reports an
error when a closure has a parameter with a nullable type declaration ([#33](https://github.com/localheinz/phpstan-rules/pull/33)), by [@localheinz](https://github.com/localheinz)

## [`0.2.0`](https://github.com/localheinz/phpstan-rules/releases/tag/0.2.0)

Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ This package provides the following rules for use with [`phpstan/phpstan`](https
* [`Localheinz\PHPStan\Rules\Classes\AbstractOrFinalRule`](https://github.com/localheinz/phpstan-rules#classesabstractorfinalrule)
* [`Localheinz\PHPStan\Rules\Classes\FinalRule`](https://github.com/localheinz/phpstan-rules#classesfinalrule)
* [`Localheinz\PHPStan\Rules\Closures\NoNullableReturnTypeDeclarationRule`](https://github.com/localheinz/phpstan-rules#closuresnonullablereturntypedeclarationrule)
* [`Localheinz\PHPStan\Rules\Closures\NoParameterWithNullableTypeDeclarationRule`](https://github.com/localheinz/phpstan-rules#closuresnoparameterwithnullabletypedeclarationrule)
* [`Localheinz\PHPStan\Rules\Closures\NoParameterWithNullDefaultValueRule`](https://github.com/localheinz/phpstan-rules#closuresnoparameterwithnulldefaultvaluerule)
* [`Localheinz\PHPStan\Rules\Functions\NoNullableReturnTypeDeclarationRule`](https://github.com/localheinz/phpstan-rules#functionsnonullablereturntypedeclarationrule)
* [`Localheinz\PHPStan\Rules\Functions\NoParameterWithNullDefaultValueRule`](https://github.com/localheinz/phpstan-rules#functionsnoparameterwithnulldefaultvaluerule)
Expand Down Expand Up @@ -89,6 +90,17 @@ rules:
- Localheinz\PHPStan\Rules\Closures\NoNullableReturnTypeDeclarationRule
```

### `Closures\NoParameterWithNullableTypeDeclarationRule`

This rule reports an error when a closure has a parameter with a nullable type declaration.

If you want to use this rule, add it to your `phpstan.neon`:

```neon
rules:
- Localheinz\PHPStan\Rules\Closures\NoParameterWithNullableTypeDeclarationRule
```

### `Closures\NoParameterWithNullDefaultValueRule`

This rule reports an error when a closure has a parameter with `null` as default value.
Expand Down
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ includes:
rules:
- Localheinz\PHPStan\Rules\Classes\AbstractOrFinalRule
- Localheinz\PHPStan\Rules\Closures\NoNullableReturnTypeDeclarationRule
- Localheinz\PHPStan\Rules\Closures\NoParameterWithNullableTypeDeclarationRule
- Localheinz\PHPStan\Rules\Functions\NoNullableReturnTypeDeclarationRule
- Localheinz\PHPStan\Rules\Functions\NoParameterWithNullDefaultValueRule
- Localheinz\PHPStan\Rules\Methods\NoNullableReturnTypeDeclarationRule
Expand Down
60 changes: 60 additions & 0 deletions src/Closures/NoParameterWithNullableTypeDeclarationRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2018 Andreas Möller.
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* @see https://github.com/localheinz/phpstan-rules
*/

namespace Localheinz\PHPStan\Rules\Closures;

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

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

/**
* @param Node\Expr\Closure $node
* @param Scope $scope
*
* @return array
*/
public function processNode(Node $node, Scope $scope): array
{
if (0 === \count($node->params)) {
return [];
}

$params = \array_filter($node->params, static function (Node\Param $node): bool {
return $node->type instanceof Node\NullableType;
});

if (0 === \count($params)) {
return [];
}

return \array_map(static function (Node\Param $node): string {
/** @var Node\Expr\Variable $variable */
$variable = $node->var;

/** @var string $parameterName */
$parameterName = $variable->name;

return \sprintf(
'Parameter "$%s" of closure should not have a nullable type declaration.',
$parameterName
);
}, $params);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Localheinz\PHPStan\Rules\Test\Fixture\Closures\NoParameterWithNullDefaultValueRule\Success;

$foo = function (?string $bar) {
return $bar;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Localheinz\PHPStan\Rules\Test\Fixture\Closures\NoParameterWithNullDefaultValueRule\Success;

$foo = function (string $bar) {
return $bar;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Localheinz\PHPStan\Rules\Test\Fixture\Closures\NoParameterWithNullDefaultValueRule\Success;

$foo = function ($bar) {
return $bar;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

declare(strict_types=1);

namespace Localheinz\PHPStan\Rules\Test\Fixture\Closures\NoParameterWithNullDefaultValueRule\Success;

$foo = function () {
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2018 Andreas Möller.
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* @see https://github.com/localheinz/phpstan-rules
*/

namespace Localheinz\PHPStan\Rules\Test\Integration\Closures;

use Localheinz\PHPStan\Rules\Closures\NoParameterWithNullableTypeDeclarationRule;
use Localheinz\PHPStan\Rules\Test\Integration\AbstractTestCase;
use PHPStan\Rules\Rule;

/**
* @internal
*/
final class NoParameterWithNullableTypeDeclarationRuleTest extends AbstractTestCase
{
public function providerAnalysisSucceeds(): \Generator
{
$paths = [
'closure-with-parameter-with-type-declaration' => __DIR__ . '/../../Fixture/Closures/NoParameterWithNullableTypeDeclarationRule/Success/closure-with-parameter-with-type-declaration.php',
'closure-with-parameter-without-type-declaration' => __DIR__ . '/../../Fixture/Closures/NoParameterWithNullableTypeDeclarationRule/Success/closure-with-parameter-without-type-declaration.php',
'closure-without-parameters' => __DIR__ . '/../../Fixture/Closures/NoParameterWithNullableTypeDeclarationRule/Success/closure-without-parameters.php',
];

foreach ($paths as $description => $path) {
yield $description => [
$path,
];
}
}

public function providerAnalysisFails(): \Generator
{
$paths = [
'closure-with-parameter-with-nullable-type-declaration' => [
__DIR__ . '/../../Fixture/Closures/NoParameterWithNullableTypeDeclarationRule/Failure/closure-with-parameter-with-nullable-type-declaration.php',
[
'Parameter "$bar" of closure should not have a nullable type declaration.',
7,
],
],
];

foreach ($paths as $description => [$path, $error]) {
yield $description => [
$path,
$error,
];
}
}

protected function getRule(): Rule
{
return new NoParameterWithNullableTypeDeclarationRule();
}
}

0 comments on commit 3e9ca63

Please sign in to comment.