annotate vendor/drupal/coder/coder_sniffer/Drupal/Sniffs/Classes/ClassDeclarationSniff.php @ 12:7a779792577d

Update Drupal core to v8.4.5 (via Composer)
author Chris Cannam
date Fri, 23 Feb 2018 15:52:07 +0000
parents 4c8ae668cc8c
children 129ea1e6d783
rev   line source
Chris@0 1 <?php
Chris@0 2 /**
Chris@0 3 * Class Declaration Test.
Chris@0 4 *
Chris@0 5 * @category PHP
Chris@0 6 * @package PHP_CodeSniffer
Chris@0 7 * @link http://pear.php.net/package/PHP_CodeSniffer
Chris@0 8 */
Chris@0 9
Chris@0 10 /**
Chris@0 11 * Class Declaration Test.
Chris@0 12 *
Chris@0 13 * Checks the declaration of the class is correct.
Chris@0 14 *
Chris@0 15 * @category PHP
Chris@0 16 * @package PHP_CodeSniffer
Chris@0 17 * @link http://pear.php.net/package/PHP_CodeSniffer
Chris@0 18 */
Chris@0 19 class Drupal_Sniffs_Classes_ClassDeclarationSniff extends PSR2_Sniffs_Classes_ClassDeclarationSniff
Chris@0 20 {
Chris@0 21
Chris@0 22
Chris@0 23 /**
Chris@0 24 * Returns an array of tokens this test wants to listen for.
Chris@0 25 *
Chris@0 26 * @return array
Chris@0 27 */
Chris@0 28 public function register()
Chris@0 29 {
Chris@0 30 return array(
Chris@0 31 T_CLASS,
Chris@0 32 T_INTERFACE,
Chris@0 33 T_TRAIT,
Chris@0 34 );
Chris@0 35
Chris@0 36 }//end register()
Chris@0 37
Chris@0 38
Chris@0 39 /**
Chris@0 40 * Processes this test, when one of its tokens is encountered.
Chris@0 41 *
Chris@0 42 * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
Chris@0 43 * @param integer $stackPtr The position of the current token in the
Chris@0 44 * stack passed in $tokens.
Chris@0 45 *
Chris@0 46 * @return void
Chris@0 47 */
Chris@0 48 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
Chris@0 49 {
Chris@0 50 $tokens = $phpcsFile->getTokens();
Chris@0 51 $errorData = array(strtolower($tokens[$stackPtr]['content']));
Chris@0 52
Chris@0 53 if (isset($tokens[$stackPtr]['scope_opener']) === false) {
Chris@0 54 $error = 'Possible parse error: %s missing opening or closing brace';
Chris@0 55 $phpcsFile->addWarning($error, $stackPtr, 'MissingBrace', $errorData);
Chris@0 56 return;
Chris@0 57 }
Chris@0 58
Chris@0 59 $openingBrace = $tokens[$stackPtr]['scope_opener'];
Chris@0 60
Chris@0 61 $next = $phpcsFile->findNext(T_WHITESPACE, ($openingBrace + 1), null, true);
Chris@0 62 if ($tokens[$next]['line'] === $tokens[$openingBrace]['line'] && $tokens[$next]['code'] !== T_CLOSE_CURLY_BRACKET) {
Chris@0 63 $error = 'Opening brace must be the last content on the line';
Chris@0 64 $fix = $phpcsFile->addFixableError($error, $openingBrace, 'ContentAfterBrace');
Chris@0 65 if ($fix === true) {
Chris@0 66 $phpcsFile->fixer->addNewline($openingBrace);
Chris@0 67 }
Chris@0 68 }
Chris@0 69
Chris@0 70 $previous = $phpcsFile->findPrevious(T_WHITESPACE, ($openingBrace - 1), null, true);
Chris@0 71 $decalrationLine = $tokens[$previous]['line'];
Chris@0 72 $braceLine = $tokens[$openingBrace]['line'];
Chris@0 73
Chris@0 74 $lineDifference = ($braceLine - $decalrationLine);
Chris@0 75
Chris@0 76 if ($lineDifference > 0) {
Chris@0 77 $error = 'Opening brace should be on the same line as the declaration';
Chris@0 78 $fix = $phpcsFile->addFixableError($error, $openingBrace, 'BraceOnNewLine');
Chris@0 79 if ($fix === true) {
Chris@0 80 $phpcsFile->fixer->beginChangeset();
Chris@0 81 for ($i = ($previous + 1); $i < $openingBrace; $i++) {
Chris@0 82 $phpcsFile->fixer->replaceToken($i, '');
Chris@0 83 }
Chris@0 84
Chris@0 85 $phpcsFile->fixer->addContent($previous, ' ');
Chris@0 86 $phpcsFile->fixer->endChangeset();
Chris@0 87 }
Chris@0 88
Chris@0 89 return;
Chris@0 90 }
Chris@0 91
Chris@0 92 $openingBrace = $tokens[$stackPtr]['scope_opener'];
Chris@0 93 if ($tokens[($openingBrace - 1)]['code'] !== T_WHITESPACE) {
Chris@0 94 $length = 0;
Chris@0 95 } else if ($tokens[($openingBrace - 1)]['content'] === "\t") {
Chris@0 96 $length = '\t';
Chris@0 97 } else {
Chris@0 98 $length = strlen($tokens[($openingBrace - 1)]['content']);
Chris@0 99 }
Chris@0 100
Chris@0 101 if ($length !== 1) {
Chris@0 102 $error = 'Expected 1 space before opening brace; found %s';
Chris@0 103 $data = array($length);
Chris@0 104 $fix = $phpcsFile->addFixableError($error, $openingBrace, 'SpaceBeforeBrace', $data);
Chris@0 105 if ($fix === true) {
Chris@0 106 if ($length === 0) {
Chris@0 107 $phpcsFile->fixer->replaceToken(($openingBrace), ' {');
Chris@0 108 } else {
Chris@0 109 $phpcsFile->fixer->replaceToken(($openingBrace - 1), ' ');
Chris@0 110 }
Chris@0 111 }
Chris@0 112 }
Chris@0 113
Chris@0 114 // Now call the open spacing method from PSR2.
Chris@0 115 $this->processOpen($phpcsFile, $stackPtr);
Chris@0 116
Chris@0 117 $this->processClose($phpcsFile, $stackPtr);
Chris@0 118
Chris@0 119 }//end process()
Chris@0 120
Chris@0 121
Chris@0 122 /**
Chris@0 123 * Processes the closing section of a class declaration.
Chris@0 124 *
Chris@0 125 * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
Chris@0 126 * @param int $stackPtr The position of the current token
Chris@0 127 * in the stack passed in $tokens.
Chris@0 128 *
Chris@0 129 * @return void
Chris@0 130 */
Chris@0 131 public function processClose(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
Chris@0 132 {
Chris@0 133 $tokens = $phpcsFile->getTokens();
Chris@0 134
Chris@0 135 // Just in case.
Chris@0 136 if (isset($tokens[$stackPtr]['scope_closer']) === false) {
Chris@0 137 return;
Chris@0 138 }
Chris@0 139
Chris@0 140 // Check that the closing brace comes right after the code body.
Chris@0 141 $closeBrace = $tokens[$stackPtr]['scope_closer'];
Chris@0 142 $prevContent = $phpcsFile->findPrevious(T_WHITESPACE, ($closeBrace - 1), null, true);
Chris@0 143 if ($prevContent !== $tokens[$stackPtr]['scope_opener']
Chris@0 144 && $tokens[$prevContent]['line'] !== ($tokens[$closeBrace]['line'] - 2)
Chris@0 145 // If the class only contains a comment no extra line is needed.
Chris@0 146 && isset(PHP_CodeSniffer_Tokens::$commentTokens[$tokens[$prevContent]['code']]) === false
Chris@0 147 ) {
Chris@0 148 $error = 'The closing brace for the %s must have an empty line before it';
Chris@0 149 $data = array($tokens[$stackPtr]['content']);
Chris@0 150 $fix = $phpcsFile->addFixableError($error, $closeBrace, 'CloseBraceAfterBody', $data);
Chris@0 151
Chris@0 152 if ($fix === true) {
Chris@0 153 $phpcsFile->fixer->beginChangeset();
Chris@0 154 for ($i = ($prevContent + 1); $i < $closeBrace; $i++) {
Chris@0 155 $phpcsFile->fixer->replaceToken($i, '');
Chris@0 156 }
Chris@0 157
Chris@0 158 $phpcsFile->fixer->replaceToken($closeBrace, $phpcsFile->eolChar.$phpcsFile->eolChar.$tokens[$closeBrace]['content']);
Chris@0 159
Chris@0 160 $phpcsFile->fixer->endChangeset();
Chris@0 161 }
Chris@0 162 }//end if
Chris@0 163
Chris@0 164 // Check the closing brace is on it's own line, but allow
Chris@0 165 // for comments like "//end class".
Chris@0 166 $nextContent = $phpcsFile->findNext(T_COMMENT, ($closeBrace + 1), null, true);
Chris@0 167 if ($tokens[$nextContent]['content'] !== $phpcsFile->eolChar
Chris@0 168 && $tokens[$nextContent]['line'] === $tokens[$closeBrace]['line']
Chris@0 169 ) {
Chris@0 170 $type = strtolower($tokens[$stackPtr]['content']);
Chris@0 171 $error = 'Closing %s brace must be on a line by itself';
Chris@0 172 $data = array($tokens[$stackPtr]['content']);
Chris@0 173 $phpcsFile->addError($error, $closeBrace, 'CloseBraceSameLine', $data);
Chris@0 174 }
Chris@0 175
Chris@0 176 }//end processClose()
Chris@0 177
Chris@0 178
Chris@0 179 }//end class