-
-
Notifications
You must be signed in to change notification settings - Fork 189
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #165 from jrfnl/feature/required-optional-function…
…-parameters Add requiredOptionalFunctionParameters sniff.
- Loading branch information
Showing
3 changed files
with
228 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
<?php | ||
/** | ||
* PHPCompatibility_Sniffs_PHP_RequiredOptionalFunctionParametersSniff. | ||
* | ||
* @category PHP | ||
* @package PHPCompatibility | ||
* @author Wim Godden <wim.godden@cu.be> | ||
*/ | ||
|
||
/** | ||
* PHPCompatibility_Sniffs_PHP_RequiredOptionalFunctionParametersSniff. | ||
* | ||
* @category PHP | ||
* @package PHPCompatibility | ||
* @author Wim Godden <wim.godden@cu.be> | ||
*/ | ||
class PHPCompatibility_Sniffs_PHP_RequiredOptionalFunctionParametersSniff extends PHPCompatibility_Sniff | ||
{ | ||
|
||
/** | ||
* A list of function parameters, which were required in older versions and became optional later on. | ||
* | ||
* The array lists : version number with true (required) and false (optional). | ||
* | ||
* The index is the location of the parameter in the parameter list, starting at 0 ! | ||
* If's sufficient to list the last version in which the parameter was still required. | ||
* | ||
* @var array | ||
*/ | ||
protected $functionParameters = array( | ||
'preg_match_all' => array( | ||
2 => array( | ||
'name' => 'matches', | ||
'5.3' => true, | ||
'5.4' => false, | ||
), | ||
), | ||
'stream_socket_enable_crypto' => array( | ||
2 => array( | ||
'name' => 'crypto_type', | ||
'5.5' => true, | ||
'5.6' => false, | ||
), | ||
), | ||
); | ||
|
||
|
||
/** | ||
* Returns an array of tokens this test wants to listen for. | ||
* | ||
* @return array | ||
*/ | ||
public function register() | ||
{ | ||
return array(T_STRING); | ||
}//end register() | ||
|
||
/** | ||
* Processes this test, when one of its tokens is encountered. | ||
* | ||
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned. | ||
* @param int $stackPtr The position of the current token in | ||
* the stack passed in $tokens. | ||
* | ||
* @return void | ||
*/ | ||
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) | ||
{ | ||
$tokens = $phpcsFile->getTokens(); | ||
|
||
$ignore = array( | ||
T_DOUBLE_COLON, | ||
T_OBJECT_OPERATOR, | ||
T_FUNCTION, | ||
T_CONST, | ||
); | ||
|
||
$prevToken = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true); | ||
if (in_array($tokens[$prevToken]['code'], $ignore) === true) { | ||
// Not a call to a PHP function. | ||
return; | ||
} | ||
|
||
$function = strtolower($tokens[$stackPtr]['content']); | ||
|
||
if (isset($this->functionParameters[$function]) === false) { | ||
return; | ||
} | ||
|
||
$parameterCount = $this->getFunctionCallParameterCount($phpcsFile, $stackPtr); | ||
if ($parameterCount === 0) { | ||
return; | ||
} | ||
|
||
// If the parameter count returned > 0, we know there will be valid open parenthesis. | ||
$openParenthesis = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true); | ||
$parameterOffsetFound = $parameterCount - 1; | ||
$requiredVersion = null; | ||
$parameterName = null; | ||
|
||
foreach($this->functionParameters[$function] as $offset => $parameterDetails) { | ||
if ($offset > $parameterOffsetFound) { | ||
foreach ($parameterDetails as $version => $present) { | ||
if ($version !== 'name' && $present === true && $this->supportsBelow($version)) { | ||
$requiredVersion = $version; | ||
$parameterName = $parameterDetails['name']; | ||
} | ||
} | ||
} | ||
} | ||
|
||
if (isset($requiredVersion, $parameterName)) { | ||
|
||
$error = 'The "%s" parameter for function %s is missing, but was required for PHP version %s and lower'; | ||
$errorCode = 'MissingRequiredParameter'; | ||
$data = array( | ||
$parameterName, | ||
$function, | ||
$requiredVersion, | ||
); | ||
$phpcsFile->addError($error, $openParenthesis, $errorCode, $data); | ||
} | ||
|
||
}//end process() | ||
|
||
}//end class |
93 changes: 93 additions & 0 deletions
93
Tests/Sniffs/PHP/RequiredOptionalFunctionParameterSniffTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
<?php | ||
/** | ||
* Required Optional Functions Parameter Sniff test file | ||
* | ||
* @package PHPCompatibility | ||
*/ | ||
|
||
|
||
/** | ||
* Required Optional Parameter Sniff test file | ||
* | ||
* @uses BaseSniffTest | ||
* @package PHPCompatibility | ||
* @author Wim Godden <wim@cu.be> | ||
*/ | ||
class RequiredOptionalFunctionParameterSniffTest extends BaseSniffTest | ||
{ | ||
|
||
const TEST_FILE = 'sniff-examples/required_optional_function_parameters.php'; | ||
|
||
/** | ||
* testRequiredOptionalParameter | ||
* | ||
* @dataProvider dataRequiredOptionalParameter | ||
* | ||
* @param string $functionName Function name. | ||
* @param string $parameterName Parameter name. | ||
* @param string $requiredUpTo The last PHP version in which the parameter was still required. | ||
* @param array $lines The line numbers in the test file which apply to this class. | ||
* @param string $okVersion A PHP version in which to test for no violation. | ||
* | ||
* @return void | ||
*/ | ||
public function testRequiredOptionalParameter($functionName, $parameterName, $requiredUpTo, $lines, $okVersion) | ||
{ | ||
$file = $this->sniffFile(self::TEST_FILE, $requiredUpTo); | ||
foreach ($lines as $line) { | ||
$this->assertError($file, $line, "The \"{$parameterName}\" parameter for function {$functionName} is missing, but was required for PHP version {$requiredUpTo} and lower"); | ||
} | ||
|
||
$file = $this->sniffFile(self::TEST_FILE, $okVersion); | ||
foreach ($lines as $line) { | ||
$this->assertNoViolation($file, $line); | ||
} | ||
} | ||
|
||
/** | ||
* Data provider. | ||
* | ||
* @see testRequiredOptionalParameter() | ||
* | ||
* @return array | ||
*/ | ||
public function dataRequiredOptionalParameter() | ||
{ | ||
return array( | ||
array('preg_match_all', 'matches', '5.3', array(8), '5.4'), | ||
array('stream_socket_enable_crypto', 'crypto_type', '5.5', array(9), '5.6'), | ||
); | ||
} | ||
|
||
|
||
/** | ||
* testValidParameter | ||
* | ||
* @dataProvider dataValidParameter | ||
* | ||
* @param int $line The line number. | ||
* | ||
* @return void | ||
*/ | ||
public function testValidParameter($line) | ||
{ | ||
$file = $this->sniffFile(self::TEST_FILE, '7.0'); | ||
$this->assertNoViolation($file, $line); | ||
} | ||
|
||
/** | ||
* Data provider. | ||
* | ||
* @see testValidParameter() | ||
* | ||
* @return array | ||
*/ | ||
public function dataValidParameter() | ||
{ | ||
return array( | ||
array(4), | ||
array(5), | ||
); | ||
} | ||
|
||
} |
9 changes: 9 additions & 0 deletions
9
Tests/sniff-examples/required_optional_function_parameters.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
|
||
// These are ok. | ||
preg_match_all('`[a-z]+`', $subject, $matches); | ||
stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_SSLv23_CLIENT); | ||
|
||
// These are not. | ||
preg_match_all('`[a-z]+`', $subject); | ||
stream_socket_enable_crypto($fp, true); |