From 0118bb10c332c6205ecc534c1909c89f2806f615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Andr=C3=A9?= Date: Wed, 17 Apr 2024 06:00:48 +0200 Subject: [PATCH] Fix EnsureExplicitNullableTypes Improve the regexp pattern to * allow "mixed" * allow fqcn (\Foo) & aliases (Foo\Bar) Improve line number reporting (replace #1714) --- src/Rule/EnsureExplicitNullableTypes.php | 9 ++++++++- .../Rule/EnsureExplicitNullableTypesTest.php | 19 ++++++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/Rule/EnsureExplicitNullableTypes.php b/src/Rule/EnsureExplicitNullableTypes.php index abf9792b..78005c90 100644 --- a/src/Rule/EnsureExplicitNullableTypes.php +++ b/src/Rule/EnsureExplicitNullableTypes.php @@ -48,13 +48,15 @@ public function check(Lines $lines, int $number, string $filename): ViolationInt $lines->next(); while ($lines->valid() && !$lines->current()->isDirective()) { + ++$number; + if (!str_contains((string) $lines->current()->clean(), ' = null')) { $lines->next(); continue; } - $pattern = '/([?]?\w+)\s+\$(\w+)\s*=\s*null(?=\s*[,\)])/'; + $pattern = '#((?:\??\\\\?\w+[|]?)+)\s+\$(\w+)\s*=\s*null(?=\s*[,\)])#siu'; if ($matches = $lines->current()->clean()->match($pattern, \PREG_SET_ORDER)) { foreach ($matches as $match) { @@ -65,6 +67,11 @@ public function check(Lines $lines, int $number, string $filename): ViolationInt continue; } + // mixed $id = null + if ('mixed' === $types) { + continue; + } + // int|string|null $id = null $types = explode('|', $types); diff --git a/tests/Rule/EnsureExplicitNullableTypesTest.php b/tests/Rule/EnsureExplicitNullableTypesTest.php index 4f3f3e3b..229b61c2 100644 --- a/tests/Rule/EnsureExplicitNullableTypesTest.php +++ b/tests/Rule/EnsureExplicitNullableTypesTest.php @@ -44,6 +44,10 @@ public static function validProvider(): iterable $validCases = [ 'function foo(int $bar = 23)', 'function foo(?int $bar = null)', + 'function foo(?\\Throwable $exception = null)', + 'function foo(\\Throwable|null $exception = null)', + 'function foo(?Foo\\Bar $bar = null)', + 'function foo(mixed $bar = null)', 'function foo(int|null $bar = null)', 'function foo(int|string|null $bar = null)', ]; @@ -51,7 +55,10 @@ public static function validProvider(): iterable foreach ($validCases as $validCase) { yield $validCase => [ NullViolation::create(), - new RstSample(['.. code-block:: php', $validCase]), + new RstSample([ + '.. code-block:: php', + ' '.$validCase, + ]), ]; } } @@ -63,6 +70,9 @@ public static function invalidProvider(): iterable { $invalidCases = [ 'public function foo(int $bar = null)', + 'public function foo(Throwable $bar = null)', + 'public function foo(Foo\\Bar $bar = null)', + 'public function foo(\\Throwable $bar = null)', 'public function foo(int|string $bar = null)', 'function foo(int $foo, int $bar = null)', 'function foo(int $foo, int $bar = null, int $baz)', @@ -76,10 +86,13 @@ public static function invalidProvider(): iterable Violation::from( 'Please use explicit nullable types.', 'filename', - 1, + 2, $invalidCase, ), - new RstSample(['.. code-block:: php', $invalidCase]), + new RstSample([ + '.. code-block:: php', + ' '.$invalidCase, + ]), ]; } }