PageRenderTime 26ms CodeModel.GetById 38ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR1/Sniffs/Files/SideEffectsSniff.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 229 lines | 129 code | 33 blank | 67 comment | 33 complexity | 2d6be1ca13202a825a8ddfac28f43b4a MD5 | raw file
  1. <?php
  2. /**
  3. * PSR1_Sniffs_Files_SideEffectsSniff.
  4. *
  5. * PHP version 5
  6. *
  7. * @category PHP
  8. * @package PHP_CodeSniffer
  9. * @author Greg Sherwood <gsherwood@squiz.net>
  10. * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
  11. * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
  12. * @link http://pear.php.net/package/PHP_CodeSniffer
  13. */
  14. /**
  15. * PSR1_Sniffs_Files_SideEffectsSniff.
  16. *
  17. * Ensures a file declare new symbols and causes no other side effects, or executes
  18. * logic with side effects, but not both.
  19. *
  20. * @category PHP
  21. * @package PHP_CodeSniffer
  22. * @author Greg Sherwood <gsherwood@squiz.net>
  23. * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
  24. * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
  25. * @version Release: @package_version@
  26. * @link http://pear.php.net/package/PHP_CodeSniffer
  27. */
  28. class PSR1_Sniffs_Files_SideEffectsSniff implements PHP_CodeSniffer_Sniff
  29. {
  30. /**
  31. * Returns an array of tokens this test wants to listen for.
  32. *
  33. * @return array
  34. */
  35. public function register()
  36. {
  37. return array(T_OPEN_TAG);
  38. }//end register()
  39. /**
  40. * Processes this sniff, when one of its tokens is encountered.
  41. *
  42. * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  43. * @param int $stackPtr The position of the current token in
  44. * the token stack.
  45. *
  46. * @return void
  47. */
  48. public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
  49. {
  50. // We are only interested if this is the first open tag.
  51. if ($stackPtr !== 0) {
  52. if ($phpcsFile->findPrevious(T_OPEN_TAG, ($stackPtr - 1)) !== false) {
  53. return;
  54. }
  55. }
  56. $tokens = $phpcsFile->getTokens();
  57. $result = $this->_searchForConflict($phpcsFile, 0, ($phpcsFile->numTokens - 1), $tokens);
  58. if ($result['symbol'] !== null && $result['effect'] !== null) {
  59. $error = 'A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should execute logic with side effects, but should not do both. The first symbol is defined on line %s and the first side effect is on line %s.';
  60. $data = array(
  61. $tokens[$result['symbol']]['line'],
  62. $tokens[$result['effect']]['line'],
  63. );
  64. $phpcsFile->addWarning($error, 0, 'FoundWithSymbols', $data);
  65. }
  66. }//end process()
  67. /**
  68. * Searches for symbol declarations and side effects.
  69. *
  70. * Returns the positions of both the first symbol declared and the first
  71. * side effect in the file. A NULL value for either indicates nothing was
  72. * found.
  73. *
  74. * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  75. * @param int $start The token to start searching from.
  76. * @param int $end The token to search to.
  77. * @param array $tokens The stack of tokens that make up
  78. * the file.
  79. *
  80. * @return array
  81. */
  82. private function _searchForConflict(PHP_CodeSniffer_File $phpcsFile, $start, $end, $tokens)
  83. {
  84. $symbols = array(
  85. T_CLASS,
  86. T_INTERFACE,
  87. T_TRAIT,
  88. T_FUNCTION,
  89. );
  90. $conditions = array(
  91. T_IF,
  92. T_ELSE,
  93. T_ELSEIF,
  94. );
  95. $firstSymbol = null;
  96. $firstEffect = null;
  97. for ($i = $start; $i <= $end; $i++) {
  98. // Ignore whitespace and comments.
  99. if (in_array($tokens[$i]['code'], PHP_CodeSniffer_Tokens::$emptyTokens) === true) {
  100. continue;
  101. }
  102. // Ignore PHP tags.
  103. if ($tokens[$i]['code'] === T_OPEN_TAG
  104. || $tokens[$i]['code'] === T_CLOSE_TAG
  105. ) {
  106. continue;
  107. }
  108. // Ignore entire namespace, const and use statements.
  109. if ($tokens[$i]['code'] === T_NAMESPACE) {
  110. $next = $phpcsFile->findNext(array(T_SEMICOLON, T_OPEN_CURLY_BRACKET), ($i + 1));
  111. if ($next === false) {
  112. $next = $i++;
  113. } else if ($tokens[$next]['code'] === T_OPEN_CURLY_BRACKET) {
  114. $next = $tokens[$next]['bracket_closer'];
  115. }
  116. $i = $next;
  117. continue;
  118. } else if ($tokens[$i]['code'] === T_USE
  119. || $tokens[$i]['code'] === T_CONST
  120. ) {
  121. $semicolon = $phpcsFile->findNext(T_SEMICOLON, ($i + 1));
  122. if ($semicolon !== false) {
  123. $i = $semicolon;
  124. }
  125. continue;
  126. }
  127. // Ignore function/class prefixes.
  128. if (in_array($tokens[$i]['code'], PHP_CodeSniffer_Tokens::$methodPrefixes) === true) {
  129. continue;
  130. }
  131. // Detect and skip over symbols.
  132. if (in_array($tokens[$i]['code'], $symbols) === true
  133. && isset($tokens[$i]['scope_closer']) === true
  134. ) {
  135. if ($firstSymbol === null) {
  136. $firstSymbol = $i;
  137. }
  138. $i = $tokens[$i]['scope_closer'];
  139. continue;
  140. } else if ($tokens[$i]['code'] === T_STRING
  141. && strtolower($tokens[$i]['content']) === 'define'
  142. ) {
  143. $prev = $phpcsFile->findPrevious(T_WHITESPACE, ($i - 1), null, true);
  144. if ($tokens[$prev]['code'] !== T_OBJECT_OPERATOR) {
  145. if ($firstSymbol === null) {
  146. $firstSymbol = $i;
  147. }
  148. $i = $phpcsFile->findNext(T_SEMICOLON, ($i + 1));
  149. continue;
  150. }
  151. }
  152. // Conditional statements are allowed in symbol files as long as the
  153. // contents is only a symbol definition. So don't count these as effects
  154. // in this case.
  155. if (in_array($tokens[$i]['code'], $conditions) === true) {
  156. if (isset($tokens[$i]['scope_opener']) === false) {
  157. // Probably an "else if", so just ignore.
  158. continue;
  159. }
  160. $result = $this->_searchForConflict(
  161. $phpcsFile,
  162. ($tokens[$i]['scope_opener'] + 1),
  163. ($tokens[$i]['scope_closer'] - 1),
  164. $tokens
  165. );
  166. if ($result['symbol'] !== null) {
  167. if ($firstSymbol === null) {
  168. $firstSymbol = $result['symbol'];
  169. }
  170. if ($result['effect'] !== null) {
  171. // Found a conflict.
  172. $firstEffect = $result['effect'];
  173. break;
  174. }
  175. }
  176. if ($firstEffect === null) {
  177. $firstEffect = $result['effect'];
  178. }
  179. $i = $tokens[$i]['scope_closer'];
  180. continue;
  181. }//end if
  182. if ($firstEffect === null) {
  183. $firstEffect = $i;
  184. }
  185. if ($firstSymbol !== null) {
  186. // We have a conflict we have to report, so no point continuing.
  187. break;
  188. }
  189. }//end for
  190. return array(
  191. 'symbol' => $firstSymbol,
  192. 'effect' => $firstEffect,
  193. );
  194. }//end _searchForConflict()
  195. }//end class
  196. ?>