GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — develop ( 699b70...879176 )
by Chris
13:23
created

WordPress_Sniffs_Arrays_ArrayDeclarationSniff   F

Complexity

Total Complexity 78

Size/Duplication

Total Lines 490
Duplicated Lines 36.94 %

Coupling/Cohesion

Components 0
Dependencies 4

Importance

Changes 0
Metric Value
dl 181
loc 490
rs 2.1126
c 0
b 0
f 0
wmc 78
lcom 0
cbo 4

2 Methods

Rating   Name   Duplication   Size   Complexity  
C processSingleLineArray() 0 56 10
F processMultiLineArray() 181 407 68

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like WordPress_Sniffs_Arrays_ArrayDeclarationSniff often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use WordPress_Sniffs_Arrays_ArrayDeclarationSniff, and based on these observations, apply Extract Interface, too.

1
<?php
1 ignored issue
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 37 and the first side effect is on line 11.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * WordPress Coding Standard.
4
 *
5
 * @package WPCS\WordPressCodingStandards
6
 * @link    https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards
7
 * @license https://opensource.org/licenses/MIT MIT
8
 */
9
10
if ( ! class_exists( 'Squiz_Sniffs_Arrays_ArrayDeclarationSniff', true ) ) {
11
	throw new PHP_CodeSniffer_Exception( 'Class Squiz_Sniffs_Arrays_ArrayDeclarationSniff not found' );
12
}
13
14
/**
15
 * Enforces WordPress array format, based upon Squiz code.
16
 *
17
 * @link    https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#indentation
18
 *
19
 * @package WPCS\WordPressCodingStandards
20
 *
21
 * @since   0.1.0
22
 * @since   0.5.0 Now extends `Squiz_Sniffs_Arrays_ArrayDeclarationSniff`.
23
 *
24
 * @todo    Check whether the upstream PRs have been merged and released and if possible,
25
 *          remove duplicate logic.
26
 *          Ref: commit 3ea49d2b56f248d83bed890f9f5246d67c775d54
27
 *          "The upstream version is similar, except that we exclude a few errors.
28
 *          Unfortunately we have to actually comment out the code rather than just
29
 *          using the upstream sniff and `<exclude>` in our ruleset, due to a bug
30
 *          (squizlabs/PHP_CodeSniffer#582). (I've also included a fix for another
31
 *          bug, squizlabs/PHP_CodeSniffer#584.) Because of this, we cannot yet
32
 *          eliminate duplicated logic from this child sniff."
33
 *
34
 * Last synced with parent class ?[unknown date]? at commit ?[unknown commit]?.
35
 * @link    https://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/Squiz/Sniffs/Arrays/ArrayDeclarationSniff.php
36
 */
