Skip to content

Commit

Permalink
Enhancement: Implement Closures\NoParameterWithNullDefaultValueRule
Browse files Browse the repository at this point in the history
  • Loading branch information
localheinz committed Nov 24, 2018
1 parent 244a35f commit 13c5372
Show file tree
Hide file tree
Showing 13 changed files with 212 additions and 2 deletions.
1 change: 1 addition & 0 deletions .php_cs.fixture
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use Localheinz\PhpCsFixer\Config;

$config = Config\Factory::fromRuleSet(new Config\RuleSet\Php71(''), [
'lowercase_constants' => false,
'static_lambda' => false,
]);

Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ jobs:
- xdebug-enable

script:
- vendor/bin/infection --min-covered-msi=85 --min-msi=85
- vendor/bin/infection --min-covered-msi=90 --min-msi=90

notifications:
email: false
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ For a full diff see [`0.2.0...master`](https://github.com/localheinz/phpstan-rul
`Methods\NoNullableReturnTypeDeclarationRule`, which reports an error
when a method declared on an anonymous class, a class, or an interface has a
nullable return type declaration ([#16](https://github.com/localheinz/phpstan-rules/pull/16)), by [@localheinz](https://github.com/localheinz)
* added `Closures\NoParameterWithNullDefaultValueRule`, which reports an
error when a closure has a parameter with `null` as default value ([#26](https://github.com/localheinz/phpstan-rules/pull/26)), by [@localheinz](https://github.com/localheinz)
* added `Closures\NoNullableReturnTypeDeclarationRule`, which reports an
error when a closure has a nullable return type declaration ([#29](https://github.com/localheinz/phpstan-rules/pull/29)), by [@localheinz](https://github.com/localheinz)

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ cs: vendor
vendor/bin/php-cs-fixer fix --config=.php_cs.fixture --diff --verbose

infection: vendor
vendor/bin/infection --min-covered-msi=85 --min-msi=85
vendor/bin/infection --min-covered-msi=90 --min-msi=90

stan: vendor
vendor/bin/phpstan analyse --configuration=phpstan.neon --level=max src
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\NoParameterWithNullDefaultValueRule`](https://github.com/localheinz/phpstan-rules#closuresnoparameterwithnulldefaultvaluerule)
* [`Localheinz\PHPStan\Rules\Functions\NoNullableReturnTypeDeclarationRule`](https://github.com/localheinz/phpstan-rules#functionsnonullablereturntypedeclarationrule)
* [`Localheinz\PHPStan\Rules\Methods\NoNullableReturnTypeDeclarationRule`](https://github.com/localheinz/phpstan-rules#methodsnonullablereturntypedeclarationrule)

Expand Down Expand Up @@ -86,6 +87,17 @@ rules:
- Localheinz\PHPStan\Rules\Closures\NoNullableReturnTypeDeclarationRule
```

### `Closures\NoParameterWithNullDefaultValueRule`

This rule reports an error when a closure has a parameter with `null` as default value.

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

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

### `Functions\NoNullableReturnTypeDeclarationRule`

This rule reports an error when a function uses a nullable return type declaration.
Expand Down
64 changes: 64 additions & 0 deletions src/Closures/NoParameterWithNullDefaultValueRule.php
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\Closures;

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

final class NoParameterWithNullDefaultValueRule 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 {
if (!$node->default instanceof Node\Expr\ConstFetch) {
return false;
}

return 'null' === $node->default->name->toLowerString();
});

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 null as default value.',
$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 ($bar = null) {
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 = null) {
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 = null) {
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 = true) {
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,78 @@
<?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\NoParameterWithNullDefaultValueRule;
use Localheinz\PHPStan\Rules\Test\Integration\AbstractTestCase;
use PHPStan\Rules\Rule;

/**
* @internal
*/
final class NoParameterWithNullDefaultValueRuleTest extends AbstractTestCase
{
public function providerAnalysisSucceeds(): \Generator
{
$paths = [
'closure-with-parameter-with-non-null-default-value' => __DIR__ . '/../../Fixture/Closures/NoParameterWithNullDefaultValueRule/Success/closure-with-parameter-with-non-null-default-value.php',
'closure-with-parameter-without-default-value' => __DIR__ . '/../../Fixture/Closures/NoParameterWithNullDefaultValueRule/Success/closure-with-parameter-without-default-value.php',
'closure-with-parameter-without-parameters' => __DIR__ . '/../../Fixture/Closures/NoParameterWithNullDefaultValueRule/Success/closure-without-parameters.php',
];

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

public function providerAnalysisFails(): \Generator
{
$paths = [
'closure-with-parameter-with-null-default-value' => [
__DIR__ . '/../../Fixture/Closures/NoParameterWithNullDefaultValueRule/Failure/closure-with-parameter-with-null-default-value.php',
[
'Parameter "$bar" of closure should not have null as default value.',
7,
],
],
'closure-with-parameter-with-root-namespace-referenced-null-default-value' => [
__DIR__ . '/../../Fixture/Closures/NoParameterWithNullDefaultValueRule/Failure/closure-with-parameter-with-root-namespace-referenced-null-default-value.php',
[
'Parameter "$bar" of closure should not have null as default value.',
7,
],
],
'closure-with-parameter-with-wrongly-capitalized-null-default-value' => [
__DIR__ . '/../../Fixture/Closures/NoParameterWithNullDefaultValueRule/Failure/closure-with-parameter-with-wrongly-capitalized-null-default-value.php',
[
'Parameter "$bar" of closure should not have null as default value.',
7,
],
],
];

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

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

0 comments on commit 13c5372

Please sign in to comment.