Skip to content

Commit 4619ac1

Browse files
Daniel MüllerDaniel Müller
authored andcommitted
Merge pull request #6 in CFA/coding-guidelines from yoda to master
* commit 'fa7fad7be2a3dee4cf272d1f071d748fcbf5af8d': - Added YODA test cases - Added yoda sniff - Updated readme
2 parents 35c998a + fa7fad7 commit 4619ac1

15 files changed

+235
-2
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,10 @@ make test
4848

4949
Use within PHPStorm
5050
-------------------
51-
- Open settings:
52-
`File` > `Default Settings...` > `Editor` > `Inspections` > `PHP`
51+
- Open settings: \
52+
Mac: `PhpStorm` > `Preferences` > `Editor` > `Inspections` > `PHP` \
53+
Windows: \<unknown>\
54+
Linux: \<unknown>
5355
- Activate Option `PHP Code Sniffer validation`
5456
- Choose "Custom" for „Coding standard:“ and click on `...` on the right hand side
5557
- Select Path to ruleset. This would be something like <YOUR_APP_ROOT>/vendor/flyeralarm/coding-guidelines/ruleset.xml
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?php
2+
3+
namespace flyeralarm\CodingGuidelines\Flyeralarm\Sniffs\ControlStructures;
4+
5+
use PHP_CodeSniffer\Sniffs\Sniff;
6+
use PHP_CodeSniffer\Files\File;
7+
8+
class YodaSniff implements Sniff
9+
{
10+
/**
11+
* @return array
12+
*/
13+
public function register()
14+
{
15+
return array(T_IF, T_ELSEIF, T_WHILE);
16+
}
17+
18+
/**
19+
* @param File $phpcsFile
20+
* @param int $stackPtr
21+
* @return void
22+
*/
23+
public function process(File $phpcsFile, $stackPtr)
24+
{
25+
$tokens = $phpcsFile->getTokens();
26+
27+
$startOfConditionPtr = $stackPtr;
28+
$endPtr = $tokens[$startOfConditionPtr]['scope_opener'] + 1;
29+
30+
$logicalOperatorTokenIds = [T_BOOLEAN_AND, T_BOOLEAN_OR, T_LOGICAL_AND, T_LOGICAL_OR, T_LOGICAL_XOR];
31+
$scopeOpenerTokenIds = [T_OPEN_CURLY_BRACKET];
32+
$tokenIdsToFindAllConditions = array_merge($logicalOperatorTokenIds, $scopeOpenerTokenIds);
33+
34+
while ($endOfConditionPtr = $phpcsFile->findNext($tokenIdsToFindAllConditions, $startOfConditionPtr, $endPtr)) {
35+
$this->checkConditionalOrderForArithmeticExpression($phpcsFile, $startOfConditionPtr, $endOfConditionPtr);
36+
$startOfConditionPtr = $endOfConditionPtr + 1;
37+
}
38+
}
39+
40+
/**
41+
* @param File $phpcsFile
42+
* @param $startOfConditionPtr
43+
* @param $endOfConditionPtr
44+
*/
45+
private function checkConditionalOrderForArithmeticExpression(
46+
File $phpcsFile,
47+
$startOfConditionPtr,
48+
$endOfConditionPtr
49+
) {
50+
$tokens = $phpcsFile->getTokens();
51+
$logicalOperatorPtr = $phpcsFile->findNext(
52+
[
53+
T_IS_NOT_IDENTICAL,
54+
T_IS_IDENTICAL,
55+
T_IS_NOT_EQUAL,
56+
T_IS_EQUAL,
57+
T_IS_GREATER_OR_EQUAL,
58+
T_IS_SMALLER_OR_EQUAL,
59+
T_LESS_THAN,
60+
T_GREATER_THAN,
61+
],
62+
$startOfConditionPtr,
63+
$endOfConditionPtr
64+
);
65+
66+
// e.g. if ($foo)
67+
if (!$logicalOperatorPtr) {
68+
return;
69+
}
70+
71+
$languageTypeTokenIds = [T_NULL, T_TRUE, T_FALSE, T_ARRAY, T_CONSTANT_ENCAPSED_STRING, T_LNUMBER];
72+
$functionAndVariableTokenIds = [T_STRING, T_VARIABLE]; // T_STRING matches count() for example
73+
$operandTokenIds = array_merge($languageTypeTokenIds, $functionAndVariableTokenIds);
74+
75+
$leftOperandPtr = $phpcsFile->findNext($operandTokenIds, $startOfConditionPtr, $logicalOperatorPtr);
76+
if (!$leftOperandPtr) {
77+
return;
78+
}
79+
80+
$rightOperandPtr = $phpcsFile->findNext($operandTokenIds, $logicalOperatorPtr, $endOfConditionPtr);
81+
if (!$rightOperandPtr) {
82+
return;
83+
}
84+
85+
$leftOperandTokenId = $tokens[$leftOperandPtr]['code'];
86+
$rightOperandTokenId = $tokens[$rightOperandPtr]['code'];
87+
88+
// e.g. if ($foo = true)
89+
// e.g. if ($foo = 'bar')
90+
if (in_array($leftOperandTokenId, $functionAndVariableTokenIds)
91+
&& in_array($rightOperandTokenId, $languageTypeTokenIds)
92+
) {
93+
return;
94+
}
95+
// e.g. if (count(..) > $test)
96+
// e.g. if ($foo == $bar)
97+
if (in_array($leftOperandTokenId, $functionAndVariableTokenIds)
98+
&& in_array($rightOperandTokenId, $functionAndVariableTokenIds)
99+
) {
100+
return;
101+
}
102+
// e.g. if ('foo' == 'bar')
103+
if (in_array($leftOperandTokenId, $languageTypeTokenIds)
104+
&& in_array($rightOperandTokenId, $languageTypeTokenIds)) {
105+
return;
106+
}
107+
108+
$phpcsFile->addError(
109+
'YODA is discouraged',
110+
$leftOperandPtr,
111+
'ConditionalOrder'
112+
);
113+
}
114+
}

