Skip to content

Commit ad34a36

Browse files
committed
Merge branch 'master' of github.com:squizlabs/PHP_CodeSniffer
2 parents 3a72428 + 6621431 commit ad34a36

File tree

9 files changed

+383
-35
lines changed

9 files changed

+383
-35
lines changed

package.xml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,19 @@ http://pear.php.net/dtd/package-2.0.xsd">
4444
- The T_LIST token and it's opening and closing parentheses now contain references to each other in the tokens array
4545
-- Uses the same parenthesis_opener/closer/owner indexes as other tokens
4646
-- Thanks to Juliette Reinders Folmer for the patch
47+
- Added Generic.ControlStructures.DisallowYodaConditions sniff
48+
-- Ban the use of Yoda conditions
49+
-- Thanks to Mponos George for the contribution
50+
- Generic.Functions.FunctionCallArgumentSpacing no longer checks spacing around assignment operators inside function calls
51+
-- Use the Squiz.WhiteSpace.OperatorSpacing sniff to enforce spacing around assignment operators
52+
--- Note that this sniff checks spacing around all assignment operators, not just inside function calls
53+
-- The Generic.Functions.FunctionCallArgumentSpacing.NoSpaceBeforeEquals error has been removed
54+
--- use Squiz.WhiteSpace.OperatorSpacing.NoSpaceBefore instead
55+
-- The Generic.Functions.FunctionCallArgumentSpacing.NoSpaceAfterEquals error has been removed
56+
--- use Squiz.WhiteSpace.OperatorSpacing.NoSpaceAfter instead
57+
-- This also changes the PEAR/PSR2/PSR12 standards so they no longer check assignment operators inside function calls
58+
--- They were previously checking these operators when they should not have
59+
-- Thanks to Juliette Reinders Folmer for the patch
4760
- Generic.WhiteSpace.ScopeIndent no longer performs exact indents checking for chained method calls
4861
-- Other sniffs can be used to enforce chained method call indent rules
4962
-- Thanks to Pieter Frenssen for the patch
@@ -210,6 +223,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
210223
<file baseinstalldir="PHP/CodeSniffer" name="UnusedFunctionParameterStandard.xml" role="php" />
211224
</dir>
212225
<dir name="ControlStructures">
226+
<file baseinstalldir="PHP/CodeSniffer" name="DisallowYodaConditionsStandard.xml" role="php" />
213227
<file baseinstalldir="PHP/CodeSniffer" name="InlineControlStructureStandard.xml" role="php" />
214228
</dir>
215229
<dir name="CodeAnalysis">
@@ -313,6 +327,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
313327
<file baseinstalldir="PHP/CodeSniffer" name="TodoSniff.php" role="php" />
314328
</dir>
315329
<dir name="ControlStructures">
330+
<file baseinstalldir="PHP/CodeSniffer" name="DisallowYodaConditionsSniff.php" role="php" />
316331
<file baseinstalldir="PHP/CodeSniffer" name="InlineControlStructureSniff.php" role="php" />
317332
</dir>
318333
<dir name="Debug">
@@ -453,6 +468,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
453468
<file baseinstalldir="PHP/CodeSniffer" name="TodoUnitTest.php" role="test" />
454469
</dir>
455470
<dir name="ControlStructures">
471+
<file baseinstalldir="PHP/CodeSniffer" name="DisallowYodaConditionsUnitTest.inc" role="test" />
472+
<file baseinstalldir="PHP/CodeSniffer" name="DisallowYodaConditionsUnitTest.php" role="test" />
456473
<file baseinstalldir="PHP/CodeSniffer" name="InlineControlStructureUnitTest.1.inc" role="test" />
457474
<file baseinstalldir="PHP/CodeSniffer" name="InlineControlStructureUnitTest.1.inc.fixed" role="test" />
458475
<file baseinstalldir="PHP/CodeSniffer" name="InlineControlStructureUnitTest.2.inc" role="test" />
@@ -1906,7 +1923,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
19061923
- Squiz.Arrays.ArrayDeclaration now has improved handling of syntax errors
19071924
- Fixed an issue where the PCRE JIT on PHP 7.3 caused PHPCS to die when using the parallel option
19081925
-- PHPCS now disables the PCRE JIT before running
1909-
- Fixed bug #2368 : MySource.PHP.AjaxNullComparison throws error when first function has no doc comment
1926+
- Fixed bug #2368 : MySource.PHP.AjaxNullComparison throws error when first function has no doc comment
19101927
- Fixed bug #2414 : Indention false positive in switch/case/if combination
19111928
- Fixed bug #2423 : Squiz.Formatting.OperatorBracket.MissingBrackets error with static
19121929
- Fixed bug #2450 : Indentation false positive when closure containing nested IF conditions used as function argument
@@ -1935,7 +1952,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
19351952
-- The Generic.Formatting.SpaceBeforeCast sniff was not previously available for PEAR installs
19361953
-- The Generic.WhiteSpace.LanguageConstructSpacing sniff was not previously available for PEAR installs
19371954
-- Thanks to Juliette Reinders Folmer for the patch
1938-
1955+
19391956
- PHPCS will now refuse to run if any of the required PHP extensions are not loaded
19401957
-- Previously, PHPCS only relied on requirements being checked by PEAR and Composer
19411958
-- Thanks to Juliette Reinders Folmer for the patch

