annotate vendor/drupal/coder/coder_sniffer/Drupal/Sniffs/Files/EndFileNewlineSniff.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 <?php
Chris@0 2 /**
Chris@17 3 * \Drupal\Sniffs\Files\EndFileNewlineSniff.
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@17 10 namespace Drupal\Sniffs\Files;
Chris@17 11
Chris@17 12 use PHP_CodeSniffer\Files\File;
Chris@17 13 use PHP_CodeSniffer\Sniffs\Sniff;
Chris@17 14
Chris@0 15 /**
Chris@0 16 * Ensures the file ends with a newline character.
Chris@0 17 *
Chris@0 18 * Largely copied from PSR2, but we need to run it on *.txt files and templates as
Chris@0 19 * well.
Chris@0 20 *
Chris@0 21 * @category PHP
Chris@0 22 * @package PHP_CodeSniffer
Chris@0 23 * @link http://pear.php.net/package/PHP_CodeSniffer
Chris@0 24 */
Chris@17 25 class EndFileNewlineSniff implements Sniff
Chris@0 26 {
Chris@0 27
Chris@0 28
Chris@0 29 /**
Chris@0 30 * A list of tokenizers this sniff supports.
Chris@0 31 *
Chris@0 32 * @var array
Chris@0 33 */
Chris@0 34 public $supportedTokenizers = array(
Chris@0 35 'PHP',
Chris@0 36 'JS',
Chris@0 37 'CSS',
Chris@0 38 );
Chris@0 39
Chris@0 40
Chris@0 41 /**
Chris@0 42 * Returns an array of tokens this test wants to listen for.
Chris@0 43 *
Chris@0 44 * @return array
Chris@0 45 */
Chris@0 46 public function register()
Chris@0 47 {
Chris@0 48 return array(
Chris@0 49 T_OPEN_TAG,
Chris@0 50 T_INLINE_HTML,
Chris@0 51 );
Chris@0 52
Chris@0 53 }//end register()
Chris@0 54
Chris@0 55
Chris@0 56 /**
Chris@0 57 * Processes this sniff, when one of its tokens is encountered.
Chris@0 58 *
Chris@17 59 * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
Chris@17 60 * @param int $stackPtr The position of the current token in
Chris@17 61 * the stack passed in $tokens.
Chris@0 62 *
Chris@0 63 * @return void
Chris@0 64 */
Chris@17 65 public function process(File $phpcsFile, $stackPtr)
Chris@0 66 {
Chris@0 67 // Skip to the end of the file.
Chris@0 68 $tokens = $phpcsFile->getTokens();
Chris@0 69 if ($phpcsFile->tokenizerType === 'PHP') {
Chris@0 70 $lastToken = ($phpcsFile->numTokens - 1);
Chris@0 71 } else {
Chris@0 72 // JS and CSS have an artificial token at the end which we have to
Chris@0 73 // ignore.
Chris@0 74 $lastToken = ($phpcsFile->numTokens - 2);
Chris@0 75 }
Chris@0 76
Chris@0 77 // Hard-coding the expected \n in this sniff as it is PSR-2 specific and
Chris@0 78 // PSR-2 enforces the use of unix style newlines.
Chris@0 79 if (substr($tokens[$lastToken]['content'], -1) !== "\n") {
Chris@0 80 $error = 'Expected 1 newline at end of file; 0 found';
Chris@0 81 $fix = $phpcsFile->addFixableError($error, $lastToken, 'NoneFound');
Chris@0 82 if ($fix === true) {
Chris@0 83 $phpcsFile->fixer->addNewline($lastToken);
Chris@0 84 }
Chris@0 85
Chris@0 86 $phpcsFile->recordMetric($stackPtr, 'Number of newlines at EOF', '0');
Chris@0 87 return ($phpcsFile->numTokens + 1);
Chris@0 88 }
Chris@0 89
Chris@0 90 // Go looking for the last non-empty line.
Chris@0 91 $lastLine = $tokens[$lastToken]['line'];
Chris@0 92 if ($tokens[$lastToken]['code'] === T_WHITESPACE) {
Chris@0 93 $lastCode = $phpcsFile->findPrevious(T_WHITESPACE, ($lastToken - 1), null, true);
Chris@0 94 } else if ($tokens[$lastToken]['code'] === T_INLINE_HTML) {
Chris@0 95 $lastCode = $lastToken;
Chris@0 96 while ($lastCode > 0 && trim($tokens[$lastCode]['content']) === '') {
Chris@0 97 $lastCode--;
Chris@0 98 }
Chris@0 99 } else {
Chris@0 100 $lastCode = $lastToken;
Chris@0 101 }
Chris@0 102
Chris@0 103 $lastCodeLine = $tokens[$lastCode]['line'];
Chris@0 104 $blankLines = ($lastLine - $lastCodeLine + 1);
Chris@0 105 $phpcsFile->recordMetric($stackPtr, 'Number of newlines at EOF', $blankLines);
Chris@0 106
Chris@0 107 if ($blankLines > 1) {
Chris@0 108 $error = 'Expected 1 newline at end of file; %s found';
Chris@0 109 $data = array($blankLines);
Chris@0 110 $fix = $phpcsFile->addFixableError($error, $lastCode, 'TooMany', $data);
Chris@0 111
Chris@0 112 if ($fix === true) {
Chris@0 113 $phpcsFile->fixer->beginChangeset();
Chris@0 114 $phpcsFile->fixer->replaceToken($lastCode, rtrim($tokens[$lastCode]['content']));
Chris@0 115 for ($i = ($lastCode + 1); $i < $lastToken; $i++) {
Chris@0 116 $phpcsFile->fixer->replaceToken($i, '');
Chris@0 117 }
Chris@0 118
Chris@0 119 $phpcsFile->fixer->replaceToken($lastToken, $phpcsFile->eolChar);
Chris@0 120 $phpcsFile->fixer->endChangeset();
Chris@0 121 }
Chris@0 122 }
Chris@0 123
Chris@0 124 // Skip the rest of the file.
Chris@0 125 return ($phpcsFile->numTokens + 1);
Chris@0 126
Chris@0 127 }//end process()
Chris@0 128
Chris@0 129
Chris@0 130 }//end class