1<?php 2/** 3 * Runs jshint.js on the file. 4 * 5 * @author Greg Sherwood <gsherwood@squiz.net> 6 * @author Alexander Wei§ <aweisswa@gmx.de> 7 * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600) 8 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence 9 */ 10 11namespace PHP_CodeSniffer\Standards\Generic\Sniffs\Debug; 12 13use PHP_CodeSniffer\Config; 14use PHP_CodeSniffer\Files\File; 15use PHP_CodeSniffer\Sniffs\Sniff; 16use PHP_CodeSniffer\Util\Common; 17 18class JSHintSniff implements Sniff 19{ 20 21 /** 22 * A list of tokenizers this sniff supports. 23 * 24 * @var array 25 */ 26 public $supportedTokenizers = ['JS']; 27 28 29 /** 30 * Returns the token types that this sniff is interested in. 31 * 32 * @return int[] 33 */ 34 public function register() 35 { 36 return [T_OPEN_TAG]; 37 38 }//end register() 39 40 41 /** 42 * Processes the tokens that this sniff is interested in. 43 * 44 * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where the token was found. 45 * @param int $stackPtr The position in the stack where 46 * the token was found. 47 * 48 * @return void 49 * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If jshint.js could not be run 50 */ 51 public function process(File $phpcsFile, $stackPtr) 52 { 53 $rhinoPath = Config::getExecutablePath('rhino'); 54 $jshintPath = Config::getExecutablePath('jshint'); 55 if ($rhinoPath === null && $jshintPath === null) { 56 return; 57 } 58 59 $fileName = $phpcsFile->getFilename(); 60 $jshintPath = Common::escapeshellcmd($jshintPath); 61 62 if ($rhinoPath !== null) { 63 $rhinoPath = Common::escapeshellcmd($rhinoPath); 64 $cmd = "$rhinoPath \"$jshintPath\" ".escapeshellarg($fileName); 65 exec($cmd, $output, $retval); 66 67 $regex = '`^(?P<error>.+)\(.+:(?P<line>[0-9]+).*:[0-9]+\)$`'; 68 } else { 69 $cmd = "$jshintPath ".escapeshellarg($fileName); 70 exec($cmd, $output, $retval); 71 72 $regex = '`^(.+?): line (?P<line>[0-9]+), col [0-9]+, (?P<error>.+)$`'; 73 } 74 75 if (is_array($output) === true) { 76 foreach ($output as $finding) { 77 $matches = []; 78 $numMatches = preg_match($regex, $finding, $matches); 79 if ($numMatches === 0) { 80 continue; 81 } 82 83 $line = (int) $matches['line']; 84 $message = 'jshint says: '.trim($matches['error']); 85 $phpcsFile->addWarningOnLine($message, $line, 'ExternalTool'); 86 } 87 } 88 89 // Ignore the rest of the file. 90 return ($phpcsFile->numTokens + 1); 91 92 }//end process() 93 94 95}//end class 96