src/Generators/Text.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ protected function printCodeComparisonBlock(\DOMNode $node)
138138
$tempTitle = '';
139139
} else {
140140
$firstTitleLines[] = $tempTitle;
141-
$tempTitle = $word;
141+
$tempTitle = $word.' ';
142142
}
143143
} else {
144144
$tempTitle .= $word.' ';
@@ -173,7 +173,7 @@ protected function printCodeComparisonBlock(\DOMNode $node)
173173
$tempTitle = '';
174174
} else {
175175
$secondTitleLines[] = $tempTitle;
176-
$tempTitle = $word;
176+
$tempTitle = $word.' ';
177177
}
178178
} else {
179179
$tempTitle .= $word.' ';
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<documentation title="Disallow Yoda conditions">
2+
<standard>
3+
<![CDATA[
4+
Yoda conditions are disallowed.
5+
]]>
6+
</standard>
7+
<code_comparison>
8+
<code title="Valid: value to be asserted must go on the right side of the comparison.">
9+
<![CDATA[
10+
if ($test === null) <em>{</em>
11+
$var = 1;
12+
<em>}</em>
13+
]]>
14+
</code>
15+
<code title="Invalid: value to be asserted must not be on the left.">
16+
<![CDATA[
17+
if (null === $test) <em>{</em>
18+
$var = 1;
19+
<em>}</em>
20+
]]>
21+
</code>
22+
</code_comparison>
23+
</documentation>
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php
2+
/**
3+
* Ban the use of Yoda conditions.
4+
*
5+
* @author Mponos George <gmponos@gmail.com>
6+
* @author Mark Scherer <username@example.com>
7+
* @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
8+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
9+
*/
10+
11+
namespace PHP_CodeSniffer\Standards\Generic\Sniffs\ControlStructures;
12+
13+
use PHP_CodeSniffer\Files\File;
14+
use PHP_CodeSniffer\Sniffs\Sniff;
15+
use PHP_CodeSniffer\Util\Tokens;
16+
17+
class DisallowYodaConditionsSniff implements Sniff
18+
{
19+
20+
21+
/**
22+
* Returns an array of tokens this test wants to listen for.
23+
*
24+
* @return array
25+
*/
26+
public function register()
27+
{
28+
return Tokens::$comparisonTokens;
29+
30+
}//end register()
31+
32+
33+
/**
34+
* Processes this test, when one of its tokens is encountered.
35+
*
36+
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
37+
* @param int $stackPtr The position of the current token in the
38+
* stack passed in $tokens.
39+
*
40+
* @return void
41+
*/
42+
public function process(File $phpcsFile, $stackPtr)
43+
{
44+
$tokens = $phpcsFile->getTokens();
45+
$previousIndex = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
46+
$relevantTokens = [
47+
T_CLOSE_SHORT_ARRAY,
48+
T_CLOSE_PARENTHESIS,
49+
T_TRUE,
50+
T_FALSE,
51+
T_NULL,
52+
T_LNUMBER,
53+
T_DNUMBER,
54+
T_CONSTANT_ENCAPSED_STRING,
55+
];
56+
57+
if ($previousIndex === false
58+
|| in_array($tokens[$previousIndex]['code'], $relevantTokens, true) === false
59+
) {
60+
return;
61+
}
62+
63+
if ($tokens[$previousIndex]['code'] === T_CLOSE_SHORT_ARRAY) {
64+
$previousIndex = $tokens[$previousIndex]['bracket_opener'];
65+
}
66+
67+
$prevIndex = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($previousIndex - 1), null, true);
68+
if ($prevIndex === false) {
69+
return;
70+
}
71+
72+
if (in_array($tokens[$prevIndex]['code'], Tokens::$arithmeticTokens, true) === true) {
73+
return;
74+
}
75+
76+
if ($tokens[$prevIndex]['code'] === T_STRING_CONCAT) {
77+
return;
78+
}
79+
80+
// Is it a parenthesis.
81+
if ($tokens[$previousIndex]['code'] === T_CLOSE_PARENTHESIS) {
82+
// Check what exists inside the parenthesis.
83+
$closeParenthesisIndex = $phpcsFile->findPrevious(
84+
Tokens::$emptyTokens,
85+
($tokens[$previousIndex]['parenthesis_opener'] - 1),
86+
null,
87+
true
88+
);
89+
90+
if ($closeParenthesisIndex === false || $tokens[$closeParenthesisIndex]['code'] !== T_ARRAY) {
91+
if ($tokens[$closeParenthesisIndex]['code'] === T_STRING) {
92+
return;
93+
}
94+
95+
// If it is not an array check what is inside.
96+
$found = $phpcsFile->findPrevious(
97+
T_VARIABLE,
98+
($previousIndex - 1),
99+
$tokens[$previousIndex]['parenthesis_opener']
100+
);
101+
102+
// If a variable exists it is not Yoda.
103+
if ($found !== false) {
104+
return;
105+
}
106+
}
107+
}//end if
108+
109+
$phpcsFile->addError(
110+
'Usage of Yoda conditions is not allowed; switch the expression order',
111+
$stackPtr,
112+
'Found'
113+
);
114+
115+
}//end process()
116+
117+
118+
}//end class

