From d6f960b20c022dea76f3e216e650f707fc82efe4 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 5 Mar 2021 03:50:37 +0100 Subject: [PATCH] PHP 8.0 | Squiz/ScopeKeywordSpacing: add support for constructor property promotion Prevent the sniff from ignoring the spacing after the scope keyword in case of PHP 8.0 constructor property promotion. As it was, the sniff would presume "normal" property syntax, which meant that in the case of constructor property promotion in a multi-line constructor declaration, the sniff would look for a semicolon to end the statement and bow out when the semicolon wasn't found. By explicitly checking for constructor property promotion and skipping the next above mentioned check in that case, we ensure that scope keywords in constructors are still handled correctly. Includes tests. --- .../WhiteSpace/ScopeKeywordSpacingSniff.php | 18 +++++++++++++++++- .../WhiteSpace/ScopeKeywordSpacingUnitTest.inc | 14 ++++++++++++++ .../ScopeKeywordSpacingUnitTest.inc.fixed | 14 ++++++++++++++ .../WhiteSpace/ScopeKeywordSpacingUnitTest.php | 3 +++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/Standards/Squiz/Sniffs/WhiteSpace/ScopeKeywordSpacingSniff.php b/src/Standards/Squiz/Sniffs/WhiteSpace/ScopeKeywordSpacingSniff.php index de92697db0..8c5b89446f 100644 --- a/src/Standards/Squiz/Sniffs/WhiteSpace/ScopeKeywordSpacingSniff.php +++ b/src/Standards/Squiz/Sniffs/WhiteSpace/ScopeKeywordSpacingSniff.php @@ -84,7 +84,23 @@ public function process(File $phpcsFile, $stackPtr) return; } - if ($nextToken !== false && $tokens[$nextToken]['code'] === T_VARIABLE) { + $isInFunctionDeclaration = false; + if (empty($tokens[$stackPtr]['nested_parenthesis']) === false) { + // Check if this is PHP 8.0 constructor property promotion. + // In that case, we can't have multi-property definitions. + $nestedParens = $tokens[$stackPtr]['nested_parenthesis']; + $lastCloseParens = end($nestedParens); + if (isset($tokens[$lastCloseParens]['parenthesis_owner']) === true + && $tokens[$tokens[$lastCloseParens]['parenthesis_owner']]['code'] === T_FUNCTION + ) { + $isInFunctionDeclaration = true; + } + } + + if ($nextToken !== false + && $tokens[$nextToken]['code'] === T_VARIABLE + && $isInFunctionDeclaration === false + ) { $endOfStatement = $phpcsFile->findNext(T_SEMICOLON, ($nextToken + 1)); if ($endOfStatement === false) { // Live coding. diff --git a/src/Standards/Squiz/Tests/WhiteSpace/ScopeKeywordSpacingUnitTest.inc b/src/Standards/Squiz/Tests/WhiteSpace/ScopeKeywordSpacingUnitTest.inc index 8295d1a9de..d8f21c4e1d 100644 --- a/src/Standards/Squiz/Tests/WhiteSpace/ScopeKeywordSpacingUnitTest.inc +++ b/src/Standards/Squiz/Tests/WhiteSpace/ScopeKeywordSpacingUnitTest.inc @@ -107,3 +107,17 @@ class TypedProperties { $boolA, $boolB; } + +// PHP 8.0 constructor property promotion. +class ConstructorPropertyPromotionTest { + public function __construct( + public $x = 0.0, + protected $y = '', + private $z = null, + $normalParam, + ) {} +} + +class ConstructorPropertyPromotionWithTypesTest { + public function __construct(protected float|int $x, public?string &$y = 'test', private mixed $z) {} +} diff --git a/src/Standards/Squiz/Tests/WhiteSpace/ScopeKeywordSpacingUnitTest.inc.fixed b/src/Standards/Squiz/Tests/WhiteSpace/ScopeKeywordSpacingUnitTest.inc.fixed index f5ed55bd54..daae2bca38 100644 --- a/src/Standards/Squiz/Tests/WhiteSpace/ScopeKeywordSpacingUnitTest.inc.fixed +++ b/src/Standards/Squiz/Tests/WhiteSpace/ScopeKeywordSpacingUnitTest.inc.fixed @@ -101,3 +101,17 @@ class TypedProperties { $boolA, $boolB; } + +// PHP 8.0 constructor property promotion. +class ConstructorPropertyPromotionTest { + public function __construct( + public $x = 0.0, + protected $y = '', + private $z = null, + $normalParam, + ) {} +} + +class ConstructorPropertyPromotionWithTypesTest { + public function __construct(protected float|int $x, public ?string &$y = 'test', private mixed $z) {} +} diff --git a/src/Standards/Squiz/Tests/WhiteSpace/ScopeKeywordSpacingUnitTest.php b/src/Standards/Squiz/Tests/WhiteSpace/ScopeKeywordSpacingUnitTest.php index bbccf1c88b..9b91298755 100644 --- a/src/Standards/Squiz/Tests/WhiteSpace/ScopeKeywordSpacingUnitTest.php +++ b/src/Standards/Squiz/Tests/WhiteSpace/ScopeKeywordSpacingUnitTest.php @@ -41,6 +41,9 @@ public function getErrorList() 98 => 1, 101 => 1, 106 => 1, + 114 => 1, + 116 => 1, + 122 => 2, ]; }//end getErrorList()