Skip to content

Commit f0a45e5

Browse files
authored
Merge pull request #289 from fredden/fixer-conflict/PSR-12/strict-types-parse-error
Improve context detection for `PSR12.Operators.OperatorSpacing` / `Squiz.WhiteSpace.OperatorSpacing` - avoids fixer conflict, bow out on parse error
2 parents 0f90d83 + 73ca839 commit f0a45e5

13 files changed

+88
-38
lines changed

src/Standards/PSR12/Sniffs/Operators/OperatorSpacingSniff.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ public function register()
3535
$targets[] = T_STRING_CONCAT;
3636
$targets[] = T_INSTANCEOF;
3737

38+
// Also register the contexts we want to specifically skip over.
39+
$targets[] = T_DECLARE;
40+
3841
return $targets;
3942

4043
}//end register()
@@ -47,12 +50,25 @@ public function register()
4750
* @param int $stackPtr The position of the current token in
4851
* the stack passed in $tokens.
4952
*
50-
* @return void
53+
* @return void|int Optionally returns a stack pointer. The sniff will not be
54+
* called again on the current file until the returned stack
55+
* pointer is reached. Return `$phpcsFile->numTokens` to skip
56+
* the rest of the file.
5157
*/
5258
public function process(File $phpcsFile, $stackPtr)
5359
{
5460
$tokens = $phpcsFile->getTokens();
5561

62+
// Skip over declare statements as those should be handled by different sniffs.
63+
if ($tokens[$stackPtr]['code'] === T_DECLARE) {
64+
if (isset($tokens[$stackPtr]['parenthesis_closer']) === false) {
65+
// Parse error / live coding.
66+
return $phpcsFile->numTokens;
67+
}
68+
69+
return $tokens[$stackPtr]['parenthesis_closer'];
70+
}
71+
5672
if ($this->isOperator($phpcsFile, $stackPtr) === false) {
5773
return;
5874
}

src/Standards/PSR12/Tests/Operators/OperatorSpacingUnitTest.inc renamed to src/Standards/PSR12/Tests/Operators/OperatorSpacingUnitTest.1.inc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,5 @@ function setDefault(#[ImportValue(
7575
{
7676
// Do something
7777
}
78+
79+
declare(strict_types=1);

src/Standards/PSR12/Tests/Operators/OperatorSpacingUnitTest.inc.fixed renamed to src/Standards/PSR12/Tests/Operators/OperatorSpacingUnitTest.1.inc.fixed

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,5 @@ function setDefault(#[ImportValue(
7575
{
7676
// Do something
7777
}
78+
79+
declare(strict_types=1);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
// Safeguard to ensure that sniff handles parse error/live coding correctly.
3+
declare(strict_types=

src/Standards/PSR12/Tests/Operators/OperatorSpacingUnitTest.php

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,32 +26,39 @@ final class OperatorSpacingUnitTest extends AbstractSniffUnitTest
2626
* The key of the array should represent the line number and the value
2727
* should represent the number of errors that should occur on that line.
2828
*
29+
* @param string $testFile The name of the file being tested.
30+
*
2931
* @return array<int, int>
3032
*/
31-
public function getErrorList()
33+
public function getErrorList($testFile='')
3234
{
33-
return [
34-
2 => 1,
35-
3 => 2,
36-
4 => 1,
37-
5 => 2,
38-
6 => 4,
39-
9 => 3,
40-
10 => 2,
41-
11 => 3,
42-
13 => 3,
43-
14 => 2,
44-
18 => 1,
45-
20 => 1,
46-
22 => 2,
47-
23 => 2,
48-
26 => 1,
49-
37 => 4,
50-
39 => 1,
51-
40 => 1,
52-
44 => 2,
53-
47 => 2,
54-
];
35+
switch ($testFile) {
36+
case 'OperatorSpacingUnitTest.1.inc':
37+
return [
38+
2 => 1,
39+
3 => 2,
40+
4 => 1,
41+
5 => 2,
42+
6 => 4,
43+
9 => 3,
44+
10 => 2,
45+
11 => 3,
46+
13 => 3,
47+
14 => 2,
48+
18 => 1,
49+
20 => 1,
50+
22 => 2,
51+
23 => 2,
52+
26 => 1,
53+
37 => 4,
54+
39 => 1,
55+
40 => 1,
56+
44 => 2,
57+
47 => 2,
58+
];
59+
default:
60+
return [];
61+
}//end switch
5562

5663
}//end getErrorList()
5764

src/Standards/Squiz/Sniffs/WhiteSpace/OperatorSpacingSniff.php

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ public function register()
114114
$targets[] = T_INLINE_ELSE;
115115
$targets[] = T_INSTANCEOF;
116116

117+
// Also register the contexts we want to specifically skip over.
118+
$targets[] = T_DECLARE;
119+
117120
return $targets;
118121

119122
}//end register()
@@ -126,12 +129,25 @@ public function register()
126129
* @param int $stackPtr The position of the current token in
127130
* the stack passed in $tokens.
128131
*
129-
* @return void
132+
* @return void|int Optionally returns a stack pointer. The sniff will not be
133+
* called again on the current file until the returned stack
134+
* pointer is reached. Return `$phpcsFile->numTokens` to skip
135+
* the rest of the file.
130136
*/
131137
public function process(File $phpcsFile, $stackPtr)
132138
{
133139
$tokens = $phpcsFile->getTokens();
134140

141+
// Skip over declare statements as those should be handled by different sniffs.
142+
if ($tokens[$stackPtr]['code'] === T_DECLARE) {
143+
if (isset($tokens[$stackPtr]['parenthesis_closer']) === false) {
144+
// Parse error / live coding.
145+
return $phpcsFile->numTokens;
146+
}
147+
148+
return $tokens[$stackPtr]['parenthesis_closer'];
149+
}
150+
135151
if ($this->isOperator($phpcsFile, $stackPtr) === false) {
136152
return;
137153
}
@@ -327,11 +343,13 @@ protected function isOperator(File $phpcsFile, $stackPtr)
327343
{
328344
$tokens = $phpcsFile->getTokens();
329345

346+
if ($tokens[$stackPtr]['code'] === T_DECLARE) {
347+
return false;
348+
}
349+
330350
// Skip default values in function declarations.
331351
// Skip declare statements.
332-
if ($tokens[$stackPtr]['code'] === T_EQUAL
333-
|| $tokens[$stackPtr]['code'] === T_MINUS
334-
) {
352+
if ($tokens[$stackPtr]['code'] === T_EQUAL) {
335353
if (isset($tokens[$stackPtr]['nested_parenthesis']) === true) {
336354
$parenthesis = array_keys($tokens[$stackPtr]['nested_parenthesis']);
337355
$bracket = array_pop($parenthesis);
@@ -340,7 +358,6 @@ protected function isOperator(File $phpcsFile, $stackPtr)
340358
if ($tokens[$function]['code'] === T_FUNCTION
341359
|| $tokens[$function]['code'] === T_CLOSURE
342360
|| $tokens[$function]['code'] === T_FN
343-
|| $tokens[$function]['code'] === T_DECLARE
344361
) {
345362
return false;
346363
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
// Safeguard to ensure that sniff handles parse error/live coding correctly.
3+
declare(strict_types=

src/Standards/Squiz/Tests/WhiteSpace/OperatorSpacingUnitTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ final class OperatorSpacingUnitTest extends AbstractSniffUnitTest
3333
public function getErrorList($testFile='')
3434
{
3535
switch ($testFile) {
36-
case 'OperatorSpacingUnitTest.inc':
36+
case 'OperatorSpacingUnitTest.1.inc':
3737
return [
3838
4 => 1,
3939
5 => 2,

0 commit comments

Comments
 (0)