/php/pear/PHP/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php

https://gitlab.com/trang1104/portable_project · PHP · 211 lines · 129 code · 27 blank · 55 comment · 25 complexity · 7996f6fd4ed01491f0cd635ae215ed65 MD5 · raw file

  1. <?php
  2. /**
  3. * Squiz_Sniffs_WhiteSpace_ControlStructureSpacingSniff.
  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-2011 Squiz Pty Ltd (ABN 77 084 670 600)
  12. * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
  13. * @link http://pear.php.net/package/PHP_CodeSniffer
  14. */
  15. /**
  16. * Squiz_Sniffs_WhiteSpace_ControlStructureSpacingSniff.
  17. *
  18. * Checks that control structures have the correct spacing around brackets.
  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-2011 Squiz Pty Ltd (ABN 77 084 670 600)
  25. * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
  26. * @version Release: 1.3.3
  27. * @link http://pear.php.net/package/PHP_CodeSniffer
  28. */
  29. class Squiz_Sniffs_WhiteSpace_ControlStructureSpacingSniff 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 array(
  48. T_IF,
  49. T_WHILE,
  50. T_FOREACH,
  51. T_FOR,
  52. T_SWITCH,
  53. T_DO,
  54. T_ELSE,
  55. T_ELSEIF,
  56. );
  57. }//end register()
  58. /**
  59. * Processes this test, when one of its tokens is encountered.
  60. *
  61. * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  62. * @param int $stackPtr The position of the current token
  63. * in the stack passed in $tokens.
  64. *
  65. * @return void
  66. */
  67. public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
  68. {
  69. $tokens = $phpcsFile->getTokens();
  70. if (isset($tokens[$stackPtr]['scope_closer']) === false) {
  71. return;
  72. }
  73. if (isset($tokens[$stackPtr]['parenthesis_opener']) === true) {
  74. $parenOpener = $tokens[$stackPtr]['parenthesis_opener'];
  75. $parenCloser = $tokens[$stackPtr]['parenthesis_closer'];
  76. if ($tokens[($parenOpener + 1)]['code'] === T_WHITESPACE) {
  77. $gap = strlen($tokens[($parenOpener + 1)]['content']);
  78. $error = 'Expected 0 spaces after opening bracket; %s found';
  79. $data = array($gap);
  80. $phpcsFile->addError($error, ($parenOpener + 1), 'SpacingAfterOpenBrace', $data);
  81. }
  82. if ($tokens[$parenOpener]['line'] === $tokens[$parenCloser]['line']
  83. && $tokens[($parenCloser - 1)]['code'] === T_WHITESPACE
  84. ) {
  85. $gap = strlen($tokens[($parenCloser - 1)]['content']);
  86. $error = 'Expected 0 spaces before closing bracket; %s found';
  87. $data = array($gap);
  88. $phpcsFile->addError($error, ($parenCloser - 1), 'SpaceBeforeCloseBrace', $data);
  89. }
  90. }//end if
  91. $scopeOpener = $tokens[$stackPtr]['scope_opener'];
  92. $scopeCloser = $tokens[$stackPtr]['scope_closer'];
  93. $firstContent = $phpcsFile->findNext(
  94. T_WHITESPACE,
  95. ($scopeOpener + 1),
  96. null,
  97. true
  98. );
  99. if ($tokens[$firstContent]['line'] !== ($tokens[$scopeOpener]['line'] + 1)) {
  100. $error = 'Blank line found at start of control structure';
  101. $phpcsFile->addError($error, $scopeOpener, 'SpacingBeforeOpen');
  102. }
  103. $lastContent = $phpcsFile->findPrevious(
  104. T_WHITESPACE,
  105. ($scopeCloser - 1),
  106. null,
  107. true
  108. );
  109. if ($tokens[$lastContent]['line'] !== ($tokens[$scopeCloser]['line'] - 1)) {
  110. $errorToken = $scopeCloser;
  111. for ($i = ($scopeCloser - 1); $i > $lastContent; $i--) {
  112. if ($tokens[$i]['line'] < $tokens[$scopeCloser]['line']) {
  113. $errorToken = $i;
  114. break;
  115. }
  116. }
  117. $error = 'Blank line found at end of control structure';
  118. $phpcsFile->addError($error, $errorToken, 'SpacingAfterClose');
  119. }
  120. $trailingContent = $phpcsFile->findNext(
  121. T_WHITESPACE,
  122. ($scopeCloser + 1),
  123. null,
  124. true
  125. );
  126. if ($tokens[$trailingContent]['code'] === T_ELSE) {
  127. if ($tokens[$stackPtr]['code'] === T_IF) {
  128. // IF with ELSE.
  129. return;
  130. }
  131. }
  132. if ($tokens[$trailingContent]['code'] === T_COMMENT) {
  133. if ($tokens[$trailingContent]['line'] === $tokens[$scopeCloser]['line']) {
  134. if (substr($tokens[$trailingContent]['content'], 0, 5) === '//end') {
  135. // There is an end comment, so we have to get the next piece
  136. // of content.
  137. $trailingContent = $phpcsFile->findNext(
  138. T_WHITESPACE,
  139. ($trailingContent + 1),
  140. null,
  141. true
  142. );
  143. }
  144. }
  145. }
  146. if ($tokens[$trailingContent]['code'] === T_BREAK) {
  147. // If this BREAK is closing a CASE, we don't need the
  148. // blank line after this control structure.
  149. if (isset($tokens[$trailingContent]['scope_condition']) === true) {
  150. $condition = $tokens[$trailingContent]['scope_condition'];
  151. if ($tokens[$condition]['code'] === T_CASE
  152. || $tokens[$condition]['code'] === T_DEFAULT
  153. ) {
  154. return;
  155. }
  156. }
  157. }
  158. if ($tokens[$trailingContent]['code'] === T_CLOSE_TAG) {
  159. // At the end of the script or embedded code.
  160. return;
  161. }
  162. if ($tokens[$trailingContent]['code'] === T_CLOSE_CURLY_BRACKET) {
  163. // Another control structure's closing brace.
  164. if (isset($tokens[$trailingContent]['scope_condition']) === true) {
  165. $owner = $tokens[$trailingContent]['scope_condition'];
  166. if ($tokens[$owner]['code'] === T_FUNCTION) {
  167. // The next content is the closing brace of a function
  168. // so normal function rules apply and we can ignore it.
  169. return;
  170. }
  171. }
  172. if ($tokens[$trailingContent]['line'] !== ($tokens[$scopeCloser]['line'] + 1)) {
  173. $error = 'Blank line found after control structure';
  174. $phpcsFile->addError($error, $scopeCloser, 'LineAfterClose');
  175. }
  176. } else {
  177. if ($tokens[$trailingContent]['line'] === ($tokens[$scopeCloser]['line'] + 1)) {
  178. $error = 'No blank line found after control structure';
  179. $phpcsFile->addError($error, $scopeCloser, 'NoLineAfterClose');
  180. }
  181. }
  182. }//end process()
  183. }//end class
  184. ?>