PageRenderTime 41ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/FunctionCommentThrowTagSniff.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 215 lines | 129 code | 28 blank | 58 comment | 20 complexity | 8e775f3d9fb41a4ade6b9bbc1c97820f MD5 | raw file
  1. <?php
  2. /**
  3. * Verifies that a @throws tag exists for a function that throws exceptions.
  4. * Verifies the number of @throws tags and the number of throw tokens matches.
  5. * Verifies the exception type.
  6. *
  7. * PHP version 5
  8. *
  9. * @category PHP
  10. * @package PHP_CodeSniffer
  11. * @author Greg Sherwood <gsherwood@squiz.net>
  12. * @author Marc McIntyre <mmcintyre@squiz.net>
  13. * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
  14. * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
  15. * @link http://pear.php.net/package/PHP_CodeSniffer
  16. */
  17. if (class_exists('PHP_CodeSniffer_Standards_AbstractScopeSniff', true) === false) {
  18. $error = 'Class PHP_CodeSniffer_Standards_AbstractScopeSniff not found';
  19. throw new PHP_CodeSniffer_Exception($error);
  20. }
  21. /**
  22. * Verifies that a @throws tag exists for a function that throws exceptions.
  23. * Verifies the number of @throws tags and the number of throw tokens matches.
  24. * Verifies the exception type.
  25. *
  26. * @category PHP
  27. * @package PHP_CodeSniffer
  28. * @author Greg Sherwood <gsherwood@squiz.net>
  29. * @author Marc McIntyre <mmcintyre@squiz.net>
  30. * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
  31. * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
  32. * @version Release: @package_version@
  33. * @link http://pear.php.net/package/PHP_CodeSniffer
  34. */
  35. class Squiz_Sniffs_Commenting_FunctionCommentThrowTagSniff extends PHP_CodeSniffer_Standards_AbstractScopeSniff
  36. {
  37. /**
  38. * Constructs a Squiz_Sniffs_Commenting_FunctionCommentThrowTagSniff.
  39. */
  40. public function __construct()
  41. {
  42. parent::__construct(array(T_FUNCTION), array(T_THROW));
  43. }//end __construct()
  44. /**
  45. * Processes the function tokens within the class.
  46. *
  47. * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found.
  48. * @param int $stackPtr The position where the token was found.
  49. * @param int $currScope The current scope opener token.
  50. *
  51. * @return void
  52. */
  53. protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope)
  54. {
  55. // Is this the first throw token within the current function scope?
  56. // If so, we have to validate other throw tokens within the same scope.
  57. $previousThrow = $phpcsFile->findPrevious(T_THROW, ($stackPtr - 1), $currScope);
  58. if ($previousThrow !== false) {
  59. return;
  60. }
  61. $tokens = $phpcsFile->getTokens();
  62. $find = array(
  63. T_COMMENT,
  64. T_DOC_COMMENT,
  65. T_CLASS,
  66. T_FUNCTION,
  67. T_OPEN_TAG,
  68. );
  69. $commentEnd = $phpcsFile->findPrevious($find, ($currScope - 1));
  70. if ($commentEnd === false) {
  71. return;
  72. }
  73. if ($tokens[$commentEnd]['code'] !== T_DOC_COMMENT) {
  74. // Function doesn't have a comment. Let someone else warn about that.
  75. return;
  76. }
  77. $commentStart = ($phpcsFile->findPrevious(T_DOC_COMMENT, ($commentEnd - 1), null, true) + 1);
  78. $comment = $phpcsFile->getTokensAsString($commentStart, ($commentEnd - $commentStart + 1));
  79. try {
  80. $this->commentParser = new PHP_CodeSniffer_CommentParser_FunctionCommentParser($comment, $phpcsFile);
  81. $this->commentParser->parse();
  82. } catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
  83. $line = ($e->getLineWithinComment() + $commentStart);
  84. $phpcsFile->addError($e->getMessage(), $line, 'FailedParse');
  85. return;
  86. }
  87. // Find the position where the current function scope ends.
  88. $currScopeEnd = 0;
  89. if (isset($tokens[$currScope]['scope_closer']) === true) {
  90. $currScopeEnd = $tokens[$currScope]['scope_closer'];
  91. }
  92. // Find all the exception type token within the current scope.
  93. $throwTokens = array();
  94. $currPos = $stackPtr;
  95. if ($currScopeEnd !== 0) {
  96. while ($currPos < $currScopeEnd && $currPos !== false) {
  97. /*
  98. If we can't find a NEW, we are probably throwing
  99. a variable, so we ignore it, but they still need to
  100. provide at least one @throws tag, even through we
  101. don't know the exception class.
  102. */
  103. $nextToken = $phpcsFile->findNext(T_WHITESPACE, ($currPos + 1), null, true);
  104. if ($tokens[$nextToken]['code'] === T_NEW) {
  105. $currException = $phpcsFile->findNext(
  106. array(
  107. T_NS_SEPARATOR,
  108. T_STRING,
  109. ),
  110. $currPos,
  111. $currScopeEnd,
  112. false,
  113. null,
  114. true
  115. );
  116. if ($currException !== false) {
  117. $endException = $phpcsFile->findNext(
  118. array(
  119. T_NS_SEPARATOR,
  120. T_STRING,
  121. ),
  122. ($currException + 1),
  123. $currScopeEnd,
  124. true,
  125. null,
  126. true
  127. );
  128. if ($endException === false) {
  129. $throwTokens[] = $tokens[$currException]['content'];
  130. } else {
  131. $throwTokens[] = $phpcsFile->getTokensAsString($currException, ($endException - $currException));
  132. }
  133. }//end if
  134. }//end if
  135. $currPos = $phpcsFile->findNext(T_THROW, ($currPos + 1), $currScopeEnd);
  136. }//end while
  137. }//end if
  138. // Only need one @throws tag for each type of exception thrown.
  139. $throwTokens = array_unique($throwTokens);
  140. sort($throwTokens);
  141. $throws = $this->commentParser->getThrows();
  142. if (empty($throws) === true) {
  143. $error = 'Missing @throws tag in function comment';
  144. $phpcsFile->addError($error, $commentEnd, 'Missing');
  145. } else if (empty($throwTokens) === true) {
  146. // If token count is zero, it means that only variables are being
  147. // thrown, so we need at least one @throws tag (checked above).
  148. // Nothing more to do.
  149. return;
  150. } else {
  151. $throwTags = array();
  152. $lineNumber = array();
  153. foreach ($throws as $throw) {
  154. $throwTags[] = $throw->getValue();
  155. $lineNumber[$throw->getValue()] = $throw->getLine();
  156. }
  157. $throwTags = array_unique($throwTags);
  158. sort($throwTags);
  159. // Make sure @throws tag count matches throw token count.
  160. $tokenCount = count($throwTokens);
  161. $tagCount = count($throwTags);
  162. if ($tokenCount !== $tagCount) {
  163. $error = 'Expected %s @throws tag(s) in function comment; %s found';
  164. $data = array(
  165. $tokenCount,
  166. $tagCount,
  167. );
  168. $phpcsFile->addError($error, $commentEnd, 'WrongNumber', $data);
  169. return;
  170. } else {
  171. // Exception type in @throws tag must be thrown in the function.
  172. foreach ($throwTags as $i => $throwTag) {
  173. $errorPos = ($commentStart + $lineNumber[$throwTag]);
  174. if (empty($throwTag) === false && $throwTag !== $throwTokens[$i]) {
  175. $error = 'Expected "%s" but found "%s" for @throws tag exception';
  176. $data = array(
  177. $throwTokens[$i],
  178. $throwTag,
  179. );
  180. $phpcsFile->addError($error, $errorPos, 'WrongType', $data);
  181. }
  182. }
  183. }
  184. }//end if
  185. }//end processTokenWithinScope()
  186. }//end class
  187. ?>