Skip to content

Commit

Permalink
Merge pull request #269 from PHPCSStandards/passedparameters/add-new-…
Browse files Browse the repository at this point in the history
…isshortarray-param

PassedParameters::[has|get]Parameters(): add new, optional `$isShortArray` parameter
  • Loading branch information
jrfnl committed May 20, 2021
2 parents 935c27f + 0afbbf0 commit 4968182
Show file tree
Hide file tree
Showing 3 changed files with 238 additions and 13 deletions.
35 changes: 22 additions & 13 deletions PHPCSUtils/Utils/PassedParameters.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,21 @@ class PassedParameters
* @since 1.0.0
* @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokenization.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found.
* @param int $stackPtr The position of the `T_STRING`, PHP 8.0 identifier
* name token, `T_VARIABLE`, `T_ARRAY`, `T_OPEN_SHORT_ARRAY`,
* `T_ISSET`, or `T_UNSET` token.
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found.
* @param int $stackPtr The position of the `T_STRING`, PHP 8.0 identifier
* name token, `T_VARIABLE`, `T_ARRAY`, `T_OPEN_SHORT_ARRAY`,
* `T_ISSET`, or `T_UNSET` token.
* @param true|null $isShortArray Optional. Short-circuit the short array check for
* `T_OPEN_SHORT_ARRAY` tokens if it isn't necessary.
* Efficiency tweak for when this has already been established,
* Use with EXTREME care.
*
* @return bool
*
* @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the token passed is not one of the
* accepted types or doesn't exist.
*/
public static function hasParameters(File $phpcsFile, $stackPtr)
public static function hasParameters(File $phpcsFile, $stackPtr, $isShortArray = null)
{
$tokens = $phpcsFile->getTokens();

Expand All @@ -94,6 +98,7 @@ public static function hasParameters(File $phpcsFile, $stackPtr)

if (($tokens[$stackPtr]['code'] === \T_OPEN_SHORT_ARRAY
|| $tokens[$stackPtr]['code'] === \T_OPEN_SQUARE_BRACKET)
&& $isShortArray !== true
&& Arrays::isShortArray($phpcsFile, $stackPtr) === false
) {
throw new RuntimeException(
Expand Down Expand Up @@ -148,12 +153,16 @@ public static function hasParameters(File $phpcsFile, $stackPtr)
* @since 1.0.0-alpha4 Added support for PHP 8.0 function calls with named arguments by
* introducing the new `'name_start'`, `'name_end'` and `'name'` index keys.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found.
* @param int $stackPtr The position of the `T_STRING`, PHP 8.0 identifier
* name token, `T_VARIABLE`, `T_ARRAY`, `T_OPEN_SHORT_ARRAY`,
* `T_ISSET`, or `T_UNSET` token.
* @param int $limit Optional. Limit the parameter retrieval to the first #
* parameters/array entries.
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found.
* @param int $stackPtr The position of the `T_STRING`, PHP 8.0 identifier
* name token, `T_VARIABLE`, `T_ARRAY`, `T_OPEN_SHORT_ARRAY`,
* `T_ISSET`, or `T_UNSET` token.
* @param int $limit Optional. Limit the parameter retrieval to the first #
* parameters/array entries.
* @param true|null $isShortArray Optional. Short-circuit the short array check for
* `T_OPEN_SHORT_ARRAY` tokens if it isn't necessary.
* Efficiency tweak for when this has already been established,
* Use with EXTREME care.
*
* @return array A multi-dimentional array information on each parameter/array item.
* The information gathered about each parameter/array item is in the following format:
Expand Down Expand Up @@ -188,9 +197,9 @@ public static function hasParameters(File $phpcsFile, $stackPtr)
* @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the token passed is not one of the
* accepted types or doesn't exist.
*/
public static function getParameters(File $phpcsFile, $stackPtr, $limit = 0)
public static function getParameters(File $phpcsFile, $stackPtr, $limit = 0, $isShortArray = null)
{
if (self::hasParameters($phpcsFile, $stackPtr) === false) {
if (self::hasParameters($phpcsFile, $stackPtr, $isShortArray) === false) {
return [];
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

/* testNoParams */
$foo = [];

/* testLongArray */
$foo = array( 1, 2 );

/* testShortArray */
$foo = [ 'a' => 1, 'b' => 2 ];

/* testShortList */
[ 'a' => 1, 'b' => 2 ] = $array;

/* testArrayAssign */
$array[] = 'foo';

/* testArrayAccess */
$foo = $array[$keys['key']];
197 changes: 197 additions & 0 deletions Tests/Utils/PassedParameters/GetParametersSkipShortArrayCheckTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
<?php
/**
* PHPCSUtils, utility functions and classes for PHP_CodeSniffer sniff developers.
*
* @package PHPCSUtils
* @copyright 2019-2020 PHPCSUtils Contributors
* @license https://opensource.org/licenses/LGPL-3.0 LGPL3
* @link https://github.com/PHPCSStandards/PHPCSUtils
*/

namespace PHPCSUtils\Tests\Utils\PassedParameters;

use PHPCSUtils\TestUtils\UtilityMethodTestCase;
use PHPCSUtils\Utils\PassedParameters;

/**
* Tests for the \PHPCSUtils\Utils\PassedParameters::hasParameters() and
* the \PHPCSUtils\Utils\PassedParameters::getParameters() methods for
* when the $isShortArray parameter has been passed.
*
* @covers \PHPCSUtils\Utils\PassedParameters::hasParameters
* @covers \PHPCSUtils\Utils\PassedParameters::getParameters
*
* @group passedparameters
*
* @since 1.0.0
*/
class GetParametersSkipShortArrayCheckTest extends UtilityMethodTestCase
{

/**
* Test receiving an expected exception when passed an invalid (non short array) token when the
* `$isShortArray` parameter is NOT passed (or not set to true).
*
* Also verify that for valid constructs, the method still behaves like normal.
*
* @dataProvider dataTestCases
*
* @param string $testMarker The comment which prefaces the target token in the test file.
* @param int|string $targetType The type of token to look for.
* @param bool $expectException Whether or not to expect an exception.
*
* @return void
*/
public function testHasParametersDontSkipShortArrayCheck($testMarker, $targetType, $expectException)
{
if ($expectException === true) {
$this->expectPhpcsException(
'The hasParameters() method expects a function call, array, isset or unset token to be passed.'
);
}

$target = $this->getTargetToken($testMarker, [$targetType]);
$hasParams = PassedParameters::hasParameters(self::$phpcsFile, $target);

if ($expectException === false) {
if (\method_exists($this, 'assertIsBool') === true) {
// PHPUnit 7.5+.
$this->assertIsBool($hasParams);
} else {
// PHPUnit < 7.5.
$this->assertInternalType('bool', $hasParams);
}
}
}

/**
* Test retrieving the parameter details for valid and invalid constructs when the
* `$isShortArray` parameter is set to TRUE.
*
* @dataProvider dataTestCases
*
* @param string $testMarker The comment which prefaces the target token in the test file.
* @param int|string $targetType The type of token to look for.
* @param bool $ignore Not used in this test.
* @param array $expected The expected return value.
*
* @return void
*/
public function testGetParametersSkipShortArrayCheck($testMarker, $targetType, $ignore, $expected)
{
$stackPtr = $this->getTargetToken($testMarker, [$targetType]);
$result = PassedParameters::getParameters(self::$phpcsFile, $stackPtr, 0, true);

if (\method_exists($this, 'assertIsArray') === true) {
// PHPUnit 7.5+.
$this->assertIsArray($result);
} else {
// PHPUnit < 7.5.
$this->assertInternalType('array', $result);
}

// Start/end token position values in the expected array are set as offsets
// in relation to the target token.
// Change these to exact positions based on the retrieved stackPtr.
foreach ($expected as $key => $value) {
$expected[$key]['start'] = ($stackPtr + $value['start']);
$expected[$key]['end'] = ($stackPtr + $value['end']);
}

foreach ($result as $key => $value) {
// The GetTokensAsString functions have their own tests, no need to duplicate it here.
unset($result[$key]['clean']);
}

$this->assertSame($expected, $result);
}

/**
* Data provider.
*
* @see testGetParametersSkipShortArrayCheck() For the array format.
* @see testHasParametersDontSkipShortArrayCheck() For the array format.
*
* @return array
*/
public function dataTestCases()
{
return [
'no-params' => [
'/* testNoParams */',
\T_OPEN_SHORT_ARRAY,
false,
[],
],
'long-array' => [
'/* testLongArray */',
\T_ARRAY,
false,
[
1 => [
'start' => 2,
'end' => 3,
'raw' => '1',
],
2 => [
'start' => 5,
'end' => 7,
'raw' => '2',
],
],
],
'short-array' => [
'/* testShortArray */',
\T_OPEN_SHORT_ARRAY,
false,
[
1 => [
'start' => 1,
'end' => 6,
'raw' => "'a' => 1",
],
2 => [
'start' => 8,
'end' => 14,
'raw' => "'b' => 2",
],
],
],
'short-list' => [
'/* testShortList */',
\T_OPEN_SHORT_ARRAY,
true,
[
1 => [
'start' => 1,
'end' => 6,
'raw' => "'a' => 1",
],
2 => [
'start' => 8,
'end' => 14,
'raw' => "'b' => 2",
],
],
],
'array-assign' => [
'/* testArrayAssign */',
\T_OPEN_SQUARE_BRACKET,
true,
[],
],
'array-access' => [
'/* testArrayAccess */',
\T_OPEN_SQUARE_BRACKET,
true,
[
1 => [
'start' => 1,
'end' => 4,
'raw' => '$keys[\'key\']',
],
],
],
];
}
}

0 comments on commit 4968182

Please sign in to comment.