diff --git a/Magento2/Sniffs/Exceptions/DirectThrowSniff.php b/Magento2/Sniffs/Exceptions/DirectThrowSniff.php index 622644bf..576d2066 100644 --- a/Magento2/Sniffs/Exceptions/DirectThrowSniff.php +++ b/Magento2/Sniffs/Exceptions/DirectThrowSniff.php @@ -44,7 +44,30 @@ public function process(File $phpcsFile, $stackPtr) $tokens = $phpcsFile->getTokens(); $endOfStatement = $phpcsFile->findEndOfStatement($stackPtr); $posOfException = $phpcsFile->findNext(T_STRING, $stackPtr, $endOfStatement); - if ($tokens[$posOfException]['content'] === 'Exception') { + + $fullExceptionString = $this->getFullClassNameAndAlias($tokens, $stackPtr, $endOfStatement); + $exceptionString = 'Exception'; + $customExceptionFound = false; + foreach ($tokens as $key => $token) { + if ($token['code'] !== T_USE) { + continue; + } + $endOfUse = $phpcsFile->findEndOfStatement($key); + $useStatementValue = $this->getFullClassNameAndAlias($tokens, $key, $endOfUse); + //we safely consider use statement has alias will not be a direct exception class + if (empty($useStatementValue['alias'])) { + if (substr($useStatementValue['name'], 0, strlen($exceptionString)) !== $exceptionString + && substr($useStatementValue['name'], -strlen($exceptionString)) === $exceptionString + && $useStatementValue['name'] !== $exceptionString + ) { + $customExceptionFound = true; + break; + } + } + } + if (($tokens[$posOfException]['content'] === 'Exception' && !$customExceptionFound) + || $fullExceptionString['name'] === '\Exception' + ) { $phpcsFile->addWarning( $this->warningMessage, $stackPtr, @@ -53,4 +76,33 @@ public function process(File $phpcsFile, $stackPtr) ); } } + + /** + * Get full class name and alias + * + * @param array $tokens + * @param int $start + * @param int $end + * @return array + */ + private function getFullClassNameAndAlias($tokens, $start, $end): array + { + $fullName = $alias = ''; + $foundAlias = false; + for ($i = $start; $i <= $end; $i++) { + $type = $tokens[$i]['code']; + if ($type === T_AS) { + $foundAlias = true; + continue; + } + if ($type === T_STRING || $type === T_NS_SEPARATOR) { + if (!$foundAlias) { + $fullName .= $tokens[$i]['content']; + } else { + $alias = $tokens[$i]['content']; + } + } + } + return ['name' => $fullName, 'alias' => $alias]; + } } diff --git a/Magento2/Tests/Exceptions/DirectThrowUnitTest.inc b/Magento2/Tests/Exceptions/DirectThrowUnitTest.1.inc similarity index 100% rename from Magento2/Tests/Exceptions/DirectThrowUnitTest.inc rename to Magento2/Tests/Exceptions/DirectThrowUnitTest.1.inc diff --git a/Magento2/Tests/Exceptions/DirectThrowUnitTest.2.inc b/Magento2/Tests/Exceptions/DirectThrowUnitTest.2.inc new file mode 100644 index 00000000..ea319647 --- /dev/null +++ b/Magento2/Tests/Exceptions/DirectThrowUnitTest.2.inc @@ -0,0 +1,31 @@ +isEnabled) { + throw new Exception('Action disabled.'); + } + } + + public function exceptionTest() + { + if (!$this->isEnabled) { + throw new \Exception('Action disabled.'); + } + } + + public function localizedExceptionTest() + { + + if (!$this->isEnabled) { + throw new LocalizedException('Localized exception.'); + } + } +} diff --git a/Magento2/Tests/Exceptions/DirectThrowUnitTest.php b/Magento2/Tests/Exceptions/DirectThrowUnitTest.php index dee9d504..906f92c5 100644 --- a/Magento2/Tests/Exceptions/DirectThrowUnitTest.php +++ b/Magento2/Tests/Exceptions/DirectThrowUnitTest.php @@ -12,7 +12,7 @@ class DirectThrowUnitTest extends AbstractSniffUnitTest /** * @inheritdoc */ - public function getErrorList() + protected function getErrorList() { return []; } @@ -20,11 +20,18 @@ public function getErrorList() /** * @inheritdoc */ - public function getWarningList() + protected function getWarningList($testFile = '') { - return [ - 10 => 1, - 17 => 1, - ]; + if ($testFile === 'DirectThrowUnitTest.1.inc') { + return [ + 10 => 1, + 17 => 1, + ]; + } elseif ($testFile === 'DirectThrowUnitTest.2.inc') { + return [ + 20 => 1 + ]; + } + return []; } }