ruleset.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@
1212
<rule ref="./custom-standards/Flyeralarm/Sniffs/File/NoClassKindSuffixSniff.php"/>
1313
<rule ref="./custom-standards/Flyeralarm/Sniffs/Docblock/ReturnTypeSniff.php"/>
1414
<rule ref="./custom-standards/Flyeralarm/Sniffs/Docblock/ExpectedExceptionMessageSniff.php"/>
15+
<rule ref="./custom-standards/Flyeralarm/Sniffs/ControlStructures/YodaSniff.php"/>
1516
</ruleset>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
// @expectedPass
4+
5+
$foo = 'bar';
6+
$bar = 'foo';
7+
8+
9+
if (true) {
10+
} elseif ($foo == 'bar') {
11+
} elseif ($foo == 'bar' && $bar == 'foo') {
12+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
// @expectedPass
4+
5+
$foo = [];
6+
$bar = 0;
7+
8+
if (count($foo) > $bar) {
9+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
// @expectedPass
4+
5+
$foo = true;
6+
7+
if (!$foo) {
8+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
// @expectedPass
4+
5+
namespace flyeralarm\CodingGuidelines;
6+
7+
class IfThisIsTrueEqualsTrue
8+
{
9+
private $isTrue;
10+
11+
public function foo()
12+
{
13+
if ($this->isTrue == true) {
14+
}
15+
}
16+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
3+
// @expectedPass
4+
5+
if (true) {
6+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
// @expectedPass
4+
5+
$foo = 'bar';
6+
7+
if ($foo == 'bar') {
8+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
// @expectedPass
4+
5+
$foo = 'bar';
6+
$bar = 'foo';
7+
8+
if ($foo == $bar) {
9+
}

0 commit comments

Comments
 (0)