diff --git a/Magento2/Sniffs/Commenting/ClassAndInterfacePHPDocFormattingSniff.php b/Magento2/Sniffs/Commenting/ClassAndInterfacePHPDocFormattingSniff.php index d890147d..57204cdb 100644 --- a/Magento2/Sniffs/Commenting/ClassAndInterfacePHPDocFormattingSniff.php +++ b/Magento2/Sniffs/Commenting/ClassAndInterfacePHPDocFormattingSniff.php @@ -72,6 +72,16 @@ public function process(File $phpcsFile, $stackPtr) ); } + if ($this->PHPDocFormattingValidator->hasDeprecatedWellFormatted($commentStartPtr, $tokens) !== true) { + $phpcsFile->addWarning( + 'Motivation behind the added @deprecated tag MUST be explained. ' + . '@see tag MUST be used with reference to new implementation when code is deprecated ' + . 'and there is a new alternative.', + $stackPtr, + 'InvalidDeprecatedTagUsage' + ); + } + $this->validateTags($phpcsFile, $commentStartPtr, $tokens); } diff --git a/Magento2/Sniffs/Commenting/ConstantsPHPDocFormattingSniff.php b/Magento2/Sniffs/Commenting/ConstantsPHPDocFormattingSniff.php index a4b9e71b..c18857ac 100644 --- a/Magento2/Sniffs/Commenting/ConstantsPHPDocFormattingSniff.php +++ b/Magento2/Sniffs/Commenting/ConstantsPHPDocFormattingSniff.php @@ -71,5 +71,15 @@ public function process(File $phpcsFile, $stackPtr) 'MissingConstantPHPDoc' ); } + + if ($this->PHPDocFormattingValidator->hasDeprecatedWellFormatted($commentStartPtr, $tokens) !== true) { + $phpcsFile->addWarning( + 'Motivation behind the added @deprecated tag MUST be explained. ' + . '@see tag MUST be used with reference to new implementation when code is deprecated ' + . 'and there is a new alternative.', + $stackPtr, + 'InvalidDeprecatedTagUsage' + ); + } } } diff --git a/Magento2/Sniffs/Commenting/PHPDocFormattingValidator.php b/Magento2/Sniffs/Commenting/PHPDocFormattingValidator.php index 5be093ae..cafdbf70 100644 --- a/Magento2/Sniffs/Commenting/PHPDocFormattingValidator.php +++ b/Magento2/Sniffs/Commenting/PHPDocFormattingValidator.php @@ -107,4 +107,59 @@ public function providesMeaning($namePtr, $commentStartPtr, $tokens) return false; } + + /** + * In case comment has deprecated tag, it must be explained and followed by see tag with details + * + * @param int $commentStartPtr + * @param array $tokens + * @return bool + */ + public function hasDeprecatedWellFormatted($commentStartPtr, $tokens) + { + $deprecatedPtr = $this->getTagPosition('@deprecated', $commentStartPtr, $tokens); + if ($deprecatedPtr === -1) { + return true; + } + + if ($tokens[$deprecatedPtr + 2]['code'] !== T_DOC_COMMENT_STRING) { + return false; + } + + $seePtr = $this->getTagPosition('@see', $commentStartPtr, $tokens); + if ($seePtr === -1) { + return true; + } + if ($tokens[$seePtr + 2]['code'] !== T_DOC_COMMENT_STRING) { + return false; + } + + return true; + } + + /** + * Searches for tag within comment + * + * @param string $tag + * @param int $commentStartPtr + * @param array $tokens + * @return int + */ + private function getTagPosition($tag, $commentStartPtr, $tokens) + { + $commentCloserPtr = $tokens[$commentStartPtr]['comment_closer']; + + for ($i = $commentStartPtr; $i <= $commentCloserPtr; $i++) { + $token = $tokens[$i]; + + // Not interesting + if ($token['code'] !== T_DOC_COMMENT_TAG || $token['content'] !== $tag) { + continue; + } + + return $i; + } + + return -1; + } } diff --git a/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.1.inc b/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.1.inc index 81cfa9bc..14ba369a 100644 --- a/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.1.inc +++ b/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.1.inc @@ -59,6 +59,7 @@ class EmptyHandler * * @api is ok here * @deprecated can be used in this context + * @see is ok here * @author is actually ok * @category is irrelevant * @package is not ment to be used @@ -90,4 +91,65 @@ class AsyncApiHandler * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class GroupRepositoryHandler -{} +{ + +} + +/** + * @deprecated + */ +class DeprecatedHandler +{ + +} + +/** + * @deprecated Should not be used + */ +class AncientHandler +{ + +} + +/** + * @deprecated + * @see + */ +class AgedHandler +{ + +} + +/** + * @deprecated Should not be used + * @see + */ +class ArhaicHandler +{ + +} + +/** + * @deprecated Should not be used + * @see Magento\Framework\NewHandler + */ +class OldHandler +{ + +} + +/** + * @see Magento\Framework\NewHandler + */ +class SomethingHandler +{ + +} + +/** + * @see + */ +class DoNotCareHandler +{ + +} diff --git a/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.2.inc b/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.2.inc index 7a9c9b6a..96900de2 100644 --- a/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.2.inc +++ b/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.2.inc @@ -59,6 +59,7 @@ interface EmptyHandler * * @api is ok here * @deprecated can be used in this context + * @see is ok here * @author is actually ok * @category is irrelevant * @package is not ment to be used @@ -89,5 +90,66 @@ interface AsyncApiHandler /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class GroupRepositoryHandler -{} +interface GroupRepositoryHandler +{ + +} + +/** + * @deprecated + */ +interface DeprecatedHandler +{ + +} + +/** + * @deprecated Should not be used + */ +interface AncientHandler +{ + +} + +/** + * @deprecated + * @see + */ +interface AgedHandler +{ + +} + +/** + * @deprecated Should not be used + * @see + */ +interface ArhaicHandler +{ + +} + +/** + * @deprecated Should not be used + * @see Magento\Framework\NewHandler + */ +interface OldHandler +{ + +} + +/** + * @see Magento\Framework\NewHandler + */ +interface SomethingHandler +{ + +} + +/** + * @see + */ +interface DoNotCareHandler +{ + +} diff --git a/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.php b/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.php index 477c1adf..959a1d09 100644 --- a/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.php +++ b/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.php @@ -29,9 +29,12 @@ public function getWarningList($testFile = '') 35 => 1, 44 => 1, 52 => 1, - 63 => 1, 64 => 1, 65 => 1, + 66 => 1, + 101 => 1, + 118 => 1, + 127 => 1, ]; } } diff --git a/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.1.inc b/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.1.inc index e3d2000a..05dfdb52 100644 --- a/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.1.inc +++ b/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.1.inc @@ -7,6 +7,17 @@ define('DS', DIRECTORY_SEPARATOR); define('BP', dirname(__FILE__)); +/** + * @deprecated It is a lie + */ +define('THERE IS', 'cake'); + +/** + * @deprecated New implementation available + * @see \Ascii\Asterisk + */ +define('ANSWER', '42'); + class Profiler { const NESTING_SEPARATOR = '->'; @@ -15,4 +26,20 @@ class Profiler * Unlike first const, this one is not self explanatory. */ const NUMBER_TWO = 2; + + /** + * @deprecated Why not + */ + const YES = false; + + /** + * @deprecated Unable to identify the question, replaced + * @see \ComputationalMatrix\Earth + */ + const COMPUTER = 'Deep Thought'; + + /** + * @see + */ + const SOMETHING = 'else'; } diff --git a/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.2.inc b/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.2.inc index c4189ff1..b413bc92 100644 --- a/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.2.inc +++ b/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.2.inc @@ -1,4 +1,5 @@ 0'); /** */ define('NUMBER_ONE', 1); +/** + * @deprecated + */ +define('A', 65); + +/** + * @deprecated + * @see + */ +define('C', 67); + +/** + * @deprecated No reference specified + * @see + */ +define('D', 68); + class Profiler { /** @@ -18,4 +36,21 @@ class Profiler * */ const NUMBER_TWO = 2; + + /** + * @deprecated + */ + const a = 97; + + /** + * @deprecated + * @see + */ + const c = 99; + + /** + * @deprecated No reference specified + * @see + */ + const d = 100; } diff --git a/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.php b/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.php index 612a3948..c5056dd7 100644 --- a/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.php +++ b/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.php @@ -27,10 +27,16 @@ public function getWarningList($testFile = '') } return [ - 5 => 1, - 8 => 1, - 15 => 1, - 20 => 1 + 6 => 1, + 9 => 1, + 14 => 1, + 20 => 1, + 26 => 1, + 33 => 1, + 38 => 1, + 43 => 1, + 49 => 1, + 55 => 1 ]; } }