src/Standards/Generic/Sniffs/Functions/FunctionCallArgumentSpacingSniff.php

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ public function process(File $phpcsFile, $stackPtr)
8787

8888
$find = [
8989
T_COMMA,
90-
T_VARIABLE,
9190
T_CLOSURE,
9291
T_ANON_CLASS,
9392
T_OPEN_SHORT_ARRAY,
@@ -157,28 +156,6 @@ public function process(File $phpcsFile, $stackPtr)
157156
}
158157
}
159158
}//end if
160-
} else {
161-
// Token is a variable.
162-
$nextToken = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextSeparator + 1), $closeBracket, true);
163-
if ($nextToken !== false) {
164-
if ($tokens[$nextToken]['code'] === T_EQUAL) {
165-
if (($tokens[($nextToken - 1)]['code']) !== T_WHITESPACE) {
166-
$error = 'Expected 1 space before = sign of default value';
167-
$fix = $phpcsFile->addFixableError($error, $nextToken, 'NoSpaceBeforeEquals');
168-
if ($fix === true) {
169-
$phpcsFile->fixer->addContentBefore($nextToken, ' ');
170-
}
171-
}
172-
173-
if ($tokens[($nextToken + 1)]['code'] !== T_WHITESPACE) {
174-
$error = 'Expected 1 space after = sign of default value';
175-
$fix = $phpcsFile->addFixableError($error, $nextToken, 'NoSpaceAfterEquals');
176-
if ($fix === true) {
177-
$phpcsFile->fixer->addContent($nextToken, ' ');
178-
}
179-
}
180-
}
181-
}
182159
}//end if
183160
}//end while
184161

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
<?php
2+
3+
$value = '';
4+
// Check booleans
5+
if ($value === true) {}
6+
if ($value == true) {}
7+
if (true === $value) {}
8+
if (true == $value) {}
9+
10+
if($value === true){}
11+
if($value == true){}
12+
if(false === $value){}
13+
if(!false == $value || true !== $value){}
14+
15+
// check integer comparison
16+
if($value === 5){}
17+
if($value == 5){}
18+
if(5 === $value){}
19+
if(5 == $value){}
20+
21+
// check float comparison
22+
if($value === 5.2){}
23+
if($value == 5.2){}
24+
if(5.2 === $value){}
25+
if(5.2 == $value){}
26+
27+
// check null comparison
28+
if($value === null){}
29+
if($value == null){}
30+
if(null === $value){}
31+
if(null == $value){}
32+
33+
if(
34+
$value
35+
===
36+
null
37+
){}
38+
if(
39+
null
40+
===
41+
$value
42+
){}
43+
44+
// check string comparison
45+
if($value === 'string'){}
46+
if($value == 'string'){}
47+
if('string' === $value){}
48+
if('string' == $value){}
49+
50+
if([] === $value){}
51+
if($value === [] ){}
52+
if([] == $value){}
53+
if($value == [] ){}
54+
55+
if($value === array()){}
56+
if($value == array()){}
57+
if(array() === $value){}
58+
if(array() == $value){}
59+
60+
// check string comparison
61+
$assigned = $value === 'string';
62+
$assigned = 'string' == $value;
63+
64+
if(($value) === $otherValue){}
65+
if($value === ($otherValue)){}
66+
67+
if(($value) === true){}
68+
if((true) === $value){}
69+
70+
if(($value + 1 + 1) === $value){}
71+
if(($value + $value) === $value){}
72+
73+
if($value == self::CONSTANT_1){}
74+
75+
const CONSTANT1 = 1;
76+
if($value === CONSTANT1){}
77+
if(CONSTANT1 === $value){}
78+
79+
if($value === ($value1 | $value2)){}
80+
if(($value1 | $value2) === $value){}
81+
82+
// Check with objects
83+
if($object->myVar === $value){}
84+
if($value === $object->myVar){}
85+
86+
if($object->function() === $value){}
87+
if($value === $object->function()){}
88+
89+
// Check with functions
90+
if(myFunction() === $value){}
91+
if($value === myFunction()){}
92+
93+
// check with multiple operations
94+
if($value === true && $value === 1 && $value === null){}
95+
if(($value === true && $value === 1) == ($value === null && $value === new stdClass())){}
96+
97+
if(true === $value && 1 === $value && null === $value){}
98+
if((true === $value && 1 === $value) == (null === $value && new stdClass() === $value)){}
99+
100+
// Add comments in the middle
101+
if(
102+
//comment
103+
true
104+
// comment
105+
===
106+
// comment
107+
$value
108+
){}
109+
110+
if(
111+
//comment
112+
$value
113+
// comment
114+
===
115+
// comment
116+
true
117+
){}
118+
119+
if(array($key => $val) === $value){}
120+
if(array($key => $val) == $value){}
121+
122+
if([$key => $val] === $value){}
123+
if([$key => $val] == $value){}
124+
125+
$config['checkAuthIn'] !== $event->getName();
126+
127+
if ($var === "ab" || 'cd') {}
128+
if ("ab" || 'cd' === $var) {}
129+
if (2 > $value || 3 < $var) {}
130+
if ($value == true && (/* comment */ 2 > test())) {}
131+
if ((int) 5 > $var) {}
132+
if ((int) $var > (int) 5) {}
133+
if (true == function() { return false;}){}
134+
if (function() { return false;} == true){}

0 commit comments

Comments
 (0)