3
* Squiz_Sniffs_PHP_DisallowMultipleAssignmentsSniff.
8
* @package PHP_CodeSniffer
9
* @author Greg Sherwood <gsherwood@squiz.net>
10
* @author Marc McIntyre <mmcintyre@squiz.net>
11
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
12
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
13
* @link http://pear.php.net/package/PHP_CodeSniffer
17
* Squiz_Sniffs_PHP_DisallowMultipleAssignmentsSniff.
19
* Ensures that there is only one value assignment on a line, and that it is
20
* the first thing on the line.
23
* @package PHP_CodeSniffer
24
* @author Greg Sherwood <gsherwood@squiz.net>
25
* @author Marc McIntyre <mmcintyre@squiz.net>
26
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
27
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
28
* @version Release: 1.3.4
29
* @link http://pear.php.net/package/PHP_CodeSniffer
31
class Squiz_Sniffs_PHP_DisallowMultipleAssignmentsSniff implements PHP_CodeSniffer_Sniff
36
* Returns an array of tokens this test wants to listen for.
40
public function register()
42
return array(T_EQUAL);
48
* Processes this test, when one of its tokens is encountered.
50
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
51
* @param int $stackPtr The position of the current token in the
52
* stack passed in $tokens.
56
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
58
$tokens = $phpcsFile->getTokens();
60
// Ignore default value assignments in function definitions.
61
$function = $phpcsFile->findPrevious(T_FUNCTION, ($stackPtr - 1));
62
if ($function !== false) {
63
$opener = $tokens[$function]['parenthesis_opener'];
64
$closer = $tokens[$function]['parenthesis_closer'];
65
if ($opener < $stackPtr && $closer > $stackPtr) {
72
Find an equal sign and go backwards along the line. If you hit an
73
end bracket, skip to the opening bracket. When you find a variable,
74
stop. That variable must be the first non-empty token on the line
75
or in the statement. If not, throw an error.
78
for ($varToken = ($stackPtr - 1); $varToken >= 0; $varToken--) {
80
if (isset($tokens[$varToken]['parenthesis_opener']) === true && $tokens[$varToken]['parenthesis_opener'] < $varToken) {
81
$varToken = $tokens[$varToken]['parenthesis_opener'];
85
if (isset($tokens[$varToken]['bracket_opener']) === true) {
86
$varToken = $tokens[$varToken]['bracket_opener'];
90
if ($tokens[$varToken]['code'] === T_SEMICOLON) {
91
// We've reached the next statement, so we
92
// didn't find a variable.
96
if ($tokens[$varToken]['code'] === T_VARIABLE) {
97
// We found our variable.
102
if ($varToken <= 0) {
103
// Didn't find a variable.
107
// Deal with this type of variable: self::$var by setting the var
108
// token to be "self" rather than "$var".
109
if ($tokens[($varToken - 1)]['code'] === T_DOUBLE_COLON) {
110
$varToken = ($varToken - 2);
113
// Deal with this type of variable: $obj->$var by setting the var
114
// token to be "$obj" rather than "$var".
115
if ($tokens[($varToken - 1)]['code'] === T_OBJECT_OPERATOR) {
116
$varToken = ($varToken - 2);
119
// Deal with this type of variable: $$var by setting the var
120
// token to be "$" rather than "$var".
121
if ($tokens[($varToken - 1)]['content'] === '$') {
125
// Ignore member var definitions.
126
$prev = $phpcsFile->findPrevious(T_WHITESPACE, ($varToken - 1), null, true);
127
if (in_array($tokens[$prev]['code'], PHP_CodeSniffer_Tokens::$scopeModifiers) === true) {
131
if ($tokens[$prev]['code'] === T_STATIC) {
135
// Make sure this variable is the first thing in the statement.
136
$varLine = $tokens[$varToken]['line'];
138
for ($i = ($varToken - 1); $i >= 0; $i--) {
139
if ($tokens[$i]['code'] === T_SEMICOLON) {
140
// We reached the end of the statement.
144
if ($tokens[$i]['code'] === T_INLINE_THEN) {
145
// We reached the end of the inline THEN statement.
149
if ($tokens[$i]['code'] === T_COLON) {
150
$then = $phpcsFile->findPrevious(T_INLINE_THEN, ($i - 1), null, false, null, true);
151
if ($then !== false) {
152
// We reached the end of the inline ELSE statement.
157
if (in_array($tokens[$i]['code'], PHP_CodeSniffer_Tokens::$emptyTokens) === false) {
158
$prevLine = $tokens[$i]['line'];
163
// Ignore the first part of FOR loops as we are allowed to
164
// assign variables there even though the variable is not the
165
// first thing on the line. Also ignore WHILE loops.
166
if ($tokens[$i]['code'] === T_OPEN_PARENTHESIS && isset($tokens[$i]['parenthesis_owner']) === true) {
167
$owner = $tokens[$i]['parenthesis_owner'];
168
if ($tokens[$owner]['code'] === T_FOR || $tokens[$owner]['code'] === T_WHILE) {
173
if ($prevLine === $varLine) {
174
$error = 'Assignments must be the first block of code on a line';
175
$phpcsFile->addError($error, $stackPtr, 'Found');