Completed
Pull Request — develop (#1492)
by Zack
33:18 queued 12:17
created
PHPCompatibility/Sniffs/ControlStructures/NewListInForeachSniff.php 1 patch
Indentation   +43 added lines, -43 removed lines patch added patch discarded remove patch
@@ -26,54 +26,54 @@
 block discarded – undo
26 26
 class NewListInForeachSniff extends Sniff
27 27
 {
28 28
 
29
-    /**
30
-     * Returns an array of tokens this test wants to listen for.
31
-     *
32
-     * @return array
33
-     */
34
-    public function register()
35
-    {
36
-        return array(\T_FOREACH);
37
-    }
29
+	/**
30
+	 * Returns an array of tokens this test wants to listen for.
31
+	 *
32
+	 * @return array
33
+	 */
34
+	public function register()
35
+	{
36
+		return array(\T_FOREACH);
37
+	}
38 38
 
39
-    /**
40
-     * Processes this test, when one of its tokens is encountered.
41
-     *
42
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
43
-     * @param int                   $stackPtr  The position of the current token in the
44
-     *                                         stack passed in $tokens.
45
-     *
46
-     * @return void
47
-     */
48
-    public function process(File $phpcsFile, $stackPtr)
49
-    {
50
-        if ($this->supportsBelow('5.4') === false) {
51
-            return;
52
-        }
39
+	/**
40
+	 * Processes this test, when one of its tokens is encountered.
41
+	 *
42
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
43
+	 * @param int                   $stackPtr  The position of the current token in the
44
+	 *                                         stack passed in $tokens.
45
+	 *
46
+	 * @return void
47
+	 */
48
+	public function process(File $phpcsFile, $stackPtr)
49
+	{
50
+		if ($this->supportsBelow('5.4') === false) {
51
+			return;
52
+		}
53 53
 
54
-        $tokens = $phpcsFile->getTokens();
54
+		$tokens = $phpcsFile->getTokens();
55 55
 
56
-        if (isset($tokens[$stackPtr]['parenthesis_opener'], $tokens[$stackPtr]['parenthesis_closer']) === false) {
57
-            return;
58
-        }
56
+		if (isset($tokens[$stackPtr]['parenthesis_opener'], $tokens[$stackPtr]['parenthesis_closer']) === false) {
57
+			return;
58
+		}
59 59
 
60
-        $opener = $tokens[$stackPtr]['parenthesis_opener'];
61
-        $closer = $tokens[$stackPtr]['parenthesis_closer'];
60
+		$opener = $tokens[$stackPtr]['parenthesis_opener'];
61
+		$closer = $tokens[$stackPtr]['parenthesis_closer'];
62 62
 
63
-        $asToken = $phpcsFile->findNext(\T_AS, ($opener + 1), $closer);
64
-        if ($asToken === false) {
65
-            return;
66
-        }
63
+		$asToken = $phpcsFile->findNext(\T_AS, ($opener + 1), $closer);
64
+		if ($asToken === false) {
65
+			return;
66
+		}
67 67
 
68
-        $hasList = $phpcsFile->findNext(array(\T_LIST, \T_OPEN_SHORT_ARRAY), ($asToken + 1), $closer);
69
-        if ($hasList === false) {
70
-            return;
71
-        }
68
+		$hasList = $phpcsFile->findNext(array(\T_LIST, \T_OPEN_SHORT_ARRAY), ($asToken + 1), $closer);
69
+		if ($hasList === false) {
70
+			return;
71
+		}
72 72
 
73
-        $phpcsFile->addError(
74
-            'Unpacking nested arrays with list() in a foreach is not supported in PHP 5.4 or earlier.',
75
-            $hasList,
76
-            'Found'
77
-        );
78
-    }
73
+		$phpcsFile->addError(
74
+			'Unpacking nested arrays with list() in a foreach is not supported in PHP 5.4 or earlier.',
75
+			$hasList,
76
+			'Found'
77
+		);
78
+	}
79 79
 }
Please login to merge, or discard this patch.
Sniffs/ControlStructures/NewForeachExpressionReferencingSniff.php 1 patch
Indentation   +52 added lines, -52 removed lines patch added patch discarded remove patch
@@ -29,68 +29,68 @@
 block discarded – undo
29 29
 class NewForeachExpressionReferencingSniff extends Sniff
30 30
 {
31 31
 
32
-    /**
33
-     * Returns an array of tokens this test wants to listen for.
34
-     *
35
-     * @return array
36
-     */
37
-    public function register()
38
-    {
39
-        return array(\T_FOREACH);
40
-    }
32
+	/**
33
+	 * Returns an array of tokens this test wants to listen for.
34
+	 *
35
+	 * @return array
36
+	 */
37
+	public function register()
38
+	{
39
+		return array(\T_FOREACH);
40
+	}
41 41
 
42
-    /**
43
-     * Processes this test, when one of its tokens is encountered.
44
-     *
45
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
46
-     * @param int                   $stackPtr  The position of the current token in the
47
-     *                                         stack passed in $tokens.
48
-     *
49
-     * @return void
50
-     */
51
-    public function process(File $phpcsFile, $stackPtr)
52
-    {
53
-        if ($this->supportsBelow('5.4') === false) {
54
-            return;
55
-        }
42
+	/**
43
+	 * Processes this test, when one of its tokens is encountered.
44
+	 *
45
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
46
+	 * @param int                   $stackPtr  The position of the current token in the
47
+	 *                                         stack passed in $tokens.
48
+	 *
49
+	 * @return void
50
+	 */
51
+	public function process(File $phpcsFile, $stackPtr)
52
+	{
53
+		if ($this->supportsBelow('5.4') === false) {
54
+			return;
55
+		}
56 56
 
57
-        $tokens = $phpcsFile->getTokens();
57
+		$tokens = $phpcsFile->getTokens();
58 58
 
59
-        if (isset($tokens[$stackPtr]['parenthesis_opener'], $tokens[$stackPtr]['parenthesis_closer']) === false) {
60
-            return;
61
-        }
59
+		if (isset($tokens[$stackPtr]['parenthesis_opener'], $tokens[$stackPtr]['parenthesis_closer']) === false) {
60
+			return;
61
+		}
62 62
 
63
-        $opener = $tokens[$stackPtr]['parenthesis_opener'];
64
-        $closer = $tokens[$stackPtr]['parenthesis_closer'];
63
+		$opener = $tokens[$stackPtr]['parenthesis_opener'];
64
+		$closer = $tokens[$stackPtr]['parenthesis_closer'];
65 65
 
66
-        $asToken = $phpcsFile->findNext(\T_AS, ($opener + 1), $closer);
67
-        if ($asToken === false) {
68
-            return;
69
-        }
66
+		$asToken = $phpcsFile->findNext(\T_AS, ($opener + 1), $closer);
67
+		if ($asToken === false) {
68
+			return;
69
+		}
70 70
 
71
-        /*
71
+		/*
72 72
          * Note: referencing $key is not allowed in any version, so this should only find referenced $values.
73 73
          * If it does find a referenced key, it would be a parse error anyway.
74 74
          */
75
-        $hasReference = $phpcsFile->findNext(\T_BITWISE_AND, ($asToken + 1), $closer);
76
-        if ($hasReference === false) {
77
-            return;
78
-        }
75
+		$hasReference = $phpcsFile->findNext(\T_BITWISE_AND, ($asToken + 1), $closer);
76
+		if ($hasReference === false) {
77
+			return;
78
+		}
79 79
 
80
-        $nestingLevel = 0;
81
-        if ($asToken !== ($opener + 1) && isset($tokens[$opener + 1]['nested_parenthesis'])) {
82
-            $nestingLevel = \count($tokens[$opener + 1]['nested_parenthesis']);
83
-        }
80
+		$nestingLevel = 0;
81
+		if ($asToken !== ($opener + 1) && isset($tokens[$opener + 1]['nested_parenthesis'])) {
82
+			$nestingLevel = \count($tokens[$opener + 1]['nested_parenthesis']);
83
+		}
84 84
 
85
-        if ($this->isVariable($phpcsFile, ($opener + 1), $asToken, $nestingLevel) === true) {
86
-            return;
87
-        }
85
+		if ($this->isVariable($phpcsFile, ($opener + 1), $asToken, $nestingLevel) === true) {
86
+			return;
87
+		}
88 88
 
89
-        // Non-variable detected before the `as` keyword.
90
-        $phpcsFile->addError(
91
-            'Referencing $value is only possible if the iterated array is a variable in PHP 5.4 or earlier.',
92
-            $hasReference,
93
-            'Found'
94
-        );
95
-    }
89
+		// Non-variable detected before the `as` keyword.
90
+		$phpcsFile->addError(
91
+			'Referencing $value is only possible if the iterated array is a variable in PHP 5.4 or earlier.',
92
+			$hasReference,
93
+			'Found'
94
+		);
95
+	}
96 96
 }
Please login to merge, or discard this patch.
PHPCompatibility/Sniffs/ControlStructures/NewExecutionDirectivesSniff.php 1 patch
Indentation   +307 added lines, -307 removed lines patch added patch discarded remove patch
@@ -24,311 +24,311 @@
 block discarded – undo
24 24
 class NewExecutionDirectivesSniff extends AbstractNewFeatureSniff
25 25
 {
26 26
 
27
-    /**
28
-     * A list of new execution directives
29
-     *
30
-     * The array lists : version number with false (not present) or true (present).
31
-     * If the execution order is conditional, add the condition as a string to the version nr.
32
-     * If's sufficient to list the first version where the execution directive appears.
33
-     *
34
-     * @var array(string => array(string => int|string|null))
35
-     */
36
-    protected $newDirectives = array(
37
-        'ticks' => array(
38
-            '3.1' => false,
39
-            '4.0' => true,
40
-            'valid_value_callback' => 'isNumeric',
41
-        ),
42
-        'encoding' => array(
43
-            '5.2' => false,
44
-            '5.3' => '--enable-zend-multibyte', // Directive ignored unless.
45
-            '5.4' => true,
46
-            'valid_value_callback' => 'validEncoding',
47
-        ),
48
-        'strict_types' => array(
49
-            '5.6' => false,
50
-            '7.0' => true,
51
-            'valid_values' => array(1),
52
-        ),
53
-    );
54
-
55
-
56
-    /**
57
-     * Tokens to ignore when trying to find the value for the directive.
58
-     *
59
-     * @var array
60
-     */
61
-    protected $ignoreTokens = array();
62
-
63
-
64
-    /**
65
-     * Returns an array of tokens this test wants to listen for.
66
-     *
67
-     * @return array
68
-     */
69
-    public function register()
70
-    {
71
-        $this->ignoreTokens           = Tokens::$emptyTokens;
72
-        $this->ignoreTokens[\T_EQUAL] = \T_EQUAL;
73
-
74
-        return array(\T_DECLARE);
75
-    }
76
-
77
-
78
-    /**
79
-     * Processes this test, when one of its tokens is encountered.
80
-     *
81
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
82
-     * @param int                   $stackPtr  The position of the current token in
83
-     *                                         the stack passed in $tokens.
84
-     *
85
-     * @return void
86
-     */
87
-    public function process(File $phpcsFile, $stackPtr)
88
-    {
89
-        $tokens = $phpcsFile->getTokens();
90
-
91
-        if (isset($tokens[$stackPtr]['parenthesis_opener'], $tokens[$stackPtr]['parenthesis_closer']) === true) {
92
-            $openParenthesis  = $tokens[$stackPtr]['parenthesis_opener'];
93
-            $closeParenthesis = $tokens[$stackPtr]['parenthesis_closer'];
94
-        } else {
95
-            if (version_compare(PHPCSHelper::getVersion(), '2.3.4', '>=')) {
96
-                return;
97
-            }
98
-
99
-            // Deal with PHPCS 2.3.0-2.3.3 which do not yet set the parenthesis properly for declare statements.
100
-            $openParenthesis = $phpcsFile->findNext(\T_OPEN_PARENTHESIS, ($stackPtr + 1), null, false, null, true);
101
-            if ($openParenthesis === false || isset($tokens[$openParenthesis]['parenthesis_closer']) === false) {
102
-                return;
103
-            }
104
-            $closeParenthesis = $tokens[$openParenthesis]['parenthesis_closer'];
105
-        }
106
-
107
-        $directivePtr = $phpcsFile->findNext(\T_STRING, ($openParenthesis + 1), $closeParenthesis, false);
108
-        if ($directivePtr === false) {
109
-            return;
110
-        }
111
-
112
-        $directiveContent = $tokens[$directivePtr]['content'];
113
-
114
-        if (isset($this->newDirectives[$directiveContent]) === false) {
115
-            $error = 'Declare can only be used with the directives %s. Found: %s';
116
-            $data  = array(
117
-                implode(', ', array_keys($this->newDirectives)),
118
-                $directiveContent,
119
-            );
120
-
121
-            $phpcsFile->addError($error, $stackPtr, 'InvalidDirectiveFound', $data);
122
-
123
-        } else {
124
-            // Check for valid directive for version.
125
-            $itemInfo = array(
126
-                'name'   => $directiveContent,
127
-            );
128
-            $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
129
-
130
-            // Check for valid directive value.
131
-            $valuePtr = $phpcsFile->findNext($this->ignoreTokens, $directivePtr + 1, $closeParenthesis, true);
132
-            if ($valuePtr === false) {
133
-                return;
134
-            }
135
-
136
-            $this->addWarningOnInvalidValue($phpcsFile, $valuePtr, $directiveContent);
137
-        }
138
-    }
139
-
140
-
141
-    /**
142
-     * Determine whether an error/warning should be thrown for an item based on collected information.
143
-     *
144
-     * @param array $errorInfo Detail information about an item.
145
-     *
146
-     * @return bool
147
-     */
148
-    protected function shouldThrowError(array $errorInfo)
149
-    {
150
-        return ($errorInfo['not_in_version'] !== '' || $errorInfo['conditional_version'] !== '');
151
-    }
152
-
153
-
154
-    /**
155
-     * Get the relevant sub-array for a specific item from a multi-dimensional array.
156
-     *
157
-     * @param array $itemInfo Base information about the item.
158
-     *
159
-     * @return array Version and other information about the item.
160
-     */
161
-    public function getItemArray(array $itemInfo)
162
-    {
163
-        return $this->newDirectives[$itemInfo['name']];
164
-    }
165
-
166
-
167
-    /**
168
-     * Get an array of the non-PHP-version array keys used in a sub-array.
169
-     *
170
-     * @return array
171
-     */
172
-    protected function getNonVersionArrayKeys()
173
-    {
174
-        return array(
175
-            'valid_value_callback',
176
-            'valid_values',
177
-        );
178
-    }
179
-
180
-
181
-    /**
182
-     * Retrieve the relevant detail (version) information for use in an error message.
183
-     *
184
-     * @param array $itemArray Version and other information about the item.
185
-     * @param array $itemInfo  Base information about the item.
186
-     *
187
-     * @return array
188
-     */
189
-    public function getErrorInfo(array $itemArray, array $itemInfo)
190
-    {
191
-        $errorInfo                        = parent::getErrorInfo($itemArray, $itemInfo);
192
-        $errorInfo['conditional_version'] = '';
193
-        $errorInfo['condition']           = '';
194
-
195
-        $versionArray = $this->getVersionArray($itemArray);
196
-
197
-        if (empty($versionArray) === false) {
198
-            foreach ($versionArray as $version => $present) {
199
-                if (\is_string($present) === true && $this->supportsBelow($version) === true) {
200
-                    // We cannot test for compilation option (ok, except by scraping the output of phpinfo...).
201
-                    $errorInfo['conditional_version'] = $version;
202
-                    $errorInfo['condition']           = $present;
203
-                }
204
-            }
205
-        }
206
-
207
-        return $errorInfo;
208
-    }
209
-
210
-
211
-    /**
212
-     * Get the error message template for this sniff.
213
-     *
214
-     * @return string
215
-     */
216
-    protected function getErrorMsgTemplate()
217
-    {
218
-        return 'Directive ' . parent::getErrorMsgTemplate();
219
-    }
220
-
221
-
222
-    /**
223
-     * Generates the error or warning for this item.
224
-     *
225
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
226
-     * @param int                   $stackPtr  The position of the relevant token in
227
-     *                                         the stack.
228
-     * @param array                 $itemInfo  Base information about the item.
229
-     * @param array                 $errorInfo Array with detail (version) information
230
-     *                                         relevant to the item.
231
-     *
232
-     * @return void
233
-     */
234
-    public function addError(File $phpcsFile, $stackPtr, array $itemInfo, array $errorInfo)
235
-    {
236
-        if ($errorInfo['not_in_version'] !== '') {
237
-            parent::addError($phpcsFile, $stackPtr, $itemInfo, $errorInfo);
238
-        } elseif ($errorInfo['conditional_version'] !== '') {
239
-            $error     = 'Directive %s is present in PHP version %s but will be disregarded unless PHP is compiled with %s';
240
-            $errorCode = $this->stringToErrorCode($itemInfo['name']) . 'WithConditionFound';
241
-            $data      = array(
242
-                $itemInfo['name'],
243
-                $errorInfo['conditional_version'],
244
-                $errorInfo['condition'],
245
-            );
246
-
247
-            $phpcsFile->addWarning($error, $stackPtr, $errorCode, $data);
248
-        }
249
-    }
250
-
251
-
252
-    /**
253
-     * Generates a error or warning for this sniff.
254
-     *
255
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
256
-     * @param int                   $stackPtr  The position of the execution directive value
257
-     *                                         in the token array.
258
-     * @param string                $directive The directive.
259
-     *
260
-     * @return void
261
-     */
262
-    protected function addWarningOnInvalidValue(File $phpcsFile, $stackPtr, $directive)
263
-    {
264
-        $tokens = $phpcsFile->getTokens();
265
-
266
-        $value = $tokens[$stackPtr]['content'];
267
-        if (isset(Tokens::$stringTokens[$tokens[$stackPtr]['code']]) === true) {
268
-            $value = $this->stripQuotes($value);
269
-        }
270
-
271
-        $isError = false;
272
-        if (isset($this->newDirectives[$directive]['valid_values'])) {
273
-            if (\in_array($value, $this->newDirectives[$directive]['valid_values']) === false) {
274
-                $isError = true;
275
-            }
276
-        } elseif (isset($this->newDirectives[$directive]['valid_value_callback'])) {
277
-            $valid = \call_user_func(array($this, $this->newDirectives[$directive]['valid_value_callback']), $value);
278
-            if ($valid === false) {
279
-                $isError = true;
280
-            }
281
-        }
282
-
283
-        if ($isError === true) {
284
-            $error     = 'The execution directive %s does not seem to have a valid value. Please review. Found: %s';
285
-            $errorCode = $this->stringToErrorCode($directive) . 'InvalidValueFound';
286
-            $data      = array(
287
-                $directive,
288
-                $value,
289
-            );
290
-
291
-            $phpcsFile->addWarning($error, $stackPtr, $errorCode, $data);
292
-        }
293
-    }
294
-
295
-
296
-    /**
297
-     * Check whether a value is numeric.
298
-     *
299
-     * Callback function to test whether the value for an execution directive is valid.
300
-     *
301
-     * @param mixed $value The value to test.
302
-     *
303
-     * @return bool
304
-     */
305
-    protected function isNumeric($value)
306
-    {
307
-        return is_numeric($value);
308
-    }
309
-
310
-
311
-    /**
312
-     * Check whether a value is a valid encoding.
313
-     *
314
-     * Callback function to test whether the value for an execution directive is valid.
315
-     *
316
-     * @param mixed $value The value to test.
317
-     *
318
-     * @return bool
319
-     */
320
-    protected function validEncoding($value)
321
-    {
322
-        static $encodings;
323
-        if (isset($encodings) === false && function_exists('mb_list_encodings')) {
324
-            $encodings = mb_list_encodings();
325
-        }
326
-
327
-        if (empty($encodings) || \is_array($encodings) === false) {
328
-            // If we can't test the encoding, let it pass through.
329
-            return true;
330
-        }
331
-
332
-        return \in_array($value, $encodings, true);
333
-    }
27
+	/**
28
+	 * A list of new execution directives
29
+	 *
30
+	 * The array lists : version number with false (not present) or true (present).
31
+	 * If the execution order is conditional, add the condition as a string to the version nr.
32
+	 * If's sufficient to list the first version where the execution directive appears.
33
+	 *
34
+	 * @var array(string => array(string => int|string|null))
35
+	 */
36
+	protected $newDirectives = array(
37
+		'ticks' => array(
38
+			'3.1' => false,
39
+			'4.0' => true,
40
+			'valid_value_callback' => 'isNumeric',
41
+		),
42
+		'encoding' => array(
43
+			'5.2' => false,
44
+			'5.3' => '--enable-zend-multibyte', // Directive ignored unless.
45
+			'5.4' => true,
46
+			'valid_value_callback' => 'validEncoding',
47
+		),
48
+		'strict_types' => array(
49
+			'5.6' => false,
50
+			'7.0' => true,
51
+			'valid_values' => array(1),
52
+		),
53
+	);
54
+
55
+
56
+	/**
57
+	 * Tokens to ignore when trying to find the value for the directive.
58
+	 *
59
+	 * @var array
60
+	 */
61
+	protected $ignoreTokens = array();
62
+
63
+
64
+	/**
65
+	 * Returns an array of tokens this test wants to listen for.
66
+	 *
67
+	 * @return array
68
+	 */
69
+	public function register()
70
+	{
71
+		$this->ignoreTokens           = Tokens::$emptyTokens;
72
+		$this->ignoreTokens[\T_EQUAL] = \T_EQUAL;
73
+
74
+		return array(\T_DECLARE);
75
+	}
76
+
77
+
78
+	/**
79
+	 * Processes this test, when one of its tokens is encountered.
80
+	 *
81
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
82
+	 * @param int                   $stackPtr  The position of the current token in
83
+	 *                                         the stack passed in $tokens.
84
+	 *
85
+	 * @return void
86
+	 */
87
+	public function process(File $phpcsFile, $stackPtr)
88
+	{
89
+		$tokens = $phpcsFile->getTokens();
90
+
91
+		if (isset($tokens[$stackPtr]['parenthesis_opener'], $tokens[$stackPtr]['parenthesis_closer']) === true) {
92
+			$openParenthesis  = $tokens[$stackPtr]['parenthesis_opener'];
93
+			$closeParenthesis = $tokens[$stackPtr]['parenthesis_closer'];
94
+		} else {
95
+			if (version_compare(PHPCSHelper::getVersion(), '2.3.4', '>=')) {
96
+				return;
97
+			}
98
+
99
+			// Deal with PHPCS 2.3.0-2.3.3 which do not yet set the parenthesis properly for declare statements.
100
+			$openParenthesis = $phpcsFile->findNext(\T_OPEN_PARENTHESIS, ($stackPtr + 1), null, false, null, true);
101
+			if ($openParenthesis === false || isset($tokens[$openParenthesis]['parenthesis_closer']) === false) {
102
+				return;
103
+			}
104
+			$closeParenthesis = $tokens[$openParenthesis]['parenthesis_closer'];
105
+		}
106
+
107
+		$directivePtr = $phpcsFile->findNext(\T_STRING, ($openParenthesis + 1), $closeParenthesis, false);
108
+		if ($directivePtr === false) {
109
+			return;
110
+		}
111
+
112
+		$directiveContent = $tokens[$directivePtr]['content'];
113
+
114
+		if (isset($this->newDirectives[$directiveContent]) === false) {
115
+			$error = 'Declare can only be used with the directives %s. Found: %s';
116
+			$data  = array(
117
+				implode(', ', array_keys($this->newDirectives)),
118
+				$directiveContent,
119
+			);
120
+
121
+			$phpcsFile->addError($error, $stackPtr, 'InvalidDirectiveFound', $data);
122
+
123
+		} else {
124
+			// Check for valid directive for version.
125
+			$itemInfo = array(
126
+				'name'   => $directiveContent,
127
+			);
128
+			$this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
129
+
130
+			// Check for valid directive value.
131
+			$valuePtr = $phpcsFile->findNext($this->ignoreTokens, $directivePtr + 1, $closeParenthesis, true);
132
+			if ($valuePtr === false) {
133
+				return;
134
+			}
135
+
136
+			$this->addWarningOnInvalidValue($phpcsFile, $valuePtr, $directiveContent);
137
+		}
138
+	}
139
+
140
+
141
+	/**
142
+	 * Determine whether an error/warning should be thrown for an item based on collected information.
143
+	 *
144
+	 * @param array $errorInfo Detail information about an item.
145
+	 *
146
+	 * @return bool
147
+	 */
148
+	protected function shouldThrowError(array $errorInfo)
149
+	{
150
+		return ($errorInfo['not_in_version'] !== '' || $errorInfo['conditional_version'] !== '');
151
+	}
152
+
153
+
154
+	/**
155
+	 * Get the relevant sub-array for a specific item from a multi-dimensional array.
156
+	 *
157
+	 * @param array $itemInfo Base information about the item.
158
+	 *
159
+	 * @return array Version and other information about the item.
160
+	 */
161
+	public function getItemArray(array $itemInfo)
162
+	{
163
+		return $this->newDirectives[$itemInfo['name']];
164
+	}
165
+
166
+
167
+	/**
168
+	 * Get an array of the non-PHP-version array keys used in a sub-array.
169
+	 *
170
+	 * @return array
171
+	 */
172
+	protected function getNonVersionArrayKeys()
173
+	{
174
+		return array(
175
+			'valid_value_callback',
176
+			'valid_values',
177
+		);
178
+	}
179
+
180
+
181
+	/**
182
+	 * Retrieve the relevant detail (version) information for use in an error message.
183
+	 *
184
+	 * @param array $itemArray Version and other information about the item.
185
+	 * @param array $itemInfo  Base information about the item.
186
+	 *
187
+	 * @return array
188
+	 */
189
+	public function getErrorInfo(array $itemArray, array $itemInfo)
190
+	{
191
+		$errorInfo                        = parent::getErrorInfo($itemArray, $itemInfo);
192
+		$errorInfo['conditional_version'] = '';
193
+		$errorInfo['condition']           = '';
194
+
195
+		$versionArray = $this->getVersionArray($itemArray);
196
+
197
+		if (empty($versionArray) === false) {
198
+			foreach ($versionArray as $version => $present) {
199
+				if (\is_string($present) === true && $this->supportsBelow($version) === true) {
200
+					// We cannot test for compilation option (ok, except by scraping the output of phpinfo...).
201
+					$errorInfo['conditional_version'] = $version;
202
+					$errorInfo['condition']           = $present;
203
+				}
204
+			}
205
+		}
206
+
207
+		return $errorInfo;
208
+	}
209
+
210
+
211
+	/**
212
+	 * Get the error message template for this sniff.
213
+	 *
214
+	 * @return string
215
+	 */
216
+	protected function getErrorMsgTemplate()
217
+	{
218
+		return 'Directive ' . parent::getErrorMsgTemplate();
219
+	}
220
+
221
+
222
+	/**
223
+	 * Generates the error or warning for this item.
224
+	 *
225
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
226
+	 * @param int                   $stackPtr  The position of the relevant token in
227
+	 *                                         the stack.
228
+	 * @param array                 $itemInfo  Base information about the item.
229
+	 * @param array                 $errorInfo Array with detail (version) information
230
+	 *                                         relevant to the item.
231
+	 *
232
+	 * @return void
233
+	 */
234
+	public function addError(File $phpcsFile, $stackPtr, array $itemInfo, array $errorInfo)
235
+	{
236
+		if ($errorInfo['not_in_version'] !== '') {
237
+			parent::addError($phpcsFile, $stackPtr, $itemInfo, $errorInfo);
238
+		} elseif ($errorInfo['conditional_version'] !== '') {
239
+			$error     = 'Directive %s is present in PHP version %s but will be disregarded unless PHP is compiled with %s';
240
+			$errorCode = $this->stringToErrorCode($itemInfo['name']) . 'WithConditionFound';
241
+			$data      = array(
242
+				$itemInfo['name'],
243
+				$errorInfo['conditional_version'],
244
+				$errorInfo['condition'],
245
+			);
246
+
247
+			$phpcsFile->addWarning($error, $stackPtr, $errorCode, $data);
248
+		}
249
+	}
250
+
251
+
252
+	/**
253
+	 * Generates a error or warning for this sniff.
254
+	 *
255
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
256
+	 * @param int                   $stackPtr  The position of the execution directive value
257
+	 *                                         in the token array.
258
+	 * @param string                $directive The directive.
259
+	 *
260
+	 * @return void
261
+	 */
262
+	protected function addWarningOnInvalidValue(File $phpcsFile, $stackPtr, $directive)
263
+	{
264
+		$tokens = $phpcsFile->getTokens();
265
+
266
+		$value = $tokens[$stackPtr]['content'];
267
+		if (isset(Tokens::$stringTokens[$tokens[$stackPtr]['code']]) === true) {
268
+			$value = $this->stripQuotes($value);
269
+		}
270
+
271
+		$isError = false;
272
+		if (isset($this->newDirectives[$directive]['valid_values'])) {
273
+			if (\in_array($value, $this->newDirectives[$directive]['valid_values']) === false) {
274
+				$isError = true;
275
+			}
276
+		} elseif (isset($this->newDirectives[$directive]['valid_value_callback'])) {
277
+			$valid = \call_user_func(array($this, $this->newDirectives[$directive]['valid_value_callback']), $value);
278
+			if ($valid === false) {
279
+				$isError = true;
280
+			}
281
+		}
282
+
283
+		if ($isError === true) {
284
+			$error     = 'The execution directive %s does not seem to have a valid value. Please review. Found: %s';
285
+			$errorCode = $this->stringToErrorCode($directive) . 'InvalidValueFound';
286
+			$data      = array(
287
+				$directive,
288
+				$value,
289
+			);
290
+
291
+			$phpcsFile->addWarning($error, $stackPtr, $errorCode, $data);
292
+		}
293
+	}
294
+
295
+
296
+	/**
297
+	 * Check whether a value is numeric.
298
+	 *
299
+	 * Callback function to test whether the value for an execution directive is valid.
300
+	 *
301
+	 * @param mixed $value The value to test.
302
+	 *
303
+	 * @return bool
304
+	 */
305
+	protected function isNumeric($value)
306
+	{
307
+		return is_numeric($value);
308
+	}
309
+
310
+
311
+	/**
312
+	 * Check whether a value is a valid encoding.
313
+	 *
314
+	 * Callback function to test whether the value for an execution directive is valid.
315
+	 *
316
+	 * @param mixed $value The value to test.
317
+	 *
318
+	 * @return bool
319
+	 */
320
+	protected function validEncoding($value)
321
+	{
322
+		static $encodings;
323
+		if (isset($encodings) === false && function_exists('mb_list_encodings')) {
324
+			$encodings = mb_list_encodings();
325
+		}
326
+
327
+		if (empty($encodings) || \is_array($encodings) === false) {
328
+			// If we can't test the encoding, let it pass through.
329
+			return true;
330
+		}
331
+
332
+		return \in_array($value, $encodings, true);
333
+	}
334 334
 }
Please login to merge, or discard this patch.
Sniffs/FunctionDeclarations/NewReturnTypeDeclarationsSniff.php 1 patch
Indentation   +144 added lines, -144 removed lines patch added patch discarded remove patch
@@ -26,148 +26,148 @@
 block discarded – undo
26 26
 class NewReturnTypeDeclarationsSniff extends AbstractNewFeatureSniff
27 27
 {
28 28
 
29
-    /**
30
-     * A list of new types
31
-     *
32
-     * The array lists : version number with false (not present) or true (present).
33
-     * If's sufficient to list the first version where the keyword appears.
34
-     *
35
-     * @var array(string => array(string => int|string|null))
36
-     */
37
-    protected $newTypes = array(
38
-        'int' => array(
39
-            '5.6' => false,
40
-            '7.0' => true,
41
-        ),
42
-        'float' => array(
43
-            '5.6' => false,
44
-            '7.0' => true,
45
-        ),
46
-        'bool' => array(
47
-            '5.6' => false,
48
-            '7.0' => true,
49
-        ),
50
-        'string' => array(
51
-            '5.6' => false,
52
-            '7.0' => true,
53
-        ),
54
-        'array' => array(
55
-            '5.6' => false,
56
-            '7.0' => true,
57
-        ),
58
-        'callable' => array(
59
-            '5.6' => false,
60
-            '7.0' => true,
61
-        ),
62
-        'parent' => array(
63
-            '5.6' => false,
64
-            '7.0' => true,
65
-        ),
66
-        'self' => array(
67
-            '5.6' => false,
68
-            '7.0' => true,
69
-        ),
70
-        'Class name' => array(
71
-            '5.6' => false,
72
-            '7.0' => true,
73
-        ),
74
-
75
-        'iterable' => array(
76
-            '7.0' => false,
77
-            '7.1' => true,
78
-        ),
79
-        'void' => array(
80
-            '7.0' => false,
81
-            '7.1' => true,
82
-        ),
83
-
84
-        'object' => array(
85
-            '7.1' => false,
86
-            '7.2' => true,
87
-        ),
88
-    );
89
-
90
-
91
-    /**
92
-     * Returns an array of tokens this test wants to listen for.
93
-     *
94
-     * @return array
95
-     */
96
-    public function register()
97
-    {
98
-        $tokens = array(
99
-            \T_FUNCTION,
100
-            \T_CLOSURE,
101
-        );
102
-
103
-        if (\defined('T_RETURN_TYPE')) {
104
-            $tokens[] = \T_RETURN_TYPE;
105
-        }
106
-
107
-        return $tokens;
108
-    }
109
-
110
-
111
-    /**
112
-     * Processes this test, when one of its tokens is encountered.
113
-     *
114
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
115
-     * @param int                   $stackPtr  The position of the current token in
116
-     *                                         the stack passed in $tokens.
117
-     *
118
-     * @return void
119
-     */
120
-    public function process(File $phpcsFile, $stackPtr)
121
-    {
122
-        $tokens = $phpcsFile->getTokens();
123
-
124
-        // Deal with older PHPCS version which don't recognize return type hints
125
-        // as well as newer PHPCS versions (3.3.0+) where the tokenization has changed.
126
-        if ($tokens[$stackPtr]['code'] === \T_FUNCTION || $tokens[$stackPtr]['code'] === \T_CLOSURE) {
127
-            $returnTypeHint = $this->getReturnTypeHintToken($phpcsFile, $stackPtr);
128
-            if ($returnTypeHint !== false) {
129
-                $stackPtr = $returnTypeHint;
130
-            }
131
-        }
132
-
133
-        if (isset($this->newTypes[$tokens[$stackPtr]['content']]) === true) {
134
-            $itemInfo = array(
135
-                'name' => $tokens[$stackPtr]['content'],
136
-            );
137
-            $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
138
-        }
139
-        // Handle class name based return types.
140
-        elseif ($tokens[$stackPtr]['code'] === \T_STRING
141
-            || (\defined('T_RETURN_TYPE') && $tokens[$stackPtr]['code'] === \T_RETURN_TYPE)
142
-        ) {
143
-            $itemInfo = array(
144
-                'name'   => 'Class name',
145
-            );
146
-            $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
147
-        }
148
-    }
149
-
150
-
151
-    /**
152
-     * Get the relevant sub-array for a specific item from a multi-dimensional array.
153
-     *
154
-     * @param array $itemInfo Base information about the item.
155
-     *
156
-     * @return array Version and other information about the item.
157
-     */
158
-    public function getItemArray(array $itemInfo)
159
-    {
160
-        return $this->newTypes[$itemInfo['name']];
161
-    }
162
-
163
-
164
-    /**
165
-     * Get the error message template for this sniff.
166
-     *
167
-     * @return string
168
-     */
169
-    protected function getErrorMsgTemplate()
170
-    {
171
-        return '%s return type is not present in PHP version %s or earlier';
172
-    }
29
+	/**
30
+	 * A list of new types
31
+	 *
32
+	 * The array lists : version number with false (not present) or true (present).
33
+	 * If's sufficient to list the first version where the keyword appears.
34
+	 *
35
+	 * @var array(string => array(string => int|string|null))
36
+	 */
37
+	protected $newTypes = array(
38
+		'int' => array(
39
+			'5.6' => false,
40
+			'7.0' => true,
41
+		),
42
+		'float' => array(
43
+			'5.6' => false,
44
+			'7.0' => true,
45
+		),
46
+		'bool' => array(
47
+			'5.6' => false,
48
+			'7.0' => true,
49
+		),
50
+		'string' => array(
51
+			'5.6' => false,
52
+			'7.0' => true,
53
+		),
54
+		'array' => array(
55
+			'5.6' => false,
56
+			'7.0' => true,
57
+		),
58
+		'callable' => array(
59
+			'5.6' => false,
60
+			'7.0' => true,
61
+		),
62
+		'parent' => array(
63
+			'5.6' => false,
64
+			'7.0' => true,
65
+		),
66
+		'self' => array(
67
+			'5.6' => false,
68
+			'7.0' => true,
69
+		),
70
+		'Class name' => array(
71
+			'5.6' => false,
72
+			'7.0' => true,
73
+		),
74
+
75
+		'iterable' => array(
76
+			'7.0' => false,
77
+			'7.1' => true,
78
+		),
79
+		'void' => array(
80
+			'7.0' => false,
81
+			'7.1' => true,
82
+		),
83
+
84
+		'object' => array(
85
+			'7.1' => false,
86
+			'7.2' => true,
87
+		),
88
+	);
89
+
90
+
91
+	/**
92
+	 * Returns an array of tokens this test wants to listen for.
93
+	 *
94
+	 * @return array
95
+	 */
96
+	public function register()
97
+	{
98
+		$tokens = array(
99
+			\T_FUNCTION,
100
+			\T_CLOSURE,
101
+		);
102
+
103
+		if (\defined('T_RETURN_TYPE')) {
104
+			$tokens[] = \T_RETURN_TYPE;
105
+		}
106
+
107
+		return $tokens;
108
+	}
109
+
110
+
111
+	/**
112
+	 * Processes this test, when one of its tokens is encountered.
113
+	 *
114
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
115
+	 * @param int                   $stackPtr  The position of the current token in
116
+	 *                                         the stack passed in $tokens.
117
+	 *
118
+	 * @return void
119
+	 */
120
+	public function process(File $phpcsFile, $stackPtr)
121
+	{
122
+		$tokens = $phpcsFile->getTokens();
123
+
124
+		// Deal with older PHPCS version which don't recognize return type hints
125
+		// as well as newer PHPCS versions (3.3.0+) where the tokenization has changed.
126
+		if ($tokens[$stackPtr]['code'] === \T_FUNCTION || $tokens[$stackPtr]['code'] === \T_CLOSURE) {
127
+			$returnTypeHint = $this->getReturnTypeHintToken($phpcsFile, $stackPtr);
128
+			if ($returnTypeHint !== false) {
129
+				$stackPtr = $returnTypeHint;
130
+			}
131
+		}
132
+
133
+		if (isset($this->newTypes[$tokens[$stackPtr]['content']]) === true) {
134
+			$itemInfo = array(
135
+				'name' => $tokens[$stackPtr]['content'],
136
+			);
137
+			$this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
138
+		}
139
+		// Handle class name based return types.
140
+		elseif ($tokens[$stackPtr]['code'] === \T_STRING
141
+			|| (\defined('T_RETURN_TYPE') && $tokens[$stackPtr]['code'] === \T_RETURN_TYPE)
142
+		) {
143
+			$itemInfo = array(
144
+				'name'   => 'Class name',
145
+			);
146
+			$this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
147
+		}
148
+	}
149
+
150
+
151
+	/**
152
+	 * Get the relevant sub-array for a specific item from a multi-dimensional array.
153
+	 *
154
+	 * @param array $itemInfo Base information about the item.
155
+	 *
156
+	 * @return array Version and other information about the item.
157
+	 */
158
+	public function getItemArray(array $itemInfo)
159
+	{
160
+		return $this->newTypes[$itemInfo['name']];
161
+	}
162
+
163
+
164
+	/**
165
+	 * Get the error message template for this sniff.
166
+	 *
167
+	 * @return string
168
+	 */
169
+	protected function getErrorMsgTemplate()
170
+	{
171
+		return '%s return type is not present in PHP version %s or earlier';
172
+	}
173 173
 }
Please login to merge, or discard this patch.
Sniffs/FunctionDeclarations/NewParamTypeDeclarationsSniff.php 1 patch
Indentation   +169 added lines, -169 removed lines patch added patch discarded remove patch
@@ -23,173 +23,173 @@
 block discarded – undo
23 23
 class NewParamTypeDeclarationsSniff extends AbstractNewFeatureSniff
24 24
 {
25 25
 
26
-    /**
27
-     * A list of new types.
28
-     *
29
-     * The array lists : version number with false (not present) or true (present).
30
-     * If's sufficient to list the first version where the keyword appears.
31
-     *
32
-     * @var array(string => array(string => int|string|null))
33
-     */
34
-    protected $newTypes = array(
35
-        'array' => array(
36
-            '5.0' => false,
37
-            '5.1' => true,
38
-        ),
39
-        'self' => array(
40
-            '5.1' => false,
41
-            '5.2' => true,
42
-        ),
43
-        'parent' => array(
44
-            '5.1' => false,
45
-            '5.2' => true,
46
-        ),
47
-        'callable' => array(
48
-            '5.3' => false,
49
-            '5.4' => true,
50
-        ),
51
-        'int' => array(
52
-            '5.6' => false,
53
-            '7.0' => true,
54
-        ),
55
-        'float' => array(
56
-            '5.6' => false,
57
-            '7.0' => true,
58
-        ),
59
-        'bool' => array(
60
-            '5.6' => false,
61
-            '7.0' => true,
62
-        ),
63
-        'string' => array(
64
-            '5.6' => false,
65
-            '7.0' => true,
66
-        ),
67
-        'iterable' => array(
68
-            '7.0' => false,
69
-            '7.1' => true,
70
-        ),
71
-        'object' => array(
72
-            '7.1' => false,
73
-            '7.2' => true,
74
-        ),
75
-    );
76
-
77
-
78
-    /**
79
-     * Invalid types
80
-     *
81
-     * The array lists : the invalid type hint => what was probably intended/alternative.
82
-     *
83
-     * @var array(string => string)
84
-     */
85
-    protected $invalidTypes = array(
86
-        'static'  => 'self',
87
-        'boolean' => 'bool',
88
-        'integer' => 'int',
89
-    );
90
-
91
-
92
-    /**
93
-     * Returns an array of tokens this test wants to listen for.
94
-     *
95
-     * @return array
96
-     */
97
-    public function register()
98
-    {
99
-        return array(
100
-            \T_FUNCTION,
101
-            \T_CLOSURE,
102
-        );
103
-    }
104
-
105
-
106
-    /**
107
-     * Processes this test, when one of its tokens is encountered.
108
-     *
109
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
110
-     * @param int                   $stackPtr  The position of the current token in
111
-     *                                         the stack passed in $tokens.
112
-     *
113
-     * @return void
114
-     */
115
-    public function process(File $phpcsFile, $stackPtr)
116
-    {
117
-        // Get all parameters from method signature.
118
-        $paramNames = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
119
-        if (empty($paramNames)) {
120
-            return;
121
-        }
122
-
123
-        $supportsPHP4 = $this->supportsBelow('4.4');
124
-
125
-        foreach ($paramNames as $param) {
126
-            if ($param['type_hint'] === '') {
127
-                continue;
128
-            }
129
-
130
-            // Strip off potential nullable indication.
131
-            $typeHint = ltrim($param['type_hint'], '?');
132
-
133
-            if ($supportsPHP4 === true) {
134
-                $phpcsFile->addError(
135
-                    'Type declarations were not present in PHP 4.4 or earlier.',
136
-                    $param['token'],
137
-                    'TypeHintFound'
138
-                );
139
-
140
-            } elseif (isset($this->newTypes[$typeHint])) {
141
-                $itemInfo = array(
142
-                    'name' => $typeHint,
143
-                );
144
-                $this->handleFeature($phpcsFile, $param['token'], $itemInfo);
145
-
146
-                // As of PHP 7.0, using `self` or `parent` outside class scope throws a fatal error.
147
-                // Only throw this error for PHP 5.2+ as before that the "type hint not supported" error
148
-                // will be thrown.
149
-                if (($typeHint === 'self' || $typeHint === 'parent')
150
-                    && $this->inClassScope($phpcsFile, $stackPtr, false) === false
151
-                    && $this->supportsAbove('5.2') !== false
152
-                ) {
153
-                    $phpcsFile->addError(
154
-                        "'%s' type cannot be used outside of class scope",
155
-                        $param['token'],
156
-                        ucfirst($typeHint) . 'OutsideClassScopeFound',
157
-                        array($typeHint)
158
-                    );
159
-                }
160
-            } elseif (isset($this->invalidTypes[$typeHint])) {
161
-                $error = "'%s' is not a valid type declaration. Did you mean %s ?";
162
-                $data  = array(
163
-                    $typeHint,
164
-                    $this->invalidTypes[$typeHint],
165
-                );
166
-
167
-                $phpcsFile->addError($error, $param['token'], 'InvalidTypeHintFound', $data);
168
-            }
169
-        }
170
-    }
171
-
172
-
173
-    /**
174
-     * Get the relevant sub-array for a specific item from a multi-dimensional array.
175
-     *
176
-     * @param array $itemInfo Base information about the item.
177
-     *
178
-     * @return array Version and other information about the item.
179
-     */
180
-    public function getItemArray(array $itemInfo)
181
-    {
182
-        return $this->newTypes[$itemInfo['name']];
183
-    }
184
-
185
-
186
-    /**
187
-     * Get the error message template for this sniff.
188
-     *
189
-     * @return string
190
-     */
191
-    protected function getErrorMsgTemplate()
192
-    {
193
-        return "'%s' type declaration is not present in PHP version %s or earlier";
194
-    }
26
+	/**
27
+	 * A list of new types.
28
+	 *
29
+	 * The array lists : version number with false (not present) or true (present).
30
+	 * If's sufficient to list the first version where the keyword appears.
31
+	 *
32
+	 * @var array(string => array(string => int|string|null))
33
+	 */
34
+	protected $newTypes = array(
35
+		'array' => array(
36
+			'5.0' => false,
37
+			'5.1' => true,
38
+		),
39
+		'self' => array(
40
+			'5.1' => false,
41
+			'5.2' => true,
42
+		),
43
+		'parent' => array(
44
+			'5.1' => false,
45
+			'5.2' => true,
46
+		),
47
+		'callable' => array(
48
+			'5.3' => false,
49
+			'5.4' => true,
50
+		),
51
+		'int' => array(
52
+			'5.6' => false,
53
+			'7.0' => true,
54
+		),
55
+		'float' => array(
56
+			'5.6' => false,
57
+			'7.0' => true,
58
+		),
59
+		'bool' => array(
60
+			'5.6' => false,
61
+			'7.0' => true,
62
+		),
63
+		'string' => array(
64
+			'5.6' => false,
65
+			'7.0' => true,
66
+		),
67
+		'iterable' => array(
68
+			'7.0' => false,
69
+			'7.1' => true,
70
+		),
71
+		'object' => array(
72
+			'7.1' => false,
73
+			'7.2' => true,
74
+		),
75
+	);
76
+
77
+
78
+	/**
79
+	 * Invalid types
80
+	 *
81
+	 * The array lists : the invalid type hint => what was probably intended/alternative.
82
+	 *
83
+	 * @var array(string => string)
84
+	 */
85
+	protected $invalidTypes = array(
86
+		'static'  => 'self',
87
+		'boolean' => 'bool',
88
+		'integer' => 'int',
89
+	);
90
+
91
+
92
+	/**
93
+	 * Returns an array of tokens this test wants to listen for.
94
+	 *
95
+	 * @return array
96
+	 */
97
+	public function register()
98
+	{
99
+		return array(
100
+			\T_FUNCTION,
101
+			\T_CLOSURE,
102
+		);
103
+	}
104
+
105
+
106
+	/**
107
+	 * Processes this test, when one of its tokens is encountered.
108
+	 *
109
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
110
+	 * @param int                   $stackPtr  The position of the current token in
111
+	 *                                         the stack passed in $tokens.
112
+	 *
113
+	 * @return void
114
+	 */
115
+	public function process(File $phpcsFile, $stackPtr)
116
+	{
117
+		// Get all parameters from method signature.
118
+		$paramNames = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
119
+		if (empty($paramNames)) {
120
+			return;
121
+		}
122
+
123
+		$supportsPHP4 = $this->supportsBelow('4.4');
124
+
125
+		foreach ($paramNames as $param) {
126
+			if ($param['type_hint'] === '') {
127
+				continue;
128
+			}
129
+
130
+			// Strip off potential nullable indication.
131
+			$typeHint = ltrim($param['type_hint'], '?');
132
+
133
+			if ($supportsPHP4 === true) {
134
+				$phpcsFile->addError(
135
+					'Type declarations were not present in PHP 4.4 or earlier.',
136
+					$param['token'],
137
+					'TypeHintFound'
138
+				);
139
+
140
+			} elseif (isset($this->newTypes[$typeHint])) {
141
+				$itemInfo = array(
142
+					'name' => $typeHint,
143
+				);
144
+				$this->handleFeature($phpcsFile, $param['token'], $itemInfo);
145
+
146
+				// As of PHP 7.0, using `self` or `parent` outside class scope throws a fatal error.
147
+				// Only throw this error for PHP 5.2+ as before that the "type hint not supported" error
148
+				// will be thrown.
149
+				if (($typeHint === 'self' || $typeHint === 'parent')
150
+					&& $this->inClassScope($phpcsFile, $stackPtr, false) === false
151
+					&& $this->supportsAbove('5.2') !== false
152
+				) {
153
+					$phpcsFile->addError(
154
+						"'%s' type cannot be used outside of class scope",
155
+						$param['token'],
156
+						ucfirst($typeHint) . 'OutsideClassScopeFound',
157
+						array($typeHint)
158
+					);
159
+				}
160
+			} elseif (isset($this->invalidTypes[$typeHint])) {
161
+				$error = "'%s' is not a valid type declaration. Did you mean %s ?";
162
+				$data  = array(
163
+					$typeHint,
164
+					$this->invalidTypes[$typeHint],
165
+				);
166
+
167
+				$phpcsFile->addError($error, $param['token'], 'InvalidTypeHintFound', $data);
168
+			}
169
+		}
170
+	}
171
+
172
+
173
+	/**
174
+	 * Get the relevant sub-array for a specific item from a multi-dimensional array.
175
+	 *
176
+	 * @param array $itemInfo Base information about the item.
177
+	 *
178
+	 * @return array Version and other information about the item.
179
+	 */
180
+	public function getItemArray(array $itemInfo)
181
+	{
182
+		return $this->newTypes[$itemInfo['name']];
183
+	}
184
+
185
+
186
+	/**
187
+	 * Get the error message template for this sniff.
188
+	 *
189
+	 * @return string
190
+	 */
191
+	protected function getErrorMsgTemplate()
192
+	{
193
+		return "'%s' type declaration is not present in PHP version %s or earlier";
194
+	}
195 195
 }
Please login to merge, or discard this patch.
Sniffs/FunctionDeclarations/ForbiddenToStringParametersSniff.php 1 patch
Indentation   +60 added lines, -60 removed lines patch added patch discarded remove patch
@@ -28,70 +28,70 @@
 block discarded – undo
28 28
 class ForbiddenToStringParametersSniff extends Sniff
29 29
 {
30 30
 
31
-    /**
32
-     * Valid scopes for the __toString() method to live in.
33
-     *
34
-     * @since 9.2.0
35
-     *
36
-     * @var array
37
-     */
38
-    public $ooScopeTokens = array(
39
-        'T_CLASS'      => true,
40
-        'T_INTERFACE'  => true,
41
-        'T_TRAIT'      => true,
42
-        'T_ANON_CLASS' => true,
43
-    );
31
+	/**
32
+	 * Valid scopes for the __toString() method to live in.
33
+	 *
34
+	 * @since 9.2.0
35
+	 *
36
+	 * @var array
37
+	 */
38
+	public $ooScopeTokens = array(
39
+		'T_CLASS'      => true,
40
+		'T_INTERFACE'  => true,
41
+		'T_TRAIT'      => true,
42
+		'T_ANON_CLASS' => true,
43
+	);
44 44
 
45
-    /**
46
-     * Returns an array of tokens this test wants to listen for.
47
-     *
48
-     * @since 9.2.0
49
-     *
50
-     * @return array
51
-     */
52
-    public function register()
53
-    {
54
-        return array(\T_FUNCTION);
55
-    }
45
+	/**
46
+	 * Returns an array of tokens this test wants to listen for.
47
+	 *
48
+	 * @since 9.2.0
49
+	 *
50
+	 * @return array
51
+	 */
52
+	public function register()
53
+	{
54
+		return array(\T_FUNCTION);
55
+	}
56 56
 
57
-    /**
58
-     * Processes this test, when one of its tokens is encountered.
59
-     *
60
-     * @since 9.2.0
61
-     *
62
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
63
-     * @param int                   $stackPtr  The position of the current token
64
-     *                                         in the stack passed in $tokens.
65
-     *
66
-     * @return void
67
-     */
68
-    public function process(File $phpcsFile, $stackPtr)
69
-    {
70
-        if ($this->supportsAbove('5.3') === false) {
71
-            return;
72
-        }
57
+	/**
58
+	 * Processes this test, when one of its tokens is encountered.
59
+	 *
60
+	 * @since 9.2.0
61
+	 *
62
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
63
+	 * @param int                   $stackPtr  The position of the current token
64
+	 *                                         in the stack passed in $tokens.
65
+	 *
66
+	 * @return void
67
+	 */
68
+	public function process(File $phpcsFile, $stackPtr)
69
+	{
70
+		if ($this->supportsAbove('5.3') === false) {
71
+			return;
72
+		}
73 73
 
74
-        $functionName = $phpcsFile->getDeclarationName($stackPtr);
75
-        if (strtolower($functionName) !== '__tostring') {
76
-            // Not the right function.
77
-            return;
78
-        }
74
+		$functionName = $phpcsFile->getDeclarationName($stackPtr);
75
+		if (strtolower($functionName) !== '__tostring') {
76
+			// Not the right function.
77
+			return;
78
+		}
79 79
 
80
-        if ($this->validDirectScope($phpcsFile, $stackPtr, $this->ooScopeTokens) === false) {
81
-            // Function, not method.
82
-            return;
83
-        }
80
+		if ($this->validDirectScope($phpcsFile, $stackPtr, $this->ooScopeTokens) === false) {
81
+			// Function, not method.
82
+			return;
83
+		}
84 84
 
85
-        $params = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
86
-        if (empty($params)) {
87
-            // Function declared without parameters.
88
-            return;
89
-        }
85
+		$params = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
86
+		if (empty($params)) {
87
+			// Function declared without parameters.
88
+			return;
89
+		}
90 90
 
91
-        $phpcsFile->addError(
92
-            'The __toString() magic method can no longer accept arguments since PHP 5.3',
93
-            $stackPtr,
94
-            'Declared'
95
-        );
96
-    }
91
+		$phpcsFile->addError(
92
+			'The __toString() magic method can no longer accept arguments since PHP 5.3',
93
+			$stackPtr,
94
+			'Declared'
95
+		);
96
+	}
97 97
 }
Please login to merge, or discard this patch.
Sniffs/FunctionDeclarations/ForbiddenVariableNamesInClosureUseSniff.php 1 patch
Indentation   +84 added lines, -84 removed lines patch added patch discarded remove patch
@@ -31,88 +31,88 @@
 block discarded – undo
31 31
 class ForbiddenVariableNamesInClosureUseSniff extends Sniff
32 32
 {
33 33
 
34
-    /**
35
-     * Returns an array of tokens this test wants to listen for.
36
-     *
37
-     * @return array
38
-     */
39
-    public function register()
40
-    {
41
-        return array(\T_USE);
42
-    }
43
-
44
-    /**
45
-     * Processes this test, when one of its tokens is encountered.
46
-     *
47
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
48
-     * @param int                   $stackPtr  The position of the current token
49
-     *                                         in the stack passed in $tokens.
50
-     *
51
-     * @return void
52
-     */
53
-    public function process(File $phpcsFile, $stackPtr)
54
-    {
55
-        if ($this->supportsAbove('7.1') === false) {
56
-            return;
57
-        }
58
-
59
-        $tokens = $phpcsFile->getTokens();
60
-
61
-        // Verify this use statement is used with a closure - if so, it has to have parenthesis before it.
62
-        $previousNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true, null, true);
63
-        if ($previousNonEmpty === false || $tokens[$previousNonEmpty]['code'] !== \T_CLOSE_PARENTHESIS
64
-            || isset($tokens[$previousNonEmpty]['parenthesis_opener']) === false
65
-        ) {
66
-            return;
67
-        }
68
-
69
-        // ... and (a variable within) parenthesis after it.
70
-        $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
71
-        if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== \T_OPEN_PARENTHESIS) {
72
-            return;
73
-        }
74
-
75
-        if (isset($tokens[$nextNonEmpty]['parenthesis_closer']) === false) {
76
-            // Live coding.
77
-            return;
78
-        }
79
-
80
-        $closurePtr = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($tokens[$previousNonEmpty]['parenthesis_opener'] - 1), null, true);
81
-        if ($closurePtr === false || $tokens[$closurePtr]['code'] !== \T_CLOSURE) {
82
-            return;
83
-        }
84
-
85
-        // Get the parameters declared by the closure.
86
-        $closureParams = PHPCSHelper::getMethodParameters($phpcsFile, $closurePtr);
87
-
88
-        $errorMsg = 'Variables bound to a closure via the use construct cannot use the same name as superglobals, $this, or a declared parameter since PHP 7.1. Found: %s';
89
-
90
-        for ($i = ($nextNonEmpty + 1); $i < $tokens[$nextNonEmpty]['parenthesis_closer']; $i++) {
91
-            if ($tokens[$i]['code'] !== \T_VARIABLE) {
92
-                continue;
93
-            }
94
-
95
-            $variableName = $tokens[$i]['content'];
96
-
97
-            if ($variableName === '$this') {
98
-                $phpcsFile->addError($errorMsg, $i, 'FoundThis', array($variableName));
99
-                continue;
100
-            }
101
-
102
-            if (isset($this->superglobals[$variableName]) === true) {
103
-                $phpcsFile->addError($errorMsg, $i, 'FoundSuperglobal', array($variableName));
104
-                continue;
105
-            }
106
-
107
-            // Check whether it is one of the parameters declared by the closure.
108
-            if (empty($closureParams) === false) {
109
-                foreach ($closureParams as $param) {
110
-                    if ($param['name'] === $variableName) {
111
-                        $phpcsFile->addError($errorMsg, $i, 'FoundShadowParam', array($variableName));
112
-                        continue 2;
113
-                    }
114
-                }
115
-            }
116
-        }
117
-    }
34
+	/**
35
+	 * Returns an array of tokens this test wants to listen for.
36
+	 *
37
+	 * @return array
38
+	 */
39
+	public function register()
40
+	{
41
+		return array(\T_USE);
42
+	}
43
+
44
+	/**
45
+	 * Processes this test, when one of its tokens is encountered.
46
+	 *
47
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
48
+	 * @param int                   $stackPtr  The position of the current token
49
+	 *                                         in the stack passed in $tokens.
50
+	 *
51
+	 * @return void
52
+	 */
53
+	public function process(File $phpcsFile, $stackPtr)
54
+	{
55
+		if ($this->supportsAbove('7.1') === false) {
56
+			return;
57
+		}
58
+
59
+		$tokens = $phpcsFile->getTokens();
60
+
61
+		// Verify this use statement is used with a closure - if so, it has to have parenthesis before it.
62
+		$previousNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true, null, true);
63
+		if ($previousNonEmpty === false || $tokens[$previousNonEmpty]['code'] !== \T_CLOSE_PARENTHESIS
64
+			|| isset($tokens[$previousNonEmpty]['parenthesis_opener']) === false
65
+		) {
66
+			return;
67
+		}
68
+
69
+		// ... and (a variable within) parenthesis after it.
70
+		$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
71
+		if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== \T_OPEN_PARENTHESIS) {
72
+			return;
73
+		}
74
+
75
+		if (isset($tokens[$nextNonEmpty]['parenthesis_closer']) === false) {
76
+			// Live coding.
77
+			return;
78
+		}
79
+
80
+		$closurePtr = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($tokens[$previousNonEmpty]['parenthesis_opener'] - 1), null, true);
81
+		if ($closurePtr === false || $tokens[$closurePtr]['code'] !== \T_CLOSURE) {
82
+			return;
83
+		}
84
+
85
+		// Get the parameters declared by the closure.
86
+		$closureParams = PHPCSHelper::getMethodParameters($phpcsFile, $closurePtr);
87
+
88
+		$errorMsg = 'Variables bound to a closure via the use construct cannot use the same name as superglobals, $this, or a declared parameter since PHP 7.1. Found: %s';
89
+
90
+		for ($i = ($nextNonEmpty + 1); $i < $tokens[$nextNonEmpty]['parenthesis_closer']; $i++) {
91
+			if ($tokens[$i]['code'] !== \T_VARIABLE) {
92
+				continue;
93
+			}
94
+
95
+			$variableName = $tokens[$i]['content'];
96
+
97
+			if ($variableName === '$this') {
98
+				$phpcsFile->addError($errorMsg, $i, 'FoundThis', array($variableName));
99
+				continue;
100
+			}
101
+
102
+			if (isset($this->superglobals[$variableName]) === true) {
103
+				$phpcsFile->addError($errorMsg, $i, 'FoundSuperglobal', array($variableName));
104
+				continue;
105
+			}
106
+
107
+			// Check whether it is one of the parameters declared by the closure.
108
+			if (empty($closureParams) === false) {
109
+				foreach ($closureParams as $param) {
110
+					if ($param['name'] === $variableName) {
111
+						$phpcsFile->addError($errorMsg, $i, 'FoundShadowParam', array($variableName));
112
+						continue 2;
113
+					}
114
+				}
115
+			}
116
+		}
117
+	}
118 118
 }
