1<?php
2/**
3 * Generic_Sniffs_Debug_ClosureLinterSniff.
4 *
5 * PHP version 5
6 *
7 * @category  PHP
8 * @package   PHP_CodeSniffer
9 * @author    Greg Sherwood <gsherwood@squiz.net>
10 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
11 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12 * @link      http://pear.php.net/package/PHP_CodeSniffer
13 */
14
15/**
16 * Generic_Sniffs_Debug_ClosureLinterSniff.
17 *
18 * Runs gjslint on the file.
19 *
20 * @category  PHP
21 * @package   PHP_CodeSniffer
22 * @author    Greg Sherwood <gsherwood@squiz.net>
23 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
24 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
25 * @version   Release: @package_version@
26 * @link      http://pear.php.net/package/PHP_CodeSniffer
27 */
28class Generic_Sniffs_Debug_ClosureLinterSniff implements PHP_CodeSniffer_Sniff
29{
30
31    /**
32     * A list of error codes that should show errors.
33     *
34     * All other error codes will show warnings.
35     *
36     * @var int
37     */
38    public $errorCodes = array();
39
40    /**
41     * A list of error codes to ignore.
42     *
43     * @var int
44     */
45    public $ignoreCodes = array();
46
47    /**
48     * A list of tokenizers this sniff supports.
49     *
50     * @var array
51     */
52    public $supportedTokenizers = array('JS');
53
54
55    /**
56     * Returns the token types that this sniff is interested in.
57     *
58     * @return int[]
59     */
60    public function register()
61    {
62        return array(T_OPEN_TAG);
63
64    }//end register()
65
66
67    /**
68     * Processes the tokens that this sniff is interested in.
69     *
70     * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
71     * @param int                  $stackPtr  The position in the stack where
72     *                                        the token was found.
73     *
74     * @return void
75     * @throws PHP_CodeSniffer_Exception If jslint.js could not be run
76     */
77    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
78    {
79        $fileName = $phpcsFile->getFilename();
80
81        $lintPath = PHP_CodeSniffer::getConfigData('gjslint_path');
82        if ($lintPath === null) {
83            return;
84        }
85
86        $lintPath = escapeshellcmd($lintPath);
87        $cmd      = '$lintPath --nosummary --notime --unix_mode '.escapeshellarg($fileName);
88        $msg      = exec($cmd, $output, $retval);
89
90        if (is_array($output) === false) {
91            return;
92        }
93
94        foreach ($output as $finding) {
95            $matches    = array();
96            $numMatches = preg_match('/^(.*):([0-9]+):\(.*?([0-9]+)\)(.*)$/', $finding, $matches);
97            if ($numMatches === 0) {
98                continue;
99            }
100
101            // Skip error codes we are ignoring.
102            $code = $matches[3];
103            if (in_array($code, $this->ignoreCodes) === true) {
104                continue;
105            }
106
107            $line  = (int) $matches[2];
108            $error = trim($matches[4]);
109
110            $message = 'gjslint says: (%s) %s';
111            $data    = array(
112                        $code,
113                        $error,
114                       );
115            if (in_array($code, $this->errorCodes) === true) {
116                $phpcsFile->addErrorOnLine($message, $line, 'ExternalToolError', $data);
117            } else {
118                $phpcsFile->addWarningOnLine($message, $line, 'ExternalTool', $data);
119            }
120        }//end foreach
121
122        // Ignore the rest of the file.
123        return ($phpcsFile->numTokens + 1);
124
125    }//end process()
126
127
128}//end class
129