PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/build/phpcs/Joomla/Sniffs/WhiteSpace/OperatorSpacingSniff.php

http://github.com/joomla/joomla-platform
PHP | 258 lines | 164 code | 26 blank | 68 comment | 37 complexity | 07081e6417e49e8e4bec76193664d144 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * Sniffs_Squiz_WhiteSpace_OperatorSpacingSniff.
  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 Squiz Pty Ltd (ABN 77 084 670 600)
  12. * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
  13. * @version CVS: $Id: OperatorSpacingSniff.php 8 2010-11-06 00:40:23Z elkuku $
  14. * @link http://pear.php.net/package/PHP_CodeSniffer
  15. */
  16. /**
  17. * Verifies that operators have valid spacing surrounding them.
  18. *
  19. * Example:
  20. * <b class="bad">$a=$b+$c;</b>
  21. * <b class="good">$a = $b + $c;</b>
  22. *
  23. * @category PHP
  24. * @package PHP_CodeSniffer
  25. * @author Greg Sherwood <gsherwood@squiz.net>
  26. * @author Marc McIntyre <mmcintyre@squiz.net>
  27. * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
  28. * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
  29. * @version Release: 1.3.0RC1
  30. * @link http://pear.php.net/package/PHP_CodeSniffer
  31. */
  32. class Joomla_Sniffs_WhiteSpace_OperatorSpacingSniff implements PHP_CodeSniffer_Sniff
  33. {
  34. /**
  35. * A list of tokenizers this sniff supports.
  36. *
  37. * @var array
  38. */
  39. public $supportedTokenizers = array(
  40. 'PHP',
  41. 'JS',
  42. );
  43. /**
  44. * Returns an array of tokens this test wants to listen for.
  45. *
  46. * @return array
  47. */
  48. public function register()
  49. {
  50. $comparison = PHP_CodeSniffer_Tokens::$comparisonTokens;
  51. $operators = PHP_CodeSniffer_Tokens::$operators;
  52. $assignment = PHP_CodeSniffer_Tokens::$assignmentTokens;
  53. return array_unique(array_merge($comparison, $operators, $assignment));
  54. }//function
  55. /**
  56. * Processes this sniff, when one of its tokens is encountered.
  57. *
  58. * @param PHP_CodeSniffer_File $phpcsFile The current file being checked.
  59. * @param integer $stackPtr The position of the current token in the
  60. * stack passed in $tokens.
  61. *
  62. * @return void
  63. */
  64. public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
  65. {
  66. $tokens = $phpcsFile->getTokens();
  67. // Skip default values in function declarations.
  68. if($tokens[$stackPtr]['code'] === T_EQUAL
  69. || $tokens[$stackPtr]['code'] === T_MINUS
  70. )
  71. {
  72. if(isset($tokens[$stackPtr]['nested_parenthesis']) === true)
  73. {
  74. $bracket = end($tokens[$stackPtr]['nested_parenthesis']);
  75. if(isset($tokens[$bracket]['parenthesis_owner']) === true)
  76. {
  77. $function = $tokens[$bracket]['parenthesis_owner'];
  78. if($tokens[$function]['code'] === T_FUNCTION)
  79. {
  80. return;
  81. }
  82. }
  83. }
  84. }
  85. if($tokens[$stackPtr]['code'] === T_EQUAL)
  86. {
  87. // Skip for '=&' case.
  88. if(isset($tokens[($stackPtr + 1)]) === true
  89. && $tokens[($stackPtr + 1)]['code'] === T_BITWISE_AND
  90. || $tokens[($stackPtr + 1)]['code'] === T_OPEN_PARENTHESIS)
  91. {
  92. return;
  93. }
  94. }
  95. if($tokens[$stackPtr]['code'] === T_EQUAL
  96. || $tokens[$stackPtr]['content'] === '.='
  97. || $tokens[$stackPtr]['content'] === '+=')
  98. {
  99. // Skip for '=(' case.
  100. // Skip also '.=('
  101. if(isset($tokens[($stackPtr + 1)]) === true
  102. && $tokens[($stackPtr + 1)]['code'] === T_OPEN_PARENTHESIS)
  103. {
  104. return;
  105. }
  106. }
  107. if($tokens[$stackPtr]['code'] === T_BITWISE_AND)
  108. {
  109. // If its not a reference, then we expect one space either side of the
  110. // bitwise operator.
  111. if($phpcsFile->isReference($stackPtr) === false)
  112. {
  113. // Check there is one space before the & operator.
  114. if($tokens[($stackPtr - 1)]['code'] !== T_WHITESPACE)
  115. {
  116. $error = 'Expected 1 space before "&" operator; 0 found';
  117. $phpcsFile->addError($error, $stackPtr, 'NoSpaceBeforeAmp');
  118. }
  119. else
  120. {
  121. if(strlen($tokens[($stackPtr - 1)]['content']) !== 1)
  122. {
  123. $found = strlen($tokens[($stackPtr - 1)]['content']);
  124. $error = sprintf('Expected 1 space before "&" operator; %s found'
  125. , $found);
  126. $phpcsFile->addError($error, $stackPtr, 'SpacingBeforeAmp');
  127. }
  128. }
  129. // Check there is one space after the & operator.
  130. if($tokens[($stackPtr + 1)]['code'] !== T_WHITESPACE)
  131. {
  132. $error = 'Expected 1 space after "&" operator; 0 found';
  133. $phpcsFile->addError($error, $stackPtr, 'NoSpaceAfterAmp');
  134. }
  135. else
  136. {
  137. if(strlen($tokens[($stackPtr + 1)]['content']) !== 1)
  138. {
  139. $found = strlen($tokens[($stackPtr + 1)]['content']);
  140. $error = sprintf('Expected 1 space after "&" operator; %s found'
  141. , $found);
  142. $phpcsFile->addError($error, $stackPtr, 'SpacingAfterAmp');
  143. }
  144. }
  145. }
  146. }
  147. else
  148. {
  149. if($tokens[$stackPtr]['code'] === T_MINUS
  150. || $tokens[$stackPtr]['code'] === T_PLUS)
  151. {
  152. // Check minus spacing, but make sure we aren't just assigning
  153. // a minus value or returning one.
  154. $prev = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
  155. if($tokens[$prev]['code'] === T_RETURN)
  156. {
  157. // Just returning a negative value; eg. return -1.
  158. return;
  159. }
  160. if(in_array($tokens[$prev]['code'], PHP_CodeSniffer_Tokens::$operators) === true)
  161. {
  162. // Just trying to operate on a negative value; eg. ($var * -1).
  163. return;
  164. }
  165. if(in_array($tokens[$prev]['code'], PHP_CodeSniffer_Tokens::$comparisonTokens) === true)
  166. {
  167. // Just trying to compare a negative value; eg. ($var === -1).
  168. return;
  169. }
  170. // A list of tokens that indicate that the token is not
  171. // part of an arithmetic operation.
  172. $invalidTokens = array(
  173. T_COMMA,
  174. T_OPEN_PARENTHESIS,
  175. T_OPEN_SQUARE_BRACKET,
  176. T_DOUBLE_ARROW,
  177. T_COLON,
  178. T_INLINE_THEN, // the ternary "?"
  179. );
  180. if(in_array($tokens[$prev]['code'], $invalidTokens) === true)
  181. {
  182. // Just trying to use a negative value; eg. myFunction($var, -2).
  183. return;
  184. }
  185. $number = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
  186. if(in_array($tokens[$number]['code'], array(T_LNUMBER, T_VARIABLE)) === true)
  187. {
  188. $semi = $phpcsFile->findNext(T_WHITESPACE, ($number + 1), null, true);
  189. if($tokens[$semi]['code'] === T_SEMICOLON)
  190. {
  191. if($prev !== false
  192. && (in_array($tokens[$prev]['code'], PHP_CodeSniffer_Tokens::$assignmentTokens) === true))
  193. {
  194. // This is a negative assignment.
  195. return;
  196. }
  197. }
  198. }
  199. }
  200. $operator = $tokens[$stackPtr]['content'];
  201. if($tokens[($stackPtr - 1)]['code'] !== T_WHITESPACE)
  202. {
  203. $error = "Expected 1 space before \"$operator\"; 0 found";
  204. $phpcsFile->addError($error, $stackPtr, 'NoSpaceBefore');
  205. }
  206. else if(strlen($tokens[($stackPtr - 1)]['content']) !== 1)
  207. {
  208. // Don't throw an error for assignments, because other standards allow
  209. // multiple spaces there to align multiple assignments.
  210. if(in_array($tokens[$stackPtr]['code'], PHP_CodeSniffer_Tokens::$assignmentTokens) === false)
  211. {
  212. $found = strlen($tokens[($stackPtr - 1)]['content']);
  213. $error = sprintf('Expected 1 space before "%s"; %s found'
  214. , $operator, $found);
  215. $phpcsFile->addError($error, $stackPtr, 'SpacingBefore');
  216. }
  217. }
  218. if($tokens[($stackPtr + 1)]['code'] !== T_WHITESPACE)
  219. {
  220. $error = "Expected 1 space after \"$operator\"; 0 found";
  221. $phpcsFile->addError($error, $stackPtr, 'NoSpaceAfter');
  222. }
  223. else if(strlen($tokens[($stackPtr + 1)]['content']) !== 1)
  224. {
  225. $found = strlen($tokens[($stackPtr + 1)]['content']);
  226. $error = sprintf('Expected 1 space after "%s"; %s found'
  227. , $operator, $found);
  228. $phpcsFile->addError($error, $stackPtr, 'SpacingAfter');
  229. }
  230. }
  231. }//function
  232. }//class