From f16591d29a03810099064cfa0d8625dbecc5a9eb Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 5 Feb 2016 11:30:29 +0100 Subject: [PATCH] Disallow assignments in if, elseif and do-while conditions --- .../AssignmentInConditionSniff.php | 67 +++++++++++++++++++ .../AssignmentInConditionSniffTest.php | 34 ++++++++++ .../data/allAssignmentsInConditions.php | 6 ++ .../data/noAssignmentsInConditions.php | 45 +++++++++++++ 4 files changed, 152 insertions(+) create mode 100644 SlevomatCodingStandard/Sniffs/ControlStructures/AssignmentInConditionSniff.php create mode 100644 tests/Sniffs/ControlStructures/AssignmentInConditionSniffTest.php create mode 100644 tests/Sniffs/ControlStructures/data/allAssignmentsInConditions.php create mode 100644 tests/Sniffs/ControlStructures/data/noAssignmentsInConditions.php diff --git a/SlevomatCodingStandard/Sniffs/ControlStructures/AssignmentInConditionSniff.php b/SlevomatCodingStandard/Sniffs/ControlStructures/AssignmentInConditionSniff.php new file mode 100644 index 000000000..d5fcfeedf --- /dev/null +++ b/SlevomatCodingStandard/Sniffs/ControlStructures/AssignmentInConditionSniff.php @@ -0,0 +1,67 @@ +getTokens(); + $token = $tokens[$conditionStartPointer]; + if ($token['code'] === T_DO) { + $whilePointer = $phpcsFile->findNext(T_WHILE, $token['scope_closer'] + 1); + $whileToken = $tokens[$whilePointer]; + $parenthesisOpener = $whileToken['parenthesis_opener']; + $parenthesisCloser = $whileToken['parenthesis_closer']; + $type = 'do-while'; + } else { + $parenthesisOpener = $token['parenthesis_opener']; + $parenthesisCloser = $token['parenthesis_closer']; + $type = $token['code'] === T_IF ? 'if' : 'elseif'; + } + $this->processCondition($phpcsFile, $parenthesisOpener, $parenthesisCloser, $type); + } + + /** + * @param \PHP_CodeSniffer_File $phpcsFile + * @param integer $parenthesisOpener + * @param integer $parenthesisCloser + * @param string $conditionType + */ + private function processCondition( + \PHP_CodeSniffer_File $phpcsFile, + $parenthesisOpener, + $parenthesisCloser, + $conditionType + ) + { + $equalsTokenPointer = $phpcsFile->findNext(T_EQUAL, $parenthesisOpener + 1, $parenthesisCloser); + if ($equalsTokenPointer !== false) { + $phpcsFile->addError( + sprintf('Assignment in %s condition is not allowed', $conditionType), + $equalsTokenPointer, + self::CODE_ASSIGNMENT_IN_CONDITION + ); + } + } + +} diff --git a/tests/Sniffs/ControlStructures/AssignmentInConditionSniffTest.php b/tests/Sniffs/ControlStructures/AssignmentInConditionSniffTest.php new file mode 100644 index 000000000..99e693801 --- /dev/null +++ b/tests/Sniffs/ControlStructures/AssignmentInConditionSniffTest.php @@ -0,0 +1,34 @@ +checkFile(__DIR__ . '/data/noAssignmentsInConditions.php'); + $this->assertNoSniffErrorInFile($resultFile); + } + + public function dataIncorrectFile() + { + $lineNumbers = []; + foreach (range(3, 6) as $lineNumber) { + $lineNumbers[$lineNumber] = [$lineNumber]; + } + + return $lineNumbers; + } + + /** + * @dataProvider dataIncorrectFile + * @param integer $lineNumber + */ + public function testIncorrectFile($lineNumber) + { + $resultFile = $this->checkFile(__DIR__ . '/data/allAssignmentsInConditions.php'); + $this->assertSniffError($resultFile, $lineNumber, AssignmentInConditionSniff::CODE_ASSIGNMENT_IN_CONDITION); + } + +} diff --git a/tests/Sniffs/ControlStructures/data/allAssignmentsInConditions.php b/tests/Sniffs/ControlStructures/data/allAssignmentsInConditions.php new file mode 100644 index 000000000..09a73fcdb --- /dev/null +++ b/tests/Sniffs/ControlStructures/data/allAssignmentsInConditions.php @@ -0,0 +1,6 @@ +fetch()) !== null) { + +} + +do { + +} while ($foo === 5);