From 13ceb9af4bdccb9caeef5136cdd406e99623f75e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stjepan=20Udovi=C4=8Di=C4=87?= Date: Thu, 22 Aug 2019 20:04:14 +0200 Subject: [PATCH] implement rule from #131 --- ...ClassAndInterfacePHPDocFormattingSniff.php | 9 +++ .../ConstantsPHPDocFormattingSniff.php | 9 +++ .../Commenting/PHPDocFormattingValidator.php | 50 ++++++++++++++++ ...AndInterfacePHPDocFormattingUnitTest.1.inc | 57 +++++++++++++++++- ...AndInterfacePHPDocFormattingUnitTest.2.inc | 58 ++++++++++++++++++- ...ssAndInterfacePHPDocFormattingUnitTest.php | 6 +- .../ConstantsPHPDocFormattingUnitTest.1.inc | 12 ++++ .../ConstantsPHPDocFormattingUnitTest.2.inc | 45 ++++++++++++++ .../ConstantsPHPDocFormattingUnitTest.php | 16 +++-- 9 files changed, 254 insertions(+), 8 deletions(-) diff --git a/Magento2/Sniffs/Commenting/ClassAndInterfacePHPDocFormattingSniff.php b/Magento2/Sniffs/Commenting/ClassAndInterfacePHPDocFormattingSniff.php index e3ed49b8..6eecabed 100644 --- a/Magento2/Sniffs/Commenting/ClassAndInterfacePHPDocFormattingSniff.php +++ b/Magento2/Sniffs/Commenting/ClassAndInterfacePHPDocFormattingSniff.php @@ -87,6 +87,15 @@ 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.', + $stackPtr, + 'InvalidDeprecatedTagUsage' + ); + } + $this->validateTags($phpcsFile, $commentStartPtr, $tokens); } diff --git a/Magento2/Sniffs/Commenting/ConstantsPHPDocFormattingSniff.php b/Magento2/Sniffs/Commenting/ConstantsPHPDocFormattingSniff.php index 205dcdf9..d922d050 100644 --- a/Magento2/Sniffs/Commenting/ConstantsPHPDocFormattingSniff.php +++ b/Magento2/Sniffs/Commenting/ConstantsPHPDocFormattingSniff.php @@ -71,5 +71,14 @@ 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.', + $stackPtr, + 'InvalidDeprecatedTagUsage' + ); + } } } diff --git a/Magento2/Sniffs/Commenting/PHPDocFormattingValidator.php b/Magento2/Sniffs/Commenting/PHPDocFormattingValidator.php index 4112f675..241a2dc9 100644 --- a/Magento2/Sniffs/Commenting/PHPDocFormattingValidator.php +++ b/Magento2/Sniffs/Commenting/PHPDocFormattingValidator.php @@ -71,4 +71,54 @@ 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) + { + $commentCloserPtr = $tokens[$commentStartPtr]['comment_closer']; + + $hasDeprecated = false; + $hasSee = false; + + for ($i = $commentStartPtr; $i <= $commentCloserPtr; $i++) { + $token = $tokens[$i]; + + // Not interesting + if ($token['code'] !== T_DOC_COMMENT_TAG) { + continue; + } + + $tag = $token['content']; + + // Not an interesting tag + if ($tag !== '@deprecated' && $tag !== '@see') { + continue; + } + + if ($tag === '@deprecated') { + $hasDeprecated = true; + } + + if ($tag === '@see') { + $hasSee = true; + } + + // Tag not followed by description + if ($tokens[$i + 2]['code'] !== T_DOC_COMMENT_STRING) { + return false; + } + } + + if ($hasDeprecated === true && $hasSee !== true) { + return false; + } + + return true; + } } diff --git a/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.1.inc b/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.1.inc index 81cfa9bc..bf47ae48 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,58 @@ 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 + */ +interface SomethingHandler +{ + +} + diff --git a/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.2.inc b/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.2.inc index 7a9c9b6a..75e7bbc3 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,58 @@ 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 +{ + +} diff --git a/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.php b/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.php index 477c1adf..9e7bfde2 100644 --- a/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.php +++ b/Magento2/Tests/Commenting/ClassAndInterfacePHPDocFormattingUnitTest.php @@ -29,9 +29,13 @@ public function getWarningList($testFile = '') 35 => 1, 44 => 1, 52 => 1, - 63 => 1, 64 => 1, 65 => 1, + 66 => 1, + 101 => 1, + 109 => 1, + 118 => 1, + 127 => 1, ]; } } diff --git a/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.1.inc b/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.1.inc index e3d2000a..f0e8b474 100644 --- a/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.1.inc +++ b/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.1.inc @@ -7,6 +7,12 @@ define('DS', DIRECTORY_SEPARATOR); define('BP', dirname(__FILE__)); +/** + * @deprecated New implementation available + * @see \Ascii\Asterisk + */ +define('ANSWER', '42'); + class Profiler { const NESTING_SEPARATOR = '->'; @@ -15,4 +21,10 @@ class Profiler * Unlike first const, this one is not self explanatory. */ const NUMBER_TWO = 2; + + /** + * @deprecated Unable to identify the question, replaced + * @see \ComputationalMatrix\Earth + */ + const COMPUTER = 'Deep Thought'; } diff --git a/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.2.inc b/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.2.inc index c4189ff1..924fe1e6 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 Slightly better, but no see tag + */ +define('B', 66); + +/** + * @deprecated + * @see + */ +define('C', 67); + +/** + * @deprecated No reference specified + * @see + */ +define('D', 68); + class Profiler { /** @@ -18,4 +41,26 @@ class Profiler * */ const NUMBER_TWO = 2; + + /** + * @deprecated + */ + const a = 97; + + /** + * @deprecated Slightly better, but no see tag + */ + const b = 98; + + /** + * @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 aa475c3d..ef6cc85d 100644 --- a/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.php +++ b/Magento2/Tests/Commenting/ConstantsPHPDocFormattingUnitTest.php @@ -27,10 +27,18 @@ public function getWarningList($testFile = '') } return [ - 5 => 1, - 8 => 1, - 15 => 1, - 20 => 1 + 6 => 1, + 9 => 1, + 14 => 1, + 19 => 1, + 25 => 1, + 31 => 1, + 38 => 1, + 43 => 1, + 48 => 1, + 53 => 1, + 59 => 1, + 65 => 1 ]; } }