Subversion Repositories Applications.framework

Rev

Rev 5 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5 aurelien 1
<?php
2
/**
3
 * An AbstractScopeTest allows for tests that extend from this class to
4
 * listen for tokens within a particluar scope.
5
 *
6
 * PHP version 5
7
 *
8
 * @category  PHP
9
 * @package   PHP_CodeSniffer
10
 * @author    Greg Sherwood <gsherwood@squiz.net>
11
 * @author    Marc McIntyre <mmcintyre@squiz.net>
12
 * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
13
 * @license   http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
34 aurelien 14
 * @version   CVS: $Id: AbstractScopeSniff.php 34 2009-04-09 07:34:39Z aurelien $
5 aurelien 15
 * @link      http://pear.php.net/package/PHP_CodeSniffer
16
 */
17
 
18
/**
19
 * An AbstractScopeTest allows for tests that extend from this class to
20
 * listen for tokens within a particluar scope.
21
 *
22
 * Below is a test that listens to methods that exist only within classes:
23
 * <code>
24
 * class ClassScopeTest extends PHP_CodeSniffer_Standards_AbstractScopeSniff
25
 * {
26
 *     public function __construct()
27
 *     {
28
 *         parent::__construct(array(T_CLASS), array(T_FUNCTION));
29
 *     }
30
 *
31
 *     protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $)
32
 *     {
33
 *         $className = $phpcsFile->getDeclarationName($currScope);
34
 *         echo 'encountered a method within class '.$className;
35
 *     }
36
 * }
37
 * </code>
38
 *
39
 * @category  PHP
40
 * @package   PHP_CodeSniffer
41
 * @author    Greg Sherwood <gsherwood@squiz.net>
42
 * @author    Marc McIntyre <mmcintyre@squiz.net>
43
 * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
44
 * @license   http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
45
 * @version   Release: 1.2.0RC1
46
 * @link      http://pear.php.net/package/PHP_CodeSniffer
47
 */
