PageRenderTime 60ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Formatting/OperatorBracketSniff.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 254 lines | 148 code | 34 blank | 72 comment | 43 complexity | 4b452b5690289d65d0f293fcac44bf0d MD5 | raw file
  1. <?php
  2. /**
  3. * Squiz_Sniffs_Formatting_OperationBracketSniff.
  4. *
  5. * PHP version 5
  6. *
  7. * @category PHP
  8. * @package PHP_CodeSniffer
  9. * @author Greg Sherwood <gsherwood@squiz.net>
  10. * @author Marc McIntyre <mmcintyre@squiz.net>
  11. * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
  12. * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
  13. * @link http://pear.php.net/package/PHP_CodeSniffer
  14. */
  15. /**
  16. * Squiz_Sniffs_Formatting_OperationBracketSniff.
  17. *
  18. * Tests that all arithmetic operations are bracketed.
  19. *
  20. * @category PHP
  21. * @package PHP_CodeSniffer
  22. * @author Greg Sherwood <gsherwood@squiz.net>
  23. * @author Marc McIntyre <mmcintyre@squiz.net>
  24. * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
  25. * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
  26. * @version Release: @package_version@
  27. * @link http://pear.php.net/package/PHP_CodeSniffer
  28. */
  29. class Squiz_Sniffs_Formatting_OperatorBracketSniff implements PHP_CodeSniffer_Sniff
  30. {
  31. /**
  32. * A list of tokenizers this sniff supports.
  33. *
  34. * @var array
  35. */
  36. public $supportedTokenizers = array(
  37. 'PHP',
  38. 'JS',
  39. );
  40. /**
  41. * Returns an array of tokens this test wants to listen for.
  42. *
  43. * @return array
  44. */
  45. public function register()
  46. {
  47. return PHP_CodeSniffer_Tokens::$operators;
  48. }//end register()
  49. /**
  50. * Processes this test, when one of its tokens is encountered.
  51. *
  52. * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  53. * @param int $stackPtr The position of the current token in the
  54. * stack passed in $tokens.
  55. *
  56. * @return void
  57. */
  58. public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
  59. {
  60. $tokens = $phpcsFile->getTokens();
  61. if ($phpcsFile->tokenizerType === 'JS' && $tokens[$stackPtr]['code'] === T_PLUS) {
  62. // JavaScript uses the plus operator for string concatenation as well
  63. // so we cannot accurately determine if it is a string concat or addition.
  64. // So just ignore it.
  65. return;
  66. }
  67. // If the & is a reference, then we don't want to check for brackets.
  68. if ($tokens[$stackPtr]['code'] === T_BITWISE_AND && $phpcsFile->isReference($stackPtr) === true) {
  69. return;
  70. }
  71. // There is one instance where brackets aren't needed, which involves
  72. // the minus sign being used to assign a negative number to a variable.
  73. if ($tokens[$stackPtr]['code'] === T_MINUS) {
  74. // Check to see if we are trying to return -n.
  75. $prev = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr - 1), null, true);
  76. if ($tokens[$prev]['code'] === T_RETURN) {
  77. return;
  78. }
  79. $number = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
  80. if ($tokens[$number]['code'] === T_LNUMBER || $tokens[$number]['code'] === T_DNUMBER) {
  81. $previous = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
  82. if ($previous !== false) {
  83. $isAssignment = in_array($tokens[$previous]['code'], PHP_CodeSniffer_Tokens::$assignmentTokens);
  84. $isEquality = in_array($tokens[$previous]['code'], PHP_CodeSniffer_Tokens::$equalityTokens);
  85. $isComparison = in_array($tokens[$previous]['code'], PHP_CodeSniffer_Tokens::$comparisonTokens);
  86. if ($isAssignment === true || $isEquality === true || $isComparison === true) {
  87. // This is a negative assignment or comparison.
  88. // We need to check that the minus and the number are
  89. // adjacent.
  90. if (($number - $stackPtr) !== 1) {
  91. $error = 'No space allowed between minus sign and number';
  92. $phpcsFile->addError($error, $stackPtr, 'SpacingAfterMinus');
  93. }
  94. return;
  95. }
  96. }
  97. }
  98. }//end if
  99. $lastBracket = false;
  100. if (isset($tokens[$stackPtr]['nested_parenthesis']) === true) {
  101. $parenthesis = array_reverse($tokens[$stackPtr]['nested_parenthesis'], true);
  102. foreach ($parenthesis as $bracket => $endBracket) {
  103. $prevToken = $phpcsFile->findPrevious(T_WHITESPACE, ($bracket - 1), null, true);
  104. $prevCode = $tokens[$prevToken]['code'];
  105. if ($prevCode === T_ISSET) {
  106. // This operation is inside an isset() call, but has
  107. // no bracket of it's own.
  108. break;
  109. }
  110. if ($prevCode === T_STRING || $prevCode === T_SWITCH) {
  111. // We allow very simple operations to not be bracketed.
  112. // For example, ceil($one / $two).
  113. $allowed = array(
  114. T_VARIABLE,
  115. T_LNUMBER,
  116. T_DNUMBER,
  117. T_STRING,
  118. T_WHITESPACE,
  119. T_THIS,
  120. T_OBJECT_OPERATOR,
  121. T_OPEN_SQUARE_BRACKET,
  122. T_CLOSE_SQUARE_BRACKET,
  123. T_MODULUS,
  124. );
  125. for ($prev = ($stackPtr - 1); $prev > $bracket; $prev--) {
  126. if (in_array($tokens[$prev]['code'], $allowed) === true) {
  127. continue;
  128. }
  129. if ($tokens[$prev]['code'] === T_CLOSE_PARENTHESIS) {
  130. $prev = $tokens[$prev]['parenthesis_opener'];
  131. } else {
  132. break;
  133. }
  134. }
  135. if ($prev !== $bracket) {
  136. break;
  137. }
  138. for ($next = ($stackPtr + 1); $next < $endBracket; $next++) {
  139. if (in_array($tokens[$next]['code'], $allowed) === true) {
  140. continue;
  141. }
  142. if ($tokens[$next]['code'] === T_OPEN_PARENTHESIS) {
  143. $next = $tokens[$next]['parenthesis_closer'];
  144. } else {
  145. break;
  146. }
  147. }
  148. if ($next !== $endBracket) {
  149. break;
  150. }
  151. }//end if
  152. if (in_array($prevCode, PHP_CodeSniffer_Tokens::$scopeOpeners) === true) {
  153. // This operation is inside a control structure like FOREACH
  154. // or IF, but has no bracket of it's own.
  155. // The only control structure allowed to do this is SWITCH.
  156. if ($prevCode !== T_SWITCH) {
  157. break;
  158. }
  159. }
  160. if ($prevCode === T_OPEN_PARENTHESIS) {
  161. // These are two open parenthesis in a row. If the current
  162. // one doesn't enclose the operator, go to the previous one.
  163. if ($endBracket < $stackPtr) {
  164. continue;
  165. }
  166. }
  167. $lastBracket = $bracket;
  168. break;
  169. }//end foreach
  170. }//end if
  171. if ($lastBracket === false) {
  172. // It is not in a bracketed statement at all.
  173. $previousToken = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true, null, true);
  174. if ($previousToken !== false) {
  175. // A list of tokens that indicate that the token is not
  176. // part of an arithmetic operation.
  177. $invalidTokens = array(
  178. T_COMMA,
  179. T_COLON,
  180. T_OPEN_PARENTHESIS,
  181. T_OPEN_SQUARE_BRACKET,
  182. T_CASE,
  183. );
  184. if (in_array($tokens[$previousToken]['code'], $invalidTokens) === false) {
  185. $error = 'Arithmetic operation must be bracketed';
  186. $phpcsFile->addError($error, $stackPtr, 'MissingBrackets');
  187. }
  188. return;
  189. }
  190. } else if ($tokens[$lastBracket]['parenthesis_closer'] < $stackPtr) {
  191. // There are a set of brackets in front of it that don't include it.
  192. $error = 'Arithmetic operation must be bracketed';
  193. $phpcsFile->addError($error, $stackPtr, 'MissingBrackets');
  194. return;
  195. } else {
  196. // We are enclosed in a set of bracket, so the last thing to
  197. // check is that we are not also enclosed in square brackets
  198. // like this: ($array[$index + 1]), which is invalid.
  199. $brackets = array(
  200. T_OPEN_SQUARE_BRACKET,
  201. T_CLOSE_SQUARE_BRACKET,
  202. );
  203. $squareBracket = $phpcsFile->findPrevious($brackets, ($stackPtr - 1), $lastBracket);
  204. if ($squareBracket !== false && $tokens[$squareBracket]['code'] === T_OPEN_SQUARE_BRACKET) {
  205. $closeSquareBracket = $phpcsFile->findNext($brackets, ($stackPtr + 1));
  206. if ($closeSquareBracket !== false && $tokens[$closeSquareBracket]['code'] === T_CLOSE_SQUARE_BRACKET) {
  207. $error = 'Arithmetic operation must be bracketed';
  208. $phpcsFile->addError($error, $stackPtr, 'MissingBrackets');
  209. }
  210. }
  211. return;
  212. }//end if
  213. $lastAssignment = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$assignmentTokens, $stackPtr, null, false, null, true);
  214. if ($lastAssignment !== false && $lastAssignment > $lastBracket) {
  215. $error = 'Arithmetic operation must be bracketed';
  216. $phpcsFile->addError($error, $stackPtr, 'MissingBrackets');
  217. }
  218. }//end process()
  219. }//end class
  220. ?>