Please login to merge, or discard this patch.
Sniffs/FunctionDeclarations/ForbiddenParameterShadowSuperGlobalsSniff.php 1 patch
Indentation   +39 added lines, -39 removed lines patch added patch discarded remove patch
@@ -33,47 +33,47 @@
 block discarded – undo
33 33
 class ForbiddenParameterShadowSuperGlobalsSniff extends Sniff
34 34
 {
35 35
 
36
-    /**
37
-     * Register the tokens to listen for.
38
-     *
39
-     * @return array
40
-     */
41
-    public function register()
42
-    {
43
-        return array(
44
-            \T_FUNCTION,
45
-            \T_CLOSURE,
46
-        );
47
-    }
36
+	/**
37
+	 * Register the tokens to listen for.
38
+	 *
39
+	 * @return array
40
+	 */
41
+	public function register()
42
+	{
43
+		return array(
44
+			\T_FUNCTION,
45
+			\T_CLOSURE,
46
+		);
47
+	}
48 48
 
49
-    /**
50
-     * Processes the test.
51
-     *
52
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
53
-     * @param int                   $stackPtr  The position of the current token.
54
-     *
55
-     * @return void
56
-     */
57
-    public function process(File $phpcsFile, $stackPtr)
58
-    {
59
-        if ($this->supportsAbove('5.4') === false) {
60
-            return;
61
-        }
49
+	/**
50
+	 * Processes the test.
51
+	 *
52
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
53
+	 * @param int                   $stackPtr  The position of the current token.
54
+	 *
55
+	 * @return void
56
+	 */
57
+	public function process(File $phpcsFile, $stackPtr)
58
+	{
59
+		if ($this->supportsAbove('5.4') === false) {
60
+			return;
61
+		}
62 62
 
63
-        // Get all parameters from function signature.
64
-        $parameters = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
65
-        if (empty($parameters) || \is_array($parameters) === false) {
66
-            return;
67
-        }
63
+		// Get all parameters from function signature.
64
+		$parameters = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
65
+		if (empty($parameters) || \is_array($parameters) === false) {
66
+			return;
67
+		}
68 68
 
69
-        foreach ($parameters as $param) {
70
-            if (isset($this->superglobals[$param['name']]) === true) {
71
-                $error     = 'Parameter shadowing super global (%s) causes fatal error since PHP 5.4';
72
-                $errorCode = $this->stringToErrorCode(substr($param['name'], 1)) . 'Found';
73
-                $data      = array($param['name']);
69
+		foreach ($parameters as $param) {
70
+			if (isset($this->superglobals[$param['name']]) === true) {
71
+				$error     = 'Parameter shadowing super global (%s) causes fatal error since PHP 5.4';
72
+				$errorCode = $this->stringToErrorCode(substr($param['name'], 1)) . 'Found';
73
+				$data      = array($param['name']);
74 74
 
75
-                $phpcsFile->addError($error, $param['token'], $errorCode, $data);
76
-            }
77
-        }
78
-    }
75
+				$phpcsFile->addError($error, $param['token'], $errorCode, $data);
76
+			}
77
+		}
78
+	}
79 79
 }
