diff --git a/src/WebimpressCodingStandard/Sniffs/PHP/DisallowFqnSniff.php b/src/WebimpressCodingStandard/Sniffs/PHP/DisallowFqnSniff.php index 845f86d..5ffc1de 100644 --- a/src/WebimpressCodingStandard/Sniffs/PHP/DisallowFqnSniff.php +++ b/src/WebimpressCodingStandard/Sniffs/PHP/DisallowFqnSniff.php @@ -38,40 +38,33 @@ use const GLOB_NOSORT; use const T_BITWISE_AND; use const T_BITWISE_OR; -use const T_CASE; use const T_CATCH; use const T_CLOSE_PARENTHESIS; use const T_CLOSURE; use const T_COLON; -use const T_COMMA; use const T_DOC_COMMENT_STRING; use const T_DOC_COMMENT_TAG; use const T_DOC_COMMENT_WHITESPACE; use const T_DOUBLE_COLON; -use const T_ECHO; use const T_ELLIPSIS; use const T_EXTENDS; use const T_FN; use const T_FUNCTION; use const T_IMPLEMENTS; -use const T_INCLUDE; -use const T_INCLUDE_ONCE; use const T_INSTANCEOF; use const T_INSTEADOF; -use const T_LOGICAL_AND; -use const T_LOGICAL_OR; -use const T_LOGICAL_XOR; use const T_NAMESPACE; use const T_NEW; use const T_NS_SEPARATOR; use const T_NULLABLE; +use const T_OPEN_CURLY_BRACKET; use const T_OPEN_PARENTHESIS; -use const T_PRINT; -use const T_REQUIRE; -use const T_REQUIRE_ONCE; -use const T_RETURN; +use const T_SEMICOLON; use const T_STRING; -use const T_THROW; +use const T_TYPE_CLOSE_PARENTHESIS; +use const T_TYPE_INTERSECTION; +use const T_TYPE_OPEN_PARENTHESIS; +use const T_TYPE_UNION; use const T_USE; use const T_VARIABLE; @@ -332,10 +325,23 @@ private function processString( ]; if (in_array($tokens[$prev]['code'], $prevClassTokens, true) - || in_array($tokens[$next]['code'], [T_VARIABLE, T_ELLIPSIS, T_DOUBLE_COLON], true) + || in_array($tokens[$next]['code'], [ + T_VARIABLE, + T_ELLIPSIS, + T_DOUBLE_COLON, + // DNF + T_TYPE_UNION, + T_TYPE_INTERSECTION, + T_TYPE_CLOSE_PARENTHESIS, + T_OPEN_CURLY_BRACKET, + ], true) ) { $type = 'class'; - } elseif ($tokens[$next]['code'] === T_OPEN_PARENTHESIS) { + } elseif ($tokens[$next]['code'] === T_OPEN_PARENTHESIS + // The below condition is temporary due to upstream issue + // @see https://github.com/PHPCSStandards/PHP_CodeSniffer/issues/630 + || $tokens[$next]['code'] === T_TYPE_OPEN_PARENTHESIS + ) { $type = 'function'; } else { $type = 'const'; @@ -362,15 +368,10 @@ private function processString( ) { $type = 'class'; } - } elseif ($tokens[$prev]['code'] === T_COMMA) { - $before = $phpcsFile->findPrevious( - Tokens::$emptyTokens + [T_STRING => T_STRING, T_NS_SEPARATOR => T_NS_SEPARATOR], - $prev - 1, - null, - true - ); - - if ($tokens[$before]['code'] === T_IMPLEMENTS) { + } elseif ($tokens[$next]['code'] === T_SEMICOLON) { + $before = $phpcsFile->findPrevious(Tokens::$emptyTokens, $prev, null, true); + + if (in_array($tokens[$before]['code'], [T_TYPE_UNION, T_TYPE_INTERSECTION], true)) { $type = 'class'; } } @@ -553,29 +554,6 @@ private function fixError(File $phpcsFile, int $stackPtr, string $expected) : vo return; } - if (in_array($tokens[$stackPtr - 1]['code'], [ - T_NEW, - T_USE, - T_EXTENDS, - T_IMPLEMENTS, - T_INSTANCEOF, - T_INSTEADOF, - T_CASE, - T_PRINT, - T_ECHO, - T_REQUIRE, - T_REQUIRE_ONCE, - T_INCLUDE, - T_INCLUDE_ONCE, - T_RETURN, - T_LOGICAL_AND, - T_LOGICAL_OR, - T_LOGICAL_XOR, - T_THROW, - ], true)) { - $expected = ' ' . $expected; - } - $phpcsFile->fixer->replaceToken($stackPtr, $expected); $i = $stackPtr; while (isset($tokens[++$i])) { diff --git a/test/Sniffs/PHP/DisallowFqnUnitTest.inc b/test/Sniffs/PHP/DisallowFqnUnitTest.inc index 48b9ead..a1ad588 100644 --- a/test/Sniffs/PHP/DisallowFqnUnitTest.inc +++ b/test/Sniffs/PHP/DisallowFqnUnitTest.inc @@ -179,4 +179,17 @@ class TheClass extends \ MyNamespace \ Hello \ ParentClass implements \ArrayAcce new \MyNamespace\Foo1\Bar1\Bar2(); new \Foo\BarBaz\Bar3(); } + + public function method3(): \DNF\Type1|(\DNF\Type2&\DNF\Type3) + { + } + + public function method4(): (\DNF\Type4|\DNF\Type5)&\DNF\Type6 + { + } + + abstract public function method5(): (\DNF\Type7|\DNF\Type8)&\DNF\Type9; + + private \DNF\Type10&(\DNF\Type11|\DNF\Type12) $prop1; + private (\DNF\Type13&\DNF\Type14)|\DNF\Type15 $prop2; } diff --git a/test/Sniffs/PHP/DisallowFqnUnitTest.inc.fixed b/test/Sniffs/PHP/DisallowFqnUnitTest.inc.fixed index 4ec3939..5aa1cbc 100644 --- a/test/Sniffs/PHP/DisallowFqnUnitTest.inc.fixed +++ b/test/Sniffs/PHP/DisallowFqnUnitTest.inc.fixed @@ -6,7 +6,7 @@ use ArrayAccess; use Countable; use DateTime; use InClosure\Param; -use const InClosure\ReturnType; +use InClosure\ReturnType; use const InClosure\CONST_IN_CLOSURE; use function InClosure\functionInClosure; use RuntimeException; @@ -29,6 +29,21 @@ use B; use InFnClosure\Param1; use InFnClosure\ReturnType1; use MyNamespace\Foo1\Bar1; +use DNF\Type1; +use DNF\Type2; +use DNF\Type3; +use DNF\Type4; +use DNF\Type5; +use DNF\Type6; +use DNF\Type7; +use DNF\Type8; +use DNF\Type9; +use DNF\Type10; +use DNF\Type11; +use DNF\Type12; +use DNF\Type13; +use DNF\Type14; +use DNF\Type15; use \ArrayObject as AO; use Foo\BarBaz; @@ -207,4 +222,17 @@ class TheClass extends ParentClass implements ArrayAccess, Countable new Bar1\Bar2(); new BarBaz\Bar3(); } + + public function method3(): Type1|(Type2&Type3) + { + } + + public function method4(): (Type4|Type5)&Type6 + { + } + + abstract public function method5(): (Type7|Type8)&Type9; + + private Type10&(Type11|Type12) $prop1; + private (Type13&Type14)|Type15 $prop2; } diff --git a/test/Sniffs/PHP/DisallowFqnUnitTest.php b/test/Sniffs/PHP/DisallowFqnUnitTest.php index f6f7164..74ff990 100644 --- a/test/Sniffs/PHP/DisallowFqnUnitTest.php +++ b/test/Sniffs/PHP/DisallowFqnUnitTest.php @@ -103,6 +103,11 @@ protected function getErrorList(string $testFile = '') : array 178 => 1, 179 => 1, 180 => 1, + 183 => 3, + 187 => 3, + 191 => 3, + 193 => 3, + 194 => 3, ]; }