48
abstract class PHP_CodeSniffer_Standards_AbstractScopeSniff implements PHP_CodeSniffer_Sniff
49
{
50
 
51
    /**
52
     * The token types that this test wishes to listen to within the scope.
53
     *
54
     * @var array()
55
     */
56
    private $_tokens = array();
57
 
58
    /**
59
     * The type of scope opener tokens that this test wishes to listen to.
60
     *
61
     * @var string
62
     */
63
    private $_scopeTokens = array();
64
 
65
    /**
66
     * The position in the tokens array that opened the current scope.
67
     *
68
     * @var array()
69
     */
70
    protected $currScope = null;
71
 
72
    /**
73
     * The current file being checked.
74
     *
75
     * @var string
76
     */
77
    protected $currFile = '';
78
 
79
    /**
80
     * True if this test should fire on tokens outside of the scope.
81
     *
82
     * @var boolean
83
     */
84
    private $_listenOutside = false;
85
 
86
 
87
    /**
88
     * Constructs a new AbstractScopeTest.
89
     *
90
     * @param array   $scopeTokens   The type of scope the test wishes to listen to.
91
     * @param array   $tokens        The tokens that the test wishes to listen to
92
     *                               within the scope.
93
     * @param boolean $listenOutside If true this test will also alert the
94
     *                               extending class when a token is found outside
95
     *                               the scope, by calling the
96
     *                               processTokenOutideScope method.
97
     *
98
     * @see PHP_CodeSniffer.getValidScopeTokeners()
99
     * @throws PHP_CodeSniffer_Test_Exception If the specified tokens array is empty.
100
     */
101
    public function __construct(
102
        array $scopeTokens,
103
        array $tokens,
104
        $listenOutside=false
105
    ) {
106
        if (empty($scopeTokens) === true) {
107
            $error = 'The scope tokens list cannot be empty';
108
            throw new PHP_CodeSniffer_Test_Exception($error);
109
        }
110
 
111
        if (empty($tokens) === true) {
112
            $error = 'The tokens list cannot be empty';
113
            throw new PHP_CodeSniffer_Test_Exception($error);
114
        }
115
 
116
        $invalidScopeTokens = array_intersect($scopeTokens, $tokens);
117
        if (empty($invalidScopeTokens) === false) {
118
            $invalid = implode(', ', $invalidScopeTokens);
119
            $error   = "Scope tokens [$invalid] cant be in the tokens array";
120
            throw new PHP_CodeSniffer_Test_Exception($error);
121
        }
122
 
123
        $this->_listenOutside = $listenOutside;
124
        $this->_scopeTokens   = $scopeTokens;
125
        $this->_tokens        = $tokens;
126
 
127
    }//end __construct()
128
 
129
 
130
    /**
131
     * The method that is called to register the tokens this test wishes to
132
     * listen to.
133
     *
134
     * DO NOT OVERRIDE THIS METHOD. Use the constructor of this class to register
135
     * for the desired tokens and scope.
136
     *
137
     * @return array(int)
138
     * @see __constructor()
139
     */
140
    public final function register()
141
    {
142
        if ($this->_listenOutside === false) {
143
            return $this->_scopeTokens;
144
        } else {
145
            return array_merge($this->_scopeTokens, $this->_tokens);
146
        }
147
 
148
    }//end register()
149
 
150
 
151
    /**
152
     * Processes the tokens that this test is listening for.
153
     *
154
     * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found.
155
     * @param int                  $stackPtr  The position in the stack where this
156
     *                                        token was found.
157
     *
158
     * @return void
159
     * @see processTokenWithinScope()
160
     */
161
    public final function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
162
    {
163
        $file = $phpcsFile->getFilename();
164
        if ($this->currFile !== $file) {
165
            // We have changed files, so clean up.
166
            $this->currScope = null;
167
            $this->currFile  = $file;
168
        }
169
 
170
        $tokens = $phpcsFile->getTokens();
171
 
172
        if (in_array($tokens[$stackPtr]['code'], $this->_scopeTokens) === true) {
173
            $this->currScope = $stackPtr;
174
            $phpcsFile->addTokenListener($this, $this->_tokens);
175
        } else if ($this->currScope !== null
176
            && isset($tokens[$this->currScope]['scope_closer']) === true
177
            && $stackPtr > $tokens[$this->currScope]['scope_closer']
178
        ) {
179
            $this->currScope = null;
180
            if ($this->_listenOutside === true) {
181
                // This is a token outside the current scope, so notify the
182
                // extender as they wish to know about this.
183
                $this->processTokenOutsideScope($phpcsFile, $stackPtr);
184
            } else {
185
                // Don't remove the listener if the extender wants to know about
186
                // tokens that live outside the current scope.
187
                $phpcsFile->removeTokenListener($this, $this->_tokens);
188
            }
189
        } else if ($this->currScope !== null) {
190
            $this->processTokenWithinScope($phpcsFile, $stackPtr, $this->currScope);
191
        } else {
192
            $this->processTokenOutsideScope($phpcsFile, $stackPtr);
193
        }
194
 
195
    }//end process()
196
 
197
 
198
    /**
199
     * Processes a token that is found within the scope that this test is
200
     * listening to.
201
     *
202
     * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found.
203
     * @param int                  $stackPtr  The position in the stack where this
204
     *                                        token was found.
205
     * @param int                  $currScope The position in the tokens array that
206
     *                                        opened the scope that this test is
207
     *                                        listening for.
208
     *
209
     * @return void
210
     */
211
    protected abstract function processTokenWithinScope(
212
        PHP_CodeSniffer_File $phpcsFile,
213
        $stackPtr,
214
        $currScope
215
    );
216
 
217
 
218
    /**
219
     * Processes a token that is found within the scope that this test is
220
     * listening to.
221
     *
222
     * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found.
223
     * @param int                  $stackPtr  The position in the stack where this
224
     *                                        token was found.
225
     *
226
     * @return void
227
     */
228
    protected function processTokenOutsideScope(
229
        PHP_CodeSniffer_File $phpcsFile,
230
        $stackPtr
231
    ) {
232
        return;
233
 
234
    }//end processTokenOutsideScope()
235
 
236
 
237
}//end class
238
 
239
?>