Please login to merge, or discard this patch.
Sniffs/FunctionDeclarations/ForbiddenParametersWithSameNameSniff.php 1 patch
Indentation   +49 added lines, -49 removed lines patch added patch discarded remove patch
@@ -29,58 +29,58 @@
 block discarded – undo
29 29
 class ForbiddenParametersWithSameNameSniff extends Sniff
30 30
 {
31 31
 
32
-    /**
33
-     * Returns an array of tokens this test wants to listen for.
34
-     *
35
-     * @return array
36
-     */
37
-    public function register()
38
-    {
39
-        return array(
40
-            \T_FUNCTION,
41
-            \T_CLOSURE,
42
-        );
43
-    }
32
+	/**
33
+	 * Returns an array of tokens this test wants to listen for.
34
+	 *
35
+	 * @return array
36
+	 */
37
+	public function register()
38
+	{
39
+		return array(
40
+			\T_FUNCTION,
41
+			\T_CLOSURE,
42
+		);
43
+	}
44 44
 
45
-    /**
46
-     * Processes this test, when one of its tokens is encountered.
47
-     *
48
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
49
-     * @param int                   $stackPtr  The position of the current token
50
-     *                                         in the stack passed in $tokens.
51
-     *
52
-     * @return void
53
-     */
54
-    public function process(File $phpcsFile, $stackPtr)
55
-    {
56
-        if ($this->supportsAbove('7.0') === false) {
57
-            return;
58
-        }
45
+	/**
46
+	 * Processes this test, when one of its tokens is encountered.
47
+	 *
48
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
49
+	 * @param int                   $stackPtr  The position of the current token
50
+	 *                                         in the stack passed in $tokens.
51
+	 *
52
+	 * @return void
53
+	 */
54
+	public function process(File $phpcsFile, $stackPtr)
55
+	{
56
+		if ($this->supportsAbove('7.0') === false) {
57
+			return;
58
+		}
59 59
 
60
-        $tokens = $phpcsFile->getTokens();
61
-        $token  = $tokens[$stackPtr];
62
-        // Skip function without body.
63
-        if (isset($token['scope_opener']) === false) {
64
-            return;
65
-        }
60
+		$tokens = $phpcsFile->getTokens();
61
+		$token  = $tokens[$stackPtr];
62
+		// Skip function without body.
63
+		if (isset($token['scope_opener']) === false) {
64
+			return;
65
+		}
66 66
 
67
-        // Get all parameters from method signature.
68
-        $parameters = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
69
-        if (empty($parameters) || \is_array($parameters) === false) {
70
-            return;
71
-        }
67
+		// Get all parameters from method signature.
68
+		$parameters = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
69
+		if (empty($parameters) || \is_array($parameters) === false) {
70
+			return;
71
+		}
72 72
 
73
-        $paramNames = array();
74
-        foreach ($parameters as $param) {
75
-            $paramNames[] = strtolower($param['name']);
76
-        }
73
+		$paramNames = array();
74
+		foreach ($parameters as $param) {
75
+			$paramNames[] = strtolower($param['name']);
76
+		}
77 77
 
78
-        if (\count($paramNames) !== \count(array_unique($paramNames))) {
79
-            $phpcsFile->addError(
80
-                'Functions can not have multiple parameters with the same name since PHP 7.0',
81
-                $stackPtr,
82
-                'Found'
83
-            );
84
-        }
85
-    }
78
+		if (\count($paramNames) !== \count(array_unique($paramNames))) {
79
+			$phpcsFile->addError(
80
+				'Functions can not have multiple parameters with the same name since PHP 7.0',
81
+				$stackPtr,
82
+				'Found'
83
+			);
84
+		}
85
+	}
86 86
 }
Please login to merge, or discard this patch.