From 13c5372ebdbb7a5e803ffdbad0639fd1808b1d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Sat, 24 Nov 2018 14:35:05 +0100 Subject: [PATCH] Enhancement: Implement Closures\NoParameterWithNullDefaultValueRule --- .php_cs.fixture | 1 + .travis.yml | 2 +- CHANGELOG.md | 2 + Makefile | 2 +- README.md | 12 +++ .../NoParameterWithNullDefaultValueRule.php | 64 +++++++++++++++ ...with-parameter-with-null-default-value.php | 9 +++ ...amespace-referenced-null-default-value.php | 9 +++ ...wrongly-capitalized-null-default-value.php | 9 +++ ...-parameter-with-non-null-default-value.php | 9 +++ ...e-with-parameter-without-default-value.php | 9 +++ .../Success/closure-without-parameters.php | 8 ++ ...oParameterWithNullDefaultValueRuleTest.php | 78 +++++++++++++++++++ 13 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 src/Closures/NoParameterWithNullDefaultValueRule.php create mode 100644 test/Fixture/Closures/NoParameterWithNullDefaultValueRule/Failure/closure-with-parameter-with-null-default-value.php create mode 100644 test/Fixture/Closures/NoParameterWithNullDefaultValueRule/Failure/closure-with-parameter-with-root-namespace-referenced-null-default-value.php create mode 100644 test/Fixture/Closures/NoParameterWithNullDefaultValueRule/Failure/closure-with-parameter-with-wrongly-capitalized-null-default-value.php create mode 100644 test/Fixture/Closures/NoParameterWithNullDefaultValueRule/Success/closure-with-parameter-with-non-null-default-value.php create mode 100644 test/Fixture/Closures/NoParameterWithNullDefaultValueRule/Success/closure-with-parameter-without-default-value.php create mode 100644 test/Fixture/Closures/NoParameterWithNullDefaultValueRule/Success/closure-without-parameters.php create mode 100644 test/Integration/Closures/NoParameterWithNullDefaultValueRuleTest.php diff --git a/.php_cs.fixture b/.php_cs.fixture index d65a5c07..9a5dd205 100644 --- a/.php_cs.fixture +++ b/.php_cs.fixture @@ -3,6 +3,7 @@ use Localheinz\PhpCsFixer\Config; $config = Config\Factory::fromRuleSet(new Config\RuleSet\Php71(''), [ + 'lowercase_constants' => false, 'static_lambda' => false, ]); diff --git a/.travis.yml b/.travis.yml index b7cd3f9c..a283f5bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 diff --git a/CHANGELOG.md b/CHANGELOG.md index 81388c29..fd2eea1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/Makefile b/Makefile index 5b74f73d..e3b4e17a 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/README.md b/README.md index 37a22eef..baa26c81 100644 --- a/README.md +++ b/README.md @@ -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) @@ -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. diff --git a/src/Closures/NoParameterWithNullDefaultValueRule.php b/src/Closures/NoParameterWithNullDefaultValueRule.php new file mode 100644 index 00000000..0acd7d62 --- /dev/null +++ b/src/Closures/NoParameterWithNullDefaultValueRule.php @@ -0,0 +1,64 @@ +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); + } +} diff --git a/test/Fixture/Closures/NoParameterWithNullDefaultValueRule/Failure/closure-with-parameter-with-null-default-value.php b/test/Fixture/Closures/NoParameterWithNullDefaultValueRule/Failure/closure-with-parameter-with-null-default-value.php new file mode 100644 index 00000000..ca6cb592 --- /dev/null +++ b/test/Fixture/Closures/NoParameterWithNullDefaultValueRule/Failure/closure-with-parameter-with-null-default-value.php @@ -0,0 +1,9 @@ + __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(); + } +}