Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * Squiz_Sniffs_PHP_DisallowMultipleAssignmentsSniff.
4
 *
5
 * PHP version 5
6
 *
7
 * @category  PHP
8
 * @package   PHP_CodeSniffer
9
 * @author    Greg Sherwood <gsherwood@squiz.net>
10
 * @author    Marc McIntyre <mmcintyre@squiz.net>
11
 * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
12
 * @license   http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
13
 * @version   CVS: $Id: DisallowMultipleAssignmentsSniff.php 253707 2008-02-25 00:36:30Z squiz $
14
 * @link      http://pear.php.net/package/PHP_CodeSniffer
15
 */
16
 
17
/**
18
 * Squiz_Sniffs_PHP_DisallowMultipleAssignmentsSniff.
19
 *
20
 * Ensures that there is only one value assignment on a line, and that it is
21
 * the first thing on the line.
22
 *
23
 * @category  PHP
24
 * @package   PHP_CodeSniffer
25
 * @author    Greg Sherwood <gsherwood@squiz.net>
26
 * @author    Marc McIntyre <mmcintyre@squiz.net>
27
 * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
28
 * @license   http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
29
 * @version   Release: 1.2.1
30
 * @link      http://pear.php.net/package/PHP_CodeSniffer
31
 */
32
class Squiz_Sniffs_PHP_DisallowMultipleAssignmentsSniff implements PHP_CodeSniffer_Sniff
33
{
34
 
35
 
36
    /**
37
     * Returns an array of tokens this test wants to listen for.
38
     *
39
     * @return array
40
     */
41
    public function register()
42
    {
43
        return array(T_EQUAL);
44
 
45
    }//end register()
46
 
47
 
48
    /**
49
     * Processes this test, when one of its tokens is encountered.
50
     *
51
     * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
52
     * @param int                  $stackPtr  The position of the current token in the
53
     *                                        stack passed in $tokens.
54
     *
55
     * @return void
56
     */
57
    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
58
    {
59
        $tokens = $phpcsFile->getTokens();
60
 
61
        // Ignore default value assignments in function definitions.
62
        $function = $phpcsFile->findPrevious(T_FUNCTION, ($stackPtr - 1));
63
        if ($function !== false) {
64
            $opener = $tokens[$function]['parenthesis_opener'];
65
            $closer = $tokens[$function]['parenthesis_closer'];
66
            if ($opener < $stackPtr && $closer > $stackPtr) {
67
                return;
68
            }
69
        }
70
 
71
        /*
72
            The general rule is:
73
            Find an equal sign and go backwards along the line. If you hit an
74
            end bracket, skip to the opening bracket. When you find a variable,
75
            stop. That variable must be the first non-empty token on the line
76
            or in the statement. If not, throw an error.
77
        */
78
 
79
        for ($varToken = ($stackPtr - 1); $varToken >= 0; $varToken--) {
80
            // Skip brackets.
81
            if (isset($tokens[$varToken]['parenthesis_opener']) === true && $tokens[$varToken]['parenthesis_opener'] < $varToken) {
82
                $varToken = $tokens[$varToken]['parenthesis_opener'];
83
                continue;
84
            }
85
 
86
            if (isset($tokens[$varToken]['bracket_opener']) === true) {
87
                $varToken = $tokens[$varToken]['bracket_opener'];
88
                continue;
89
            }
90
 
91
            if ($tokens[$varToken]['code'] === T_SEMICOLON) {
92
                // We've reached the next statement, so we
93
                // didn't find a variable.
94
                return;
95
            }
96
 
97
            if ($tokens[$varToken]['code'] === T_VARIABLE) {
98
                // We found our variable.
99
                break;
100
            }
101
        }
102
 
103
        if ($varToken <= 0) {
104
            // Didn't find a variable.
105
            return;
106
        }
107
 
108
        // Deal with this type of variable: self::$var by setting the var
109
        // token to be "self" rather than "$var".
110
        if ($tokens[($varToken - 1)]['code'] === T_DOUBLE_COLON) {
111
            $varToken = ($varToken - 2);
112
        }
113
 
114
        // Deal with this type of variable: $obj->$var by setting the var
115
        // token to be "$obj" rather than "$var".
116
        if ($tokens[($varToken - 1)]['code'] === T_OBJECT_OPERATOR) {
117
            $varToken = ($varToken - 2);
118
        }
119
 
120
        // Deal with this type of variable: $$var by setting the var
121
        // token to be "$" rather than "$var".
122
        if ($tokens[($varToken - 1)]['content'] === '$') {
123
            $varToken--;
124
        }
125
 
126
        // Ignore member var definitions.
127
        $prev = $phpcsFile->findPrevious(T_WHITESPACE, ($varToken - 1), null, true);
128
        if (in_array($tokens[$prev]['code'], PHP_CodeSniffer_Tokens::$scopeModifiers) === true) {
129
            return;
130
        }
131
 
132
        if ($tokens[$prev]['code'] === T_STATIC) {
133
            return;
134
        }
135
 
136
        // Make sure this variable is the first thing in the statement.
137
        $varLine  = $tokens[$varToken]['line'];
138
        $prevLine = 0;
139
        for ($i = ($varToken - 1); $i >= 0; $i--) {
140
            if ($tokens[$i]['code'] === T_SEMICOLON) {
141
                // We reached the end of the statement.
142
                return;
143
            }
144
 
145
            if ($tokens[$i]['code'] === T_INLINE_THEN) {
146
                // We reached the end of the inline THEN statement.
147
                return;
148
            }
149
 
150
            if ($tokens[$i]['code'] === T_COLON) {
151
                $then = $phpcsFile->findPrevious(T_INLINE_THEN, ($i - 1), null, false, null, true);
152
                if ($then !== false) {
153
                    // We reached the end of the inline ELSE statement.
154
                    return;
155
                }
156
            }
157
 
158
            if (in_array($tokens[$i]['code'], PHP_CodeSniffer_Tokens::$emptyTokens) === false) {
159
                $prevLine = $tokens[$i]['line'];
160
                break;
161
            }
162
        }
163
 
164
        // Ignore the first part of FOR loops as we are allowed to
165
        // assign variables there even though the variable is not the
166
        // first thing on the line. Also ignore WHILE loops.
167
        if ($tokens[$i]['code'] === T_OPEN_PARENTHESIS && isset($tokens[$i]['parenthesis_owner']) === true) {
168
            $owner = $tokens[$i]['parenthesis_owner'];
169
            if ($tokens[$owner]['code'] === T_FOR || $tokens[$owner]['code'] === T_WHILE) {
170
                return;
171
            }
172
        }
173
 
174
        if ($prevLine === $varLine) {
175
            $error = 'Assignments must be the first block of code on a line';
176
            $phpcsFile->addError($error, $stackPtr);
177
        }
178
 
179
    }//end process()
180
 
181
 
182
}//end class
183
 
184
?>