diff --git a/src/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php b/src/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php index ba3e1710f0..6d349eaf7a 100644 --- a/src/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php +++ b/src/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php @@ -306,16 +306,47 @@ protected function processParams(File $phpcsFile, $stackPtr, $commentStart) $varSpace = 0; $comment = ''; $commentLines = []; + $isMultiLine = false; if ($tokens[($tag + 2)]['code'] === T_DOC_COMMENT_STRING) { + $content = $tokens[($tag + 2)]['content']; + + $multiLineExtra = 0; + + if ($this->parenthesisClosed($content, '{', '}') === false + || $this->parenthesisClosed($content, '<', '>') === false + ) { + $isMultiLine = true; + $content = ''; + + $i = ($tag + 2); + + while (true) { + if ($tokens[$i]['content'] === '@param') { + break; + } + + $content .= $tokens[$i]['content']; + + if ($this->parenthesisClosed($content, '{', '}') === true + && $this->parenthesisClosed($content, '<', '>') === true + ) { + break; + } + + $multiLineExtra++; + $i++; + } + }//end if + $matches = []; - preg_match('/([^$&.]+)(?:((?:\.\.\.)?(?:\$|&)[^\s]+)(?:(\s+)(.*))?)?/', $tokens[($tag + 2)]['content'], $matches); + preg_match('/([^$&.]+)(?:((?:\.\.\.)?(?:\$|&)[^\s]+)(?:(\s+)(.*))?)?/', $content, $matches); if (empty($matches) === false) { $typeLen = strlen($matches[1]); $type = trim($matches[1]); $typeSpace = ($typeLen - strlen($type)); $typeLen = strlen($type); - if ($typeLen > $maxType) { + if ($typeLen > $maxType && $isMultiLine === false) { $maxType = $typeLen; } } @@ -323,7 +354,7 @@ protected function processParams(File $phpcsFile, $stackPtr, $commentStart) if (isset($matches[2]) === true) { $var = $matches[2]; $varLen = strlen($var); - if ($varLen > $maxVar) { + if ($varLen > $maxVar && $isMultiLine === false) { $maxVar = $varLen; } @@ -332,7 +363,7 @@ protected function processParams(File $phpcsFile, $stackPtr, $commentStart) $comment = $matches[4]; $commentLines[] = [ 'comment' => $comment, - 'token' => ($tag + 2), + 'token' => ($tag + 2 + $multiLineExtra), 'indent' => $varSpace, ]; @@ -343,7 +374,7 @@ protected function processParams(File $phpcsFile, $stackPtr, $commentStart) $end = $tokens[$commentStart]['comment_closer']; } - for ($i = ($tag + 3); $i < $end; $i++) { + for ($i = ($tag + 3 + $multiLineExtra); $i < $end; $i++) { if ($tokens[$i]['code'] === T_DOC_COMMENT_STRING) { $indent = 0; if ($tokens[($i - 1)]['code'] === T_DOC_COMMENT_WHITESPACE) { @@ -380,6 +411,7 @@ protected function processParams(File $phpcsFile, $stackPtr, $commentStart) 'commentLines' => $commentLines, 'type_space' => $typeSpace, 'var_space' => $varSpace, + 'multi_line' => $isMultiLine, ]; }//end foreach @@ -547,7 +579,9 @@ protected function processParams(File $phpcsFile, $stackPtr, $commentStart) $foundParams[] = $param['var']; // Check number of spaces after the type. - $this->checkSpacingAfterParamType($phpcsFile, $param, $maxType); + if ($param['multi_line'] === false) { + $this->checkSpacingAfterParamType($phpcsFile, $param, $maxType); + } // Make sure the param name is correct. if (isset($realParams[$pos]) === true) { @@ -580,7 +614,9 @@ protected function processParams(File $phpcsFile, $stackPtr, $commentStart) } // Check number of spaces after the var name. - $this->checkSpacingAfterParamName($phpcsFile, $param, $maxVar); + if ($param['multi_line'] === false) { + $this->checkSpacingAfterParamName($phpcsFile, $param, $maxVar); + } // Param comments must start with a capital letter and end with a full stop. if (preg_match('/^(\p{Ll}|\P{L})/u', $param['comment']) === 1) { @@ -765,4 +801,27 @@ protected function checkInheritdoc(File $phpcsFile, $stackPtr, $commentStart) }//end checkInheritdoc() + /** + * Determines wether string has the same number of open and close parenthesis. + * + * @param string $string String to check + * @param string $openChar Opening character. + * @param string $closeChar Closing character. + * + * @return bool + */ + private function parenthesisClosed($string, $openChar, $closeChar) + { + if (stripos($string, $openChar) === false) { + return true; + } + + $open = substr_count($string, $openChar); + $close = substr_count($string, $closeChar); + + return $open === $close; + + }//end parenthesisClosed() + + }//end class diff --git a/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc b/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc index 4f59f60b71..12392ab8ba 100644 --- a/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc +++ b/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc @@ -1046,3 +1046,20 @@ public function ignored() { * @return void * @throws Exception If any other error occurs. */ function throwCommentOneLine() {} + + +/** + * @param array{foo: int} $a A. + * @param array{x: int} $ccc C. + * @param array{xxxx: int} $dddd D. + * @param array $bb B. + * + * @return integer + */ +public function multiLineArray(array $a, array $ccc, array $dddd, array $bb) +{ + return 1; +}//end multiLineArray() diff --git a/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc.fixed b/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc.fixed index 21a4103eb5..1134310a07 100644 --- a/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc.fixed +++ b/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc.fixed @@ -1046,3 +1046,20 @@ public function ignored() { * @return void * @throws Exception If any other error occurs. */ function throwCommentOneLine() {} + + +/** + * @param array{foo: int} $a A. + * @param array{x: int} $ccc C. + * @param array{xxxx: int} $dddd D. + * @param array $bb B. + * + * @return integer + */ +public function multiLineArray(array $a, array $ccc, array $dddd, array $bb) +{ + return 1; +}//end multiLineArray() diff --git a/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.php b/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.php index 632b7c51b2..63a50b928e 100644 --- a/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.php +++ b/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.php @@ -116,6 +116,8 @@ public function getErrorList() 1004 => 2, 1006 => 1, 1029 => 1, + 1052 => 2, + 1053 => 2, ]; // Scalar type hints only work from PHP 7 onwards.