37
class WordPress_Sniffs_Arrays_ArrayDeclarationSniff extends Squiz_Sniffs_Arrays_ArrayDeclarationSniff {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
38
39
	/**
40
	 * Process a single line array.
41
	 *
42
	 * @since 0.5.0
43
	 *
44
	 * @param PHP_CodeSniffer_File $phpcsFile  The file being scanned.
45
	 * @param int                  $stackPtr   The position of the current token
46
	 *                                         in the stack passed in $tokens.
47
	 * @param int                  $arrayStart Position of the array opener in the token stack.
48
	 * @param int                  $arrayEnd   Position of the array closer in the token stack.
49
	 */
50
	public function processSingleLineArray( PHP_CodeSniffer_File $phpcsFile, $stackPtr, $arrayStart, $arrayEnd ) {
51
52
		parent::processSingleLineArray( $phpcsFile, $stackPtr, $arrayStart, $arrayEnd );
53
54
		// This array is empty, so the below checks aren't necessary.
55
		if ( ( $arrayStart + 1 ) === $arrayEnd ) {
56
			return;
57
		}
58
59
		$tokens = $phpcsFile->getTokens();
60
61
		// Check that there is a single space after the array opener.
62
		if ( T_WHITESPACE !== $tokens[ ( $arrayStart + 1 ) ]['code'] ) {
63
64
			$warning = 'Missing space after array opener.';
65
			$fix     = $phpcsFile->addFixableError( $warning, $arrayStart, 'NoSpaceAfterOpenParenthesis' );
66
67
			if ( true === $fix ) {
68
				$phpcsFile->fixer->addContent( $arrayStart, ' ' );
69
			}
70
		} elseif ( ' ' !== $tokens[ ( $arrayStart + 1 ) ]['content'] ) {
71
72
			$fix = $phpcsFile->addFixableError(
73
				'Expected 1 space after array opener, found %s.',
74
				$arrayStart,
75
				'SpaceAfterArrayOpener',
76
				strlen( $tokens[ ( $arrayStart + 1 ) ]['content'] )
0 ignored issues
show
Documentation introduced by
strlen($tokens[$arrayStart + 1]['content']) is of type integer, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
77
			);
78
79
			if ( true === $fix ) {
80
				$phpcsFile->fixer->replaceToken( ( $arrayStart + 1 ), ' ' );
81
			}
82
		}
83
84
		if ( T_WHITESPACE !== $tokens[ ( $arrayEnd - 1 ) ]['code'] ) {
85
86
			$warning = 'Missing space before array closer.';
87
			$fix     = $phpcsFile->addFixableError( $warning, $arrayEnd, 'NoSpaceAfterOpenParenthesis' );
88
89
			if ( true === $fix ) {
90
				$phpcsFile->fixer->addContentBefore( $arrayEnd, ' ' );
91
			}
92
		} elseif ( ' ' !== $tokens[ ( $arrayEnd - 1 ) ]['content'] ) {
93
94
			$fix = $phpcsFile->addFixableError(
95
				'Expected 1 space before array closer, found %s.',
96
				$arrayEnd,
97
				'SpaceAfterArrayCloser',
98
				strlen( $tokens[ ( $arrayEnd - 1 ) ]['content'] )
0 ignored issues
show
Documentation introduced by
strlen($tokens[$arrayEnd - 1]['content']) is of type integer, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
99
			);
100
101
			if ( true === $fix ) {
102
				$phpcsFile->fixer->replaceToken( ( $arrayEnd - 1 ), ' ' );
103
			}
104
		}
105
	}
106
107
	/**
108
	 * Process a multi-line array.
109
	 *
110
	 * @since 0.5.0
111
	 *
112
	 * @param PHP_CodeSniffer_File $phpcsFile  The file being scanned.
113
	 * @param int                  $stackPtr   The position of the current token
114
	 *                                         in the stack passed in $tokens.
115
	 * @param int                  $arrayStart Position of the array opener in the token stack.
116
	 * @param int                  $arrayEnd   Position of the array closer in the token stack.
117
	 */
118
	public function processMultiLineArray( PHP_CodeSniffer_File $phpcsFile, $stackPtr, $arrayStart, $arrayEnd ) {
119
		$tokens       = $phpcsFile->getTokens();
120
		$keywordStart = $tokens[ $stackPtr ]['column'];
121
122
		// Check the closing bracket is on a new line.
123
		$lastContent = $phpcsFile->findPrevious( T_WHITESPACE, ( $arrayEnd - 1 ), $arrayStart, true );
124
		if ( $tokens[ $lastContent ]['line'] === $tokens[ $arrayEnd ]['line'] ) {
125
			$error = 'Closing parenthesis of array declaration must be on a new line';
126
			$fix   = $phpcsFile->addFixableError( $error, $arrayEnd, 'CloseBraceNewLine' );
127
			if ( true === $fix ) {
128
				$phpcsFile->fixer->addNewlineBefore( $arrayEnd );
129
			}
130
		} // end if
131
132
		$nextToken  = $stackPtr;
0 ignored issues
show
Unused Code introduced by
$nextToken is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
133
		$keyUsed    = false;
134
		$singleUsed = false;
0 ignored issues
show
Unused Code introduced by
$singleUsed is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
135
		$indices    = array();
136
		$maxLength  = 0;
137
138 View Code Duplication
		if ( T_ARRAY === $tokens[ $stackPtr ]['code'] ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
139
			$lastToken = $tokens[ $stackPtr ]['parenthesis_opener'];
140
		} else {
141
			$lastToken = $stackPtr;
142
		}
143
144
		// Find all the double arrows that reside in this scope.
145
		for ( $nextToken = ( $stackPtr + 1 ); $nextToken < $arrayEnd; $nextToken++ ) {
146
			// Skip bracketed statements, like function calls.
147 View Code Duplication
			if ( T_OPEN_PARENTHESIS === $tokens[ $nextToken ]['code']
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
148
			    && ( ! isset( $tokens[ $nextToken ]['parenthesis_owner'] )
149
			        || $tokens[ $nextToken ]['parenthesis_owner'] !== $stackPtr )
150
			) {
151
				$nextToken = $tokens[ $nextToken ]['parenthesis_closer'];
152
				continue;
153
			}
154
155 View Code Duplication
			if ( T_ARRAY === $tokens[ $nextToken ]['code'] ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
156
				// Let subsequent calls of this test handle nested arrays.
157
				if ( T_DOUBLE_ARROW !== $tokens[ $lastToken ]['code'] ) {
158
					$indices[] = array( 'value' => $nextToken );
159
					$lastToken = $nextToken;
160
				}
161
162
				$nextToken = $tokens[ $tokens[ $nextToken ]['parenthesis_opener'] ]['parenthesis_closer'];
163
				$nextToken = $phpcsFile->findNext( T_WHITESPACE, ( $nextToken + 1 ), null, true );
164
				if ( T_COMMA !== $tokens[ $nextToken ]['code'] ) {
165
					$nextToken--;
166
				} else {
167
					$lastToken = $nextToken;
168
				}
169
170
				continue;
171
			}
172
173 View Code Duplication
			if ( T_OPEN_SHORT_ARRAY === $tokens[ $nextToken ]['code'] ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
174
				// Let subsequent calls of this test handle nested arrays.
175
				if ( T_DOUBLE_ARROW !== $tokens[ $lastToken ]['code'] ) {
176
					$indices[] = array( 'value' => $nextToken );
177
					$lastToken = $nextToken;
178
				}
179
180
				$nextToken = $tokens[ $nextToken ]['bracket_closer'];
181
				$nextToken = $phpcsFile->findNext( T_WHITESPACE, ( $nextToken + 1 ), null, true );
182
				if ( T_COMMA !== $tokens[ $nextToken ]['code'] ) {
183
					$nextToken--;
184
				} else {
185
					$lastToken = $nextToken;
186
				}
187
188
				continue;
189
			}
190
191 View Code Duplication
			if ( T_CLOSURE === $tokens[ $nextToken ]['code'] ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
192
				if ( T_DOUBLE_ARROW !== $tokens[ $lastToken ]['code'] ) {
193
					$indices[] = array( 'value' => $nextToken );
194
					$lastToken = $nextToken;
195
				}
196
197
				$nextToken = $tokens[ $nextToken ]['scope_closer'];
198
				$nextToken = $phpcsFile->findNext( T_WHITESPACE, ( $nextToken + 1 ), null, true );
199
				if ( T_COMMA !== $tokens[ $nextToken ]['code'] ) {
200
					$nextToken--;
201
				} else {
202
					$lastToken = $nextToken;
203
				}
204
205
				continue;
206
			}
207
208 View Code Duplication
			if ( T_DOUBLE_ARROW !== $tokens[ $nextToken ]['code'] && T_COMMA !== $tokens[ $nextToken ]['code'] ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
209
				continue;
210
			}
211
212
			$currentEntry = array();
213
214
			if ( T_COMMA === $tokens[ $nextToken ]['code'] ) {
215
				$stackPtrCount = 0;
216 View Code Duplication
				if ( isset( $tokens[ $stackPtr ]['nested_parenthesis'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
217
					$stackPtrCount = count( $tokens[ $stackPtr ]['nested_parenthesis'] );
218
				}
219
220
				$commaCount = 0;
221
				if ( isset( $tokens[ $nextToken ]['nested_parenthesis'] ) ) {
222
					$commaCount = count( $tokens[ $nextToken ]['nested_parenthesis'] );
223
					if ( T_ARRAY === $tokens[ $stackPtr ]['code'] ) {
224
						// Remove parenthesis that are used to define the array.
225
						$commaCount--;
226
					}
227
				}
228
229
				if ( $commaCount > $stackPtrCount ) {
230
					// This comma is inside more parenthesis than the ARRAY keyword,
231
					// then there it is actually a comma used to separate arguments
232
					// in a function call.
233
					continue;
234
				}
235
236 View Code Duplication
				if ( false === $keyUsed ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
237
					if ( T_WHITESPACE === $tokens[ ( $nextToken - 1 ) ]['code'] ) {
238
						$content = $tokens[ ( $nextToken - 2 ) ]['content'];
239
						if ( $tokens[ ( $nextToken - 1 ) ]['content'] === $phpcsFile->eolChar ) {
240
							$spaceLength = 'newline';
241
						} else {
242
							$spaceLength = $tokens[ ( $nextToken - 1 ) ]['length'];
243
						}
244
245
						$error = 'Expected 0 spaces between "%s" and comma; %s found';
246
						$data  = array(
247
							$content,
248
							$spaceLength,
249
						);
250
251
						$fix = $phpcsFile->addFixableError( $error, $nextToken, 'SpaceBeforeComma', $data );
252
						if ( true === $fix ) {
253
							$phpcsFile->fixer->replaceToken( ( $nextToken - 1 ), '' );
254
						}
255
					}
256
257
					$valueContent = $phpcsFile->findNext(
258
						PHP_CodeSniffer_Tokens::$emptyTokens,
259
						( $lastToken + 1 ),
260
						$nextToken,
261
						true
262
					);
263
264
					$indices[]  = array( 'value' => $valueContent );
265
					$singleUsed = true;
0 ignored issues
show
Unused Code introduced by
$singleUsed is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
266
				} // end if
267
268
				$lastToken = $nextToken;
269
				continue;
270
			} // end if
271
272
			if ( T_DOUBLE_ARROW === $tokens[ $nextToken ]['code'] ) {
273
274
				$currentEntry['arrow'] = $nextToken;
275
				$keyUsed               = true;
276
277
				// Find the start of index that uses this double arrow.
278
				$indexEnd   = $phpcsFile->findPrevious( T_WHITESPACE, ( $nextToken - 1 ), $arrayStart, true );
279
				$indexStart = $phpcsFile->findStartOfStatement( $indexEnd );
0 ignored issues
show
Bug introduced by
It seems like $indexEnd defined by $phpcsFile->findPrevious...- 1, $arrayStart, true) on line 278 can also be of type boolean; however, PHP_CodeSniffer_File::findStartOfStatement() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
280
281 View Code Duplication
				if ( $indexStart === $indexEnd ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
282
					$currentEntry['index']         = $indexEnd;
283
					$currentEntry['index_content'] = $tokens[ $indexEnd ]['content'];
284
				} else {
285
					$currentEntry['index']         = $indexStart;
286
					$currentEntry['index_content'] = $phpcsFile->getTokensAsString( $indexStart, ( $indexEnd - $indexStart + 1 ) );
287
				}
288
289
				$indexLength = strlen( $currentEntry['index_content'] );
290
				if ( $maxLength < $indexLength ) {
291
					$maxLength = $indexLength;
292
				}
293
294
				// Find the value of this index.
295
				$nextContent = $phpcsFile->findNext(
296
					PHP_CodeSniffer_Tokens::$emptyTokens,
297
					( $nextToken + 1 ),
298
					$arrayEnd,
299
					true
300
				);
301
302
				$currentEntry['value'] = $nextContent;
303
				$indices[]             = $currentEntry;
304
				$lastToken             = $nextToken;
305
			} // end if
306
		} // end for
307
308
		// Check for mutli-line arrays that should be single-line.
309
		$singleValue = false;
0 ignored issues
show
Unused Code introduced by
$singleValue is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
310
311 View Code Duplication
		if ( empty( $indices ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
312
			$singleValue = true;
0 ignored issues
show
Unused Code introduced by
$singleValue is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
313
		} elseif ( 1 === count( $indices ) && T_COMMA === $tokens[ $lastToken ]['code'] ) {
314
			// There may be another array value without a comma.
315
			$exclude     = PHP_CodeSniffer_Tokens::$emptyTokens;
316
			$exclude[]   = T_COMMA;
317
			$nextContent = $phpcsFile->findNext( $exclude, ( $indices[0]['value'] + 1 ), $arrayEnd, true );
318
			if ( false === $nextContent ) {
319
				$singleValue = true;
0 ignored issues
show
Unused Code introduced by
$singleValue is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
320
			}
321
		}
322
323
		/*
324
			This section checks for arrays that don't specify keys.
325
326
			Arrays such as:
327
			   array(
328
				'aaa',
329
				'bbb',
330
				'd',
331
			   );
332
		*/
333
334
		if ( false === $keyUsed && ! empty( $indices ) ) {
335
			$count     = count( $indices );
336
			$lastIndex = $indices[ ( $count - 1 ) ]['value'];
337
338
			$trailingContent = $phpcsFile->findPrevious(
339
				PHP_CodeSniffer_Tokens::$emptyTokens,
340
				( $arrayEnd - 1 ),
341
				$lastIndex,
342
				true
343
			);
344
345
			if ( T_COMMA !== $tokens[ $trailingContent ]['code'] ) {
346
				$phpcsFile->recordMetric( $stackPtr, 'Array end comma', 'no' );
347
				$error = 'Comma required after last value in array declaration';
348
				$fix   = $phpcsFile->addFixableError( $error, $trailingContent, 'NoCommaAfterLast' );
0 ignored issues
show
Bug introduced by
It seems like $trailingContent defined by $phpcsFile->findPrevious... - 1, $lastIndex, true) on line 338 can also be of type boolean; however, PHP_CodeSniffer_File::addFixableError() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
349
				if ( true === $fix ) {
350
					$phpcsFile->fixer->addContent( $trailingContent, ',' );
0 ignored issues
show
Bug introduced by
It seems like $trailingContent defined by $phpcsFile->findPrevious... - 1, $lastIndex, true) on line 338 can also be of type boolean; however, PHP_CodeSniffer_Fixer::addContent() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
351
				}
352
			} else {
353
				$phpcsFile->recordMetric( $stackPtr, 'Array end comma', 'yes' );
354
			}
355
356
			$lastValueLine = false;
357
			foreach ( $indices as $value ) {
358
				if ( empty( $value['value'] ) ) {
359
					// Array was malformed and we couldn't figure out
360
					// the array value correctly, so we have to ignore it.
361
					// Other parts of this sniff will correct the error.
362
					continue;
363
				}
364
365
				if ( false !== $lastValueLine && $tokens[ $value['value'] ]['line'] === $lastValueLine ) {
366
					$error = 'Each value in a multi-line array must be on a new line';
367
					$fix   = $phpcsFile->addFixableError( $error, $value['value'], 'ValueNoNewline' );
368
					if ( true === $fix ) {
369
						if ( T_WHITESPACE === $tokens[ ( $value['value'] - 1 ) ]['code'] ) {
370
							$phpcsFile->fixer->replaceToken( ( $value['value'] - 1 ), '' );
371
						}
372
373
						$phpcsFile->fixer->addNewlineBefore( $value['value'] );
374
					}
375
				} // end if
376
377
				$lastValueLine = $tokens[ $value['value'] ]['line'];
378
			} // end foreach
379
		} // end if
380
381
		/*
382
			Below the actual indentation of the array is checked.
383
			Errors will be thrown when a key is not aligned, when
384
			a double arrow is not aligned, and when a value is not
385
			aligned correctly.
386
			If an error is found in one of the above areas, then errors
387
			are not reported for the rest of the line to avoid reporting
388
			spaces and columns incorrectly. Often fixing the first
389
			problem will fix the other 2 anyway.
390
391
			For example:
392
393
			$a = array(
394
				  'index'  => '2',
395
				 );
396
397
			or
398
399
			$a = [
400
				  'index'  => '2',
401
				 ];
402
403
			In this array, the double arrow is indented too far, but this
404
			will also cause an error in the value's alignment. If the arrow were
405
			to be moved back one space however, then both errors would be fixed.
406
		 */
407
408
		$numValues = count( $indices );
409
410
		$indicesStart  = ( $keywordStart + 1 );
411
		$arrowStart    = ( $indicesStart + $maxLength + 1 );
412
		$valueStart    = ( $arrowStart + 3 );
0 ignored issues
show
Unused Code introduced by
$valueStart is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
413
		$indexLine     = $tokens[ $stackPtr ]['line'];
414
		$lastIndexLine = null;
0 ignored issues
show
Unused Code introduced by
$lastIndexLine is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
415
		foreach ( $indices as $index ) {
416 View Code Duplication
			if ( ! isset( $index['index'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
417
				// Array value only.
418
				if ( $tokens[ $index['value'] ]['line'] === $tokens[ $stackPtr ]['line'] && $numValues > 1 ) {
419
					$error = 'The first value in a multi-value array must be on a new line';
420
					$fix   = $phpcsFile->addFixableError( $error, $stackPtr, 'FirstValueNoNewline' );
421
					if ( true === $fix ) {
422
						$phpcsFile->fixer->addNewlineBefore( $index['value'] );
423
					}
424
				}
425
426
				continue;
427
			}
428
429
			$lastIndexLine = $indexLine;
430
			$indexLine     = $tokens[ $index['index'] ]['line'];
431
432
			if ( $indexLine === $tokens[ $stackPtr ]['line'] ) {
433
				$error = 'The first index in a multi-value array must be on a new line';
434
				$fix   = $phpcsFile->addFixableError( $error, $index['index'], 'FirstIndexNoNewline' );
435
				if ( true === $fix ) {
436
					$phpcsFile->fixer->addNewlineBefore( $index['index'] );
437
				}
438
439
				continue;
440
			}
441
442 View Code Duplication
			if ( $indexLine === $lastIndexLine ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
443
				$error = 'Each index in a multi-line array must be on a new line';
444
				$fix   = $phpcsFile->addFixableError( $error, $index['index'], 'IndexNoNewline' );
445
				if ( true === $fix ) {
446
					if ( T_WHITESPACE === $tokens[ ( $index['index'] - 1 ) ]['code'] ) {
447
						$phpcsFile->fixer->replaceToken( ( $index['index'] - 1 ), '' );
448
					}
449
450
					$phpcsFile->fixer->addNewlineBefore( $index['index'] );
451
				}
452
453
				continue;
454
			}
455
456
			// Check each line ends in a comma.
457
			$valueLine = $tokens[ $index['value'] ]['line'];
458
			$nextComma = false;
459
			for ( $i = $index['value']; $i < $arrayEnd; $i++ ) {
460
				// Skip bracketed statements, like function calls.
461 View Code Duplication
				if ( T_OPEN_PARENTHESIS === $tokens[ $i ]['code'] ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
462
					$i         = $tokens[ $i ]['parenthesis_closer'];
463
					$valueLine = $tokens[ $i ]['line'];
464
					continue;
465
				}
466
467
				if ( T_ARRAY === $tokens[ $i ]['code'] ) {
468
					$i         = $tokens[ $tokens[ $i ]['parenthesis_opener'] ]['parenthesis_closer'];
469
					$valueLine = $tokens[ $i ]['line'];
470
					continue;
471
				}
472
473 View Code Duplication
				if ( T_OPEN_SHORT_ARRAY === $tokens[ $i ]['code'] ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
474
					$i         = $tokens[ $i ]['bracket_closer'];
475
					$valueLine = $tokens[ $i ]['line'];
476
					continue;
477
				}
478
479 View Code Duplication
				if ( T_CLOSURE === $tokens[ $i ]['code'] ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
480
					$i         = $tokens[ $i ]['scope_closer'];
481
					$valueLine = $tokens[ $i ]['line'];
482
					continue;
483
				}
484
485
				if ( T_COMMA === $tokens[ $i ]['code'] ) {
486
					$nextComma = $i;
487
					break;
488
				}
489
			} // End for.
490
491
			if ( false === $nextComma ) {
492
				$error = 'Each line in an array declaration must end in a comma';
493
				$fix   = $phpcsFile->addFixableError( $error, $index['value'], 'NoComma' );
494
495 View Code Duplication
				if ( true === $fix ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
496
					// Find the end of the line and put a comma there.
497
					for ( $i = ( $index['value'] + 1 ); $i < $phpcsFile->numTokens; $i++ ) {
498
						if ( $tokens[ $i ]['line'] > $valueLine ) {
499
							break;
500
						}
501
					}
502
503
					$phpcsFile->fixer->addContentBefore( ( $i - 1 ), ',' );
504
				}
505
			}
506
507
			// Check that there is no space before the comma.
508 View Code Duplication
			if ( false !== $nextComma && T_WHITESPACE === $tokens[ ( $nextComma - 1 ) ]['code'] ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
509
				$content     = $tokens[ ( $nextComma - 2 ) ]['content'];
510
				$spaceLength = $tokens[ ( $nextComma - 1 ) ]['length'];
511
				$error       = 'Expected 0 spaces between "%s" and comma; %s found';
512
				$data        = array(
513
					$content,
514
					$spaceLength,
515
				);
516
517
				$fix = $phpcsFile->addFixableError( $error, $nextComma, 'SpaceBeforeComma', $data );
518
				if ( true === $fix ) {
519
					$phpcsFile->fixer->replaceToken( ( $nextComma - 1 ), '' );
520
				}
521
			}
522
		} // end foreach
523
524
	} // end processMultiLineArray()
525
526
} // End class.
527