From 264e3eaddcc71f4dc1d1342784efe8c15cfc4f9c Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 18 Oct 2022 08:45:37 +0200 Subject: [PATCH] PHP 8.1 | Utils\PassedParameters: change named param implementation/named params after variadic Follow up on 235 and 361. As of PHP 8.1, named parameters after argument unpacking in function calls is allowed. This has implications for how to retrieve a parameter from the parameter stack in the `PassedParameters::getParameterFromStack()` method and exposes a pre-existing short-coming in the method as argument unpacking was not taken into account. While argument unpacking will always throw the retrieval of a specific parameter off if that specific parameter is one of the parameters being unpacked, the method can still be improved to handle this better in the context of named parameters. To make this more straight-forward, I'm changing the implementation for support for named parameters in the `PassedParameters::getParameters()` method. Previously (but so far unreleased), the return array for named parameters would contain three extra keys: `name_start`, `name_end` and `name` and the top-level index for the parameter would be based on the position of the parameter in the function call. As support for PHPCS < 3.7.1 has been dropped, the `name_start` and `name_end` are no longer relevant as the tokenization of the names will be consistent and will always be `T_PARAM_NAME` - `T_COLON`. (This was previously not the case as prior to PHPCS 3.6.0, the tokenization of parameter labels could vary based on the label and the spacing used). The `name_start` and `name_end` keys are now being replaced by a `name_token` key pointing to the `T_PARAM_NAME` token. On top of that, for named parameters, the position in the function call is irrelevant, so having the position as the top-level index is redundant. So... this commit makes the following changes: 1. `PassedParameters::getParameters()`: the `name_start` and `name_end` keys have been removed and instead a `name_token` key will be added. Note: the `name` key in the parameter sub-array _will_ also still be set as both the `PassedParameters::getParameter()` method as well as the `PassedParameters::getParameterFromStack()` method will return only the parameter specific sub-array and what with a sniff potentially passing multiple parameter names, it is still useful to know which one was matched. 2. `PassedParameters::getParameters()`: the _key_ for the parameter will now be either its position or the parameter name. This does mean that the behaviour for function calls passing _duplicate_ named parameters has changed. The first parameter using the name will be in the top-level array by name, the second parameter using the same name, will be in the array using their position as the key (as the duplicate name would otherwise overwrite the first entry). As duplicate parameter names being used in a function call would result in an `Error` exception in PHP anyway, I'm not too concerned about this. 3. `PassedParameters::getParameterFromStack()` will now attempt to find a named parameter first and only look for the positional variant after. Includes: * An additional test for the `PassedParameters::getParameterFromStack()` method to verify that retrieving a named parameter after a variadic parameter is handled correctly. * An additional test for the `PassedParameters::getParameterCount()` method to safeguard that duplicate parameter names will still result in a correct parameter count. * Updating the test expectations in various test classes. * A minor ruleset tweak to exempt the `GetParametersNamedTest` class from the `Universal.Arrays.MixedArrayKeyTypes` sniff as the return value of `PassedParameters::getParameters()` may now contain mixed array keys. * Removing an unused `use` statement (follow up after 369). Note: it will still be the responsibility of individual sniffs to take argument unpacking in function calls into account when examining parameters. Refs: * https://www.php.net/manual/en/migration81.new-features.php#migration81.new-features.core.named-arg-after-unpack --- PHPCSUtils/Utils/PassedParameters.php | 73 +++--- .../GetParameterCountTest.inc | 4 + .../GetParameterCountTest.php | 4 + .../GetParameterFromStackTest.inc | 4 + .../GetParameterFromStackTest.php | 139 ++++++++--- .../GetParametersNamedTest.inc | 2 +- .../GetParametersNamedTest.php | 232 +++++++----------- phpcs.xml.dist | 5 + 8 files changed, 254 insertions(+), 209 deletions(-) diff --git a/PHPCSUtils/Utils/PassedParameters.php b/PHPCSUtils/Utils/PassedParameters.php index e5927b8b..cd616b29 100644 --- a/PHPCSUtils/Utils/PassedParameters.php +++ b/PHPCSUtils/Utils/PassedParameters.php @@ -17,7 +17,6 @@ use PHPCSUtils\Tokens\Collections; use PHPCSUtils\Utils\Arrays; use PHPCSUtils\Utils\GetTokensAsString; -use PHPCSUtils\Utils\NamingConventions; /** * Utility functions to retrieve information about parameters passed to function calls, @@ -157,8 +156,9 @@ public static function hasParameters(File $phpcsFile, $stackPtr, $isShortArray = * See {@see PassedParameters::hasParameters()} for information on the supported constructs. * * @since 1.0.0 - * @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. + * @since 1.0.0-alpha4 Added support for PHP 8.0 function calls with named arguments by introducing + * the `'name'` and `'name_token'` index keys as well as using the name + * as the index for the top-level array for named parameters. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. * @param int $stackPtr The position of function call name, @@ -170,32 +170,28 @@ public static function hasParameters(File $phpcsFile, $stackPtr, $isShortArray = * 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. + * @return array A multi-dimentional array with information on each parameter/array item. * The information gathered about each parameter/array item is in the following format: * ```php - * 1 => array( + * [1] => array( * 'start' => int, // The stack pointer to the first token in the parameter/array item. * 'end' => int, // The stack pointer to the last token in the parameter/array item. * 'raw' => string, // A string with the contents of all tokens between `start` and `end`. * 'clean' => string, // Same as `raw`, but all comment tokens have been stripped out. * ) * ``` - * For function calls passing named arguments, the format is as follows: + * If a named parameter is encountered in a function call, the top-level index will not be + * the parameter _position_, but the _parameter name_ and the array will include two extra keys: * ```php - * 1 => array( - * 'name_start' => int, // The stack pointer to the first token in the parameter name. - * 'name_end' => int, // The stack pointer to the last token in the parameter name. - * // This will point to the colon. - * 'name' => string, // The parameter name as a string (without the colon). - * 'start' => int, // The stack pointer to the first token in the parameter value. - * 'end' => int, // The stack pointer to the last token in the parameter value. - * 'raw' => string, // A string with the contents of all tokens between `start` and `end`. - * 'clean' => string, // Same as `raw`, but all comment tokens have been stripped out. + * [parameter_name] => array( + * 'name' => string, // The parameter name (without the colon). + * 'name_token' => int, // The stack pointer to the parameter name token. * ) * ``` * The `'start'`, `'end'`, `'raw'` and `'clean'` indexes will always contain just and only * information on the parameter value. - * _Note: The array starts at index 1._ + * _Note: The array starts at index 1 for positional parameters._ + * _The key for named parameters will be the parameter name._ * If no parameters/array items are found, an empty array will be returned. * * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the token passed is not one of the @@ -288,6 +284,7 @@ public static function getParameters(File $phpcsFile, $stackPtr, $limit = 0, $is // Ok, we've reached the end of the parameter. $paramEnd = ($nextComma - 1); + $key = $cnt; if ($mayHaveNames === true) { $firstNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, $paramStart, ($paramEnd + 1), true); @@ -302,18 +299,22 @@ public static function getParameters(File $phpcsFile, $stackPtr, $limit = 0, $is if ($tokens[$secondNonEmpty]['code'] === \T_COLON && $tokens[$firstNonEmpty]['code'] === \T_PARAM_NAME ) { - $parameters[$cnt]['name_start'] = $paramStart; - $parameters[$cnt]['name_end'] = $secondNonEmpty; - $parameters[$cnt]['name'] = $tokens[$firstNonEmpty]['content']; + if (isset($parameters[$tokens[$firstNonEmpty]['content']]) === false) { + // Set the key to be the name, but only if we've not seen this name before. + $key = $tokens[$firstNonEmpty]['content']; + } + + $parameters[$key]['name'] = $tokens[$firstNonEmpty]['content']; + $parameters[$key]['name_token'] = $firstNonEmpty; $paramStart = ($secondNonEmpty + 1); } } } - $parameters[$cnt]['start'] = $paramStart; - $parameters[$cnt]['end'] = $paramEnd; - $parameters[$cnt]['raw'] = \trim(GetTokensAsString::normal($phpcsFile, $paramStart, $paramEnd)); - $parameters[$cnt]['clean'] = \trim(GetTokensAsString::noComments($phpcsFile, $paramStart, $paramEnd)); + $parameters[$key]['start'] = $paramStart; + $parameters[$key]['end'] = $paramEnd; + $parameters[$key]['raw'] = \trim(GetTokensAsString::normal($phpcsFile, $paramStart, $paramEnd)); + $parameters[$key]['clean'] = \trim(GetTokensAsString::noComments($phpcsFile, $paramStart, $paramEnd)); // Check if there are more tokens before the closing parenthesis. // Prevents function calls with trailing comma's from setting an extra parameter: @@ -476,7 +477,18 @@ public static function getParameterFromStack(array $parameters, $paramOffset, $p return false; } - // First check for positional parameters. + // First check for a named parameter. + if (empty($paramNames) === false) { + $paramNames = (array) $paramNames; + foreach ($paramNames as $name) { + // Note: parameter names are case-sensitive!. + if (isset($parameters[$name]) === true) { + return $parameters[$name]; + } + } + } + + // Next check for positional parameters. if (isset($parameters[$paramOffset]) === true && isset($parameters[$paramOffset]['name']) === false ) { @@ -489,19 +501,6 @@ public static function getParameterFromStack(array $parameters, $paramOffset, $p ); } - $paramNames = \array_flip((array) $paramNames); - - // Next check if a named parameter was passed with the specified name. - foreach ($parameters as $paramDetails) { - if (isset($paramDetails['name']) === false) { - continue; - } - - if (isset($paramNames[$paramDetails['name']]) === true) { - return $paramDetails; - } - } - return false; } } diff --git a/Tests/Utils/PassedParameters/GetParameterCountTest.inc b/Tests/Utils/PassedParameters/GetParameterCountTest.inc index 0b6a345c..490a579e 100644 --- a/Tests/Utils/PassedParameters/GetParameterCountTest.inc +++ b/Tests/Utils/PassedParameters/GetParameterCountTest.inc @@ -162,6 +162,10 @@ Partially\Qualified\myfunction( $a ); /* testFunctionCallNamespaceOperator */ namespace\myfunction( $a ); +/* testFunctionCallNamedParamsDuplicateName */ +// Error Exception, but not the concern of PHPCSUtils. Should still be handled. +test(param: 1, param: 2); + /* testLongArray1 */ $foo = array( 1, 2, 3, 4, 5, 6, true ); diff --git a/Tests/Utils/PassedParameters/GetParameterCountTest.php b/Tests/Utils/PassedParameters/GetParameterCountTest.php index c3358296..49d85db4 100644 --- a/Tests/Utils/PassedParameters/GetParameterCountTest.php +++ b/Tests/Utils/PassedParameters/GetParameterCountTest.php @@ -277,6 +277,10 @@ public function dataGetParameterCount() 'expected' => 1, 'targetContent' => ($php8Names === true) ? null : 'myfunction', ], + 'function-call-named-params-duplicate-name' => [ + 'testMarker' => '/* testFunctionCallNamedParamsDuplicateName */', + 'expected' => 2, + ], // Long arrays. 'long-array-1' => [ diff --git a/Tests/Utils/PassedParameters/GetParameterFromStackTest.inc b/Tests/Utils/PassedParameters/GetParameterFromStackTest.inc index b18b415a..a7587ab3 100644 --- a/Tests/Utils/PassedParameters/GetParameterFromStackTest.inc +++ b/Tests/Utils/PassedParameters/GetParameterFromStackTest.inc @@ -57,3 +57,7 @@ setcookie( 'name', expires: time() + (60 * 60 * 24), ); + +/* testPHP81NamedParamAfterVariadic */ +// Prior to PHP 8.1, this was a compile error, but this is now supported. +test($positional, ...$variadic, namedA: $valueA, namedB: $valueB); diff --git a/Tests/Utils/PassedParameters/GetParameterFromStackTest.php b/Tests/Utils/PassedParameters/GetParameterFromStackTest.php index f83ac527..b600f753 100644 --- a/Tests/Utils/PassedParameters/GetParameterFromStackTest.php +++ b/Tests/Utils/PassedParameters/GetParameterFromStackTest.php @@ -159,9 +159,8 @@ public function testGetParameterFunctionCallWithParamName($testMarker, $expected $expected['start'] += $stackPtr; $expected['end'] += $stackPtr; - if (isset($expected['name_start'], $expected['name_end']) === true) { - $expected['name_start'] += $stackPtr; - $expected['name_end'] += $stackPtr; + if (isset($expected['name_token'])) { + $expected['name_token'] += $stackPtr; } $expected['clean'] = $expected['raw']; @@ -182,9 +181,8 @@ public function dataGetParameterFunctionCallWithParamName() 'all-named-non-standard-order' => [ 'testMarker' => '/* testAllParamsNamedNonStandardOrder */', 'expected' => [ - 'name_start' => 46, - 'name_end' => 49, 'name' => 'value', + 'name_token' => 48, 'start' => 50, 'end' => 51, 'raw' => "'value'", @@ -229,9 +227,8 @@ public function testGetParameterFromStack($testMarker, $expectedName, $expectedE $expected = $expectedName; $expected['start'] += $stackPtr; $expected['end'] += $stackPtr; - if (isset($expected['name_start'], $expected['name_end']) === true) { - $expected['name_start'] += $stackPtr; - $expected['name_end'] += $stackPtr; + if (isset($expected['name_token'])) { + $expected['name_token'] += $stackPtr; } $expected['clean'] = $expected['raw']; } @@ -250,9 +247,8 @@ public function testGetParameterFromStack($testMarker, $expectedName, $expectedE $expected = $expectedExpires; $expected['start'] += $stackPtr; $expected['end'] += $stackPtr; - if (isset($expected['name_start'], $expected['name_end']) === true) { - $expected['name_start'] += $stackPtr; - $expected['name_end'] += $stackPtr; + if (isset($expected['name_token'])) { + $expected['name_token'] += $stackPtr; } $expected['clean'] = $expected['raw']; } @@ -271,9 +267,8 @@ public function testGetParameterFromStack($testMarker, $expectedName, $expectedE $expected = $expectedHttpOnly; $expected['start'] += $stackPtr; $expected['end'] += $stackPtr; - if (isset($expected['name_start'], $expected['name_end']) === true) { - $expected['name_start'] += $stackPtr; - $expected['name_end'] += $stackPtr; + if (isset($expected['name_token'])) { + $expected['name_token'] += $stackPtr; } $expected['clean'] = $expected['raw']; } @@ -313,25 +308,22 @@ public function dataGetParameterFromStack() 'all-params-all-named-standard-order' => [ 'testMarker' => '/* testAllParamsNamedStandardOrder */', 'expectedName' => [ - 'name_start' => 2, - 'name_end' => 5, 'name' => 'name', + 'name_token' => 4, 'start' => 6, 'end' => 7, 'raw' => "'name'", ], 'expectedExpires' => [ - 'name_start' => 16, - 'name_end' => 19, 'name' => 'expires_or_options', + 'name_token' => 18, 'start' => 20, 'end' => 37, 'raw' => 'time() + (60 * 60 * 24)', ], 'expectedHttpOnly' => [ - 'name_start' => 60, - 'name_end' => 63, 'name' => 'httponly', + 'name_token' => 62, 'start' => 64, 'end' => 66, 'raw' => 'false', @@ -340,25 +332,22 @@ public function dataGetParameterFromStack() 'all-params-all-named-random-order' => [ 'testMarker' => '/* testAllParamsNamedNonStandardOrder */', 'expectedName' => [ - 'name_start' => 32, - 'name_end' => 35, 'name' => 'name', + 'name_token' => 34, 'start' => 36, 'end' => 37, 'raw' => "'name'", ], 'expectedExpires' => [ - 'name_start' => 2, - 'name_end' => 5, 'name' => 'expires_or_options', + 'name_token' => 4, 'start' => 6, 'end' => 23, 'raw' => 'time() + (60 * 60 * 24)', ], 'expectedHttpOnly' => [ - 'name_start' => 53, - 'name_end' => 56, 'name' => 'httponly', + 'name_token' => 55, 'start' => 57, 'end' => 58, 'raw' => 'false', @@ -377,9 +366,8 @@ public function dataGetParameterFromStack() 'raw' => 'time() + (60 * 60 * 24)', ], 'expectedHttpOnly' => [ - 'name_start' => 44, - 'name_end' => 47, 'name' => 'httponly', + 'name_token' => 46, 'start' => 48, 'end' => 49, 'raw' => 'false', @@ -393,9 +381,8 @@ public function dataGetParameterFromStack() 'raw' => "'name'", ], 'expectedExpires' => [ - 'name_start' => 6, - 'name_end' => 9, 'name' => 'expires_or_options', + 'name_token' => 8, 'start' => 10, 'end' => 27, 'raw' => 'time() + (60 * 60 * 24)', @@ -410,9 +397,8 @@ public function dataGetParameterFromStack() 'raw' => "'name'", ], 'expectedExpires' => [ - 'name_start' => 6, - 'name_end' => 9, 'name' => 'expires', + 'name_token' => 8, 'start' => 10, 'end' => 27, 'raw' => 'time() + (60 * 60 * 24)', @@ -421,4 +407,93 @@ public function dataGetParameterFromStack() ], ]; } + + /** + * Test retrieving the parameter details from a function call with a named parameter after a variadic one. + * + * This is supported since PHP 8.1. + * + * @dataProvider dataGetParameterFromStackNamedAfterVariadic + * + * @param string $offset The positional offfset to pass. + * @param array $names The parameter names to pass. + * @param array|false $expected The expected result array for the parameter. + * + * @return void + */ + public function testGetParameterFromStackNamedAfterVariadic($offset, $names, $expected) + { + $stackPtr = $this->getTargetToken('/* testPHP81NamedParamAfterVariadic */', \T_STRING); + + if ($expected !== false) { + // 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. + $expected['start'] += $stackPtr; + $expected['end'] += $stackPtr; + if (isset($expected['name_token'])) { + $expected['name_token'] += $stackPtr; + } + $expected['clean'] = $expected['raw']; + } + + $parameters = PassedParameters::getParameters(self::$phpcsFile, $stackPtr); + $result = PassedParameters::getParameterFromStack($parameters, $offset, $names); + + $this->assertSame($expected, $result); + } + + /** + * Data provider. + * + * @see testGetParameterFromStackNamedAfterVariadic() For the array format. + * + * @return array + */ + public function dataGetParameterFromStackNamedAfterVariadic() + { + return [ + 'first param, positional' => [ + 'offset' => 1, + 'names' => ['none'], + 'expected' => [ + 'start' => 2, + 'end' => 2, + 'raw' => '$positional', + ], + ], + 'second param, positional, variadic' => [ + 'offset' => 2, + 'names' => ['none'], + 'expected' => [ + 'start' => 4, + 'end' => 6, + 'raw' => '...$variadic', + ], + ], + 'named param "namedA"' => [ + 'offset' => 5, + 'names' => ['alternative', 'namedA'], + 'expected' => [ + 'name' => 'namedA', + 'name_token' => 9, + 'start' => 11, + 'end' => 12, + 'raw' => '$valueA', + ], + ], + 'named param "namedB"' => [ + // Position intentionally set to 2 to collide with the variadic param (which may contain named params). + 'offset' => 2, + 'names' => ['namedB'], + 'expected' => [ + 'name' => 'namedB', + 'name_token' => 15, + 'start' => 17, + 'end' => 18, + 'raw' => '$valueB', + ], + ], + ]; + } } diff --git a/Tests/Utils/PassedParameters/GetParametersNamedTest.inc b/Tests/Utils/PassedParameters/GetParametersNamedTest.inc index cb153c32..61cb163a 100644 --- a/Tests/Utils/PassedParameters/GetParametersNamedTest.inc +++ b/Tests/Utils/PassedParameters/GetParametersNamedTest.inc @@ -70,7 +70,7 @@ array_fill(start_index: 0, ...[100, 50]); test(...$values, param: $value); /* testParseErrorNoValue */ -// Not the concern of PHPCSUtils. Should still be handled. +// Not the concern of PHPCSUtils. Should still be handled (but currently isn't). //test(param1:, param2:); /* testParseErrorDynamicName */ diff --git a/Tests/Utils/PassedParameters/GetParametersNamedTest.php b/Tests/Utils/PassedParameters/GetParametersNamedTest.php index 34c752da..75c446dc 100644 --- a/Tests/Utils/PassedParameters/GetParametersNamedTest.php +++ b/Tests/Utils/PassedParameters/GetParametersNamedTest.php @@ -50,12 +50,11 @@ public function testGetParameters($testMarker, $targetType, $expected, $targetCo // 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']); + $expected[$key]['start'] += $stackPtr; + $expected[$key]['end'] += $stackPtr; - if (isset($value['name_start'], $value['name_end']) === true) { - $expected[$key]['name_start'] = ($stackPtr + $value['name_start']); - $expected[$key]['name_end'] = ($stackPtr + $value['name_end']); + if (isset($value['name_token'])) { + $expected[$key]['name_token'] += $stackPtr; } } @@ -108,26 +107,23 @@ public function dataGetParameters() 'testMarker' => '/* testNamedArgs */', 'targetType' => \T_STRING, 'expected' => [ - 1 => [ - 'name_start' => 2, - 'name_end' => 3, + 'start_index' => [ 'name' => 'start_index', + 'name_token' => 2, 'start' => 4, 'end' => 5, 'raw' => '0', ], - 2 => [ - 'name_start' => 7, - 'name_end' => 9, + 'count' => [ 'name' => 'count', + 'name_token' => 8, 'start' => 10, 'end' => 11, 'raw' => '100', ], - 3 => [ - 'name_start' => 13, - 'name_end' => 15, + 'value' => [ 'name' => 'value', + 'name_token' => 14, 'start' => 16, 'end' => 17, 'raw' => '50', @@ -138,26 +134,23 @@ public function dataGetParameters() 'testMarker' => '/* testNamedArgsMultiline */', 'targetType' => \T_STRING, 'expected' => [ - 1 => [ - 'name_start' => 2, - 'name_end' => 6, + 'start_index' => [ 'name' => 'start_index', + 'name_token' => 4, 'start' => 7, 'end' => 8, 'raw' => '0', ], - 2 => [ - 'name_start' => 10, - 'name_end' => 14, + 'count' => [ 'name' => 'count', + 'name_token' => 12, 'start' => 15, 'end' => 16, 'raw' => '100', ], - 3 => [ - 'name_start' => 18, - 'name_end' => 22, + 'value' => [ 'name' => 'value', + 'name_token' => 20, 'start' => 23, 'end' => 24, 'raw' => '50', @@ -168,26 +161,23 @@ public function dataGetParameters() 'testMarker' => '/* testNamedArgsWithWhitespaceAndComments */', 'targetType' => \T_STRING, 'expected' => [ - 1 => [ - 'name_start' => 3, - 'name_end' => 6, + 'start_index' => [ 'name' => 'start_index', + 'name_token' => 4, 'start' => 7, 'end' => 8, 'raw' => '0', ], - 2 => [ - 'name_start' => 10, - 'name_end' => 17, + 'count' => [ 'name' => 'count', + 'name_token' => 13, 'start' => 18, 'end' => 19, 'raw' => '100', ], - 3 => [ - 'name_start' => 21, - 'name_end' => 23, + 'value' => [ 'name' => 'value', + 'name_token' => 22, 'start' => 24, 'end' => 25, 'raw' => '50', @@ -203,10 +193,9 @@ public function dataGetParameters() 'end' => 2, 'raw' => '$string', ], - 2 => [ - 'name_start' => 4, - 'name_end' => 6, + 'double_encode' => [ 'name' => 'double_encode', + 'name_token' => 5, 'start' => 7, 'end' => 8, 'raw' => 'false', @@ -217,26 +206,23 @@ public function dataGetParameters() 'testMarker' => '/* testNestedFunctionCallOuter */', 'targetType' => \T_STRING, 'expected' => [ - 1 => [ - 'name_start' => 2, - 'name_end' => 5, + 'start_index' => [ 'name' => 'start_index', + 'name_token' => 4, 'start' => 6, 'end' => 17, 'raw' => '/* testNestedFunctionCallInner1 */ $obj->getPos(skip: false)', ], - 2 => [ - 'name_start' => 19, - 'name_end' => 22, + 'count' => [ 'name' => 'count', + 'name_token' => 21, 'start' => 23, 'end' => 32, 'raw' => '/* testNestedFunctionCallInner2 */ count(array_or_countable: $array)', ], - 3 => [ - 'name_start' => 34, - 'name_end' => 37, + 'value' => [ 'name' => 'value', + 'name_token' => 36, 'start' => 38, 'end' => 40, 'raw' => '50', @@ -247,10 +233,9 @@ public function dataGetParameters() 'testMarker' => '/* testNestedFunctionCallInner1 */', 'targetType' => \T_STRING, 'expected' => [ - 1 => [ - 'name_start' => 2, - 'name_end' => 3, + 'skip' => [ 'name' => 'skip', + 'name_token' => 2, 'start' => 4, 'end' => 5, 'raw' => 'false', @@ -261,10 +246,9 @@ public function dataGetParameters() 'testMarker' => '/* testNestedFunctionCallInner2 */', 'targetType' => \T_STRING, 'expected' => [ - 1 => [ - 'name_start' => 2, - 'name_end' => 3, + 'array_or_countable' => [ 'name' => 'array_or_countable', + 'name_token' => 2, 'start' => 4, 'end' => 5, 'raw' => '$array', @@ -275,18 +259,16 @@ public function dataGetParameters() 'testMarker' => '/* testNamespacedFQNFunction */', 'targetType' => ($php8Names === true) ? \T_NAME_FULLY_QUALIFIED : \T_STRING, 'expected' => [ - 1 => [ - 'name_start' => 2, - 'name_end' => 3, + 'label' => [ 'name' => 'label', + 'name_token' => 2, 'start' => 4, 'end' => 5, 'raw' => '$string', ], - 2 => [ - 'name_start' => 7, - 'name_end' => 9, + 'more' => [ 'name' => 'more', + 'name_token' => 8, 'start' => 10, 'end' => 10, 'raw' => 'false', @@ -298,18 +280,16 @@ public function dataGetParameters() 'testMarker' => '/* testVariableFunction */', 'targetType' => \T_VARIABLE, 'expected' => [ - 1 => [ - 'name_start' => 2, - 'name_end' => 3, + 'label' => [ 'name' => 'label', + 'name_token' => 2, 'start' => 4, 'end' => 5, 'raw' => '$string', ], - 2 => [ - 'name_start' => 7, - 'name_end' => 9, + 'more' => [ 'name' => 'more', + 'name_token' => 8, 'start' => 10, 'end' => 10, 'raw' => 'false', @@ -320,18 +300,16 @@ public function dataGetParameters() 'testMarker' => '/* testClassInstantiationStatic */', 'targetType' => \T_STATIC, 'expected' => [ - 1 => [ - 'name_start' => 2, - 'name_end' => 3, + 'label' => [ 'name' => 'label', + 'name_token' => 2, 'start' => 4, 'end' => 5, 'raw' => '$string', ], - 2 => [ - 'name_start' => 7, - 'name_end' => 9, + 'more' => [ 'name' => 'more', + 'name_token' => 8, 'start' => 10, 'end' => 10, 'raw' => 'false', @@ -342,18 +320,16 @@ public function dataGetParameters() 'testMarker' => '/* testAnonClass */', 'targetType' => \T_ANON_CLASS, 'expected' => [ - 1 => [ - 'name_start' => 2, - 'name_end' => 3, + 'label' => [ 'name' => 'label', + 'name_token' => 2, 'start' => 4, 'end' => 5, 'raw' => '$string', ], - 2 => [ - 'name_start' => 7, - 'name_end' => 9, + 'more' => [ 'name' => 'more', + 'name_token' => 8, 'start' => 10, 'end' => 11, 'raw' => 'false', @@ -364,26 +340,23 @@ public function dataGetParameters() 'testMarker' => '/* testNonAsciiNames */', 'targetType' => \T_STRING, 'expected' => [ - 1 => [ - 'name_start' => 2, - 'name_end' => 3, + '💩💩💩' => [ 'name' => '💩💩💩', + 'name_token' => 2, 'start' => 4, 'end' => 6, 'raw' => '[]', ], - 2 => [ - 'name_start' => 8, - 'name_end' => 10, + 'Пасха' => [ 'name' => 'Пасха', + 'name_token' => 9, 'start' => 11, 'end' => 12, 'raw' => "'text'", ], - 3 => [ - 'name_start' => 14, - 'name_end' => 16, + '_valid' => [ 'name' => '_valid', + 'name_token' => 15, 'start' => 17, 'end' => 18, 'raw' => '123', @@ -399,10 +372,9 @@ public function dataGetParameters() 'end' => 11, 'raw' => '$cond ? true : false', ], - 2 => [ - 'name_start' => 13, - 'name_end' => 15, + 'name' => [ 'name' => 'name', + 'name_token' => 14, 'start' => 16, 'end' => 18, 'raw' => '$value2', @@ -413,18 +385,16 @@ public function dataGetParameters() 'testMarker' => '/* testNamedArgWithTernary */', 'targetType' => \T_STRING, 'expected' => [ - 1 => [ - 'name_start' => 2, - 'name_end' => 4, + 'label' => [ 'name' => 'label', + 'name_token' => 3, 'start' => 5, 'end' => 14, 'raw' => '$cond ? true : false', ], - 2 => [ - 'name_start' => 16, - 'name_end' => 18, + 'more' => [ 'name' => 'more', + 'name_token' => 17, 'start' => 19, 'end' => 29, 'raw' => '$cond ? CONSTANT_A : CONSTANT_B', @@ -435,10 +405,9 @@ public function dataGetParameters() 'testMarker' => '/* testTernaryWithFunctionCallsInThenElse */', 'targetType' => \T_STRING, 'expected' => [ - 1 => [ - 'name_start' => 2, - 'name_end' => 4, + 'label' => [ 'name' => 'label', + 'name_token' => 3, 'start' => 5, 'end' => 7, 'raw' => '$something', @@ -449,10 +418,9 @@ public function dataGetParameters() 'testMarker' => '/* testTernaryWithFunctionCallsInElse */', 'targetType' => \T_STRING, 'expected' => [ - 1 => [ - 'name_start' => 2, - 'name_end' => 4, + 'more' => [ 'name' => 'more', + 'name_token' => 3, 'start' => 5, 'end' => 7, 'raw' => '$something_else', @@ -463,10 +431,9 @@ public function dataGetParameters() 'testMarker' => '/* testCompileErrorNamedBeforePositional */', 'targetType' => \T_STRING, 'expected' => [ - 1 => [ - 'name_start' => 2, - 'name_end' => 3, + 'param' => [ 'name' => 'param', + 'name_token' => 2, 'start' => 4, 'end' => 5, 'raw' => '$bar', @@ -482,18 +449,16 @@ public function dataGetParameters() 'testMarker' => '/* testDuplicateName */', 'targetType' => \T_STRING, 'expected' => [ - 1 => [ - 'name_start' => 2, - 'name_end' => 3, + 'param' => [ 'name' => 'param', + 'name_token' => 2, 'start' => 4, 'end' => 5, 'raw' => '1', ], 2 => [ - 'name_start' => 7, - 'name_end' => 9, 'name' => 'param', + 'name_token' => 8, 'start' => 10, 'end' => 11, 'raw' => '2', @@ -504,10 +469,9 @@ public function dataGetParameters() 'testMarker' => '/* testIncorrectOrderWithVariadic */', 'targetType' => \T_STRING, 'expected' => [ - 1 => [ - 'name_start' => 2, - 'name_end' => 3, + 'start_index' => [ 'name' => 'start_index', + 'name_token' => 2, 'start' => 4, 'end' => 5, 'raw' => '0', @@ -529,10 +493,9 @@ public function dataGetParameters() 'end' => 3, 'raw' => '...$values', ], - 2 => [ - 'name_start' => 5, - 'name_end' => 7, + 'param' => [ 'name' => 'param', + 'name_token' => 6, 'start' => 8, 'end' => 9, 'raw' => '$value', @@ -554,74 +517,65 @@ public function dataGetParameters() 'testMarker' => '/* testReservedKeywordAsName */', 'targetType' => \T_STRING, 'expected' => [ - 1 => [ - 'name_start' => 2, - 'name_end' => 5, + 'abstract' => [ 'name' => 'abstract', + 'name_token' => 4, 'start' => 6, 'end' => 7, 'raw' => '$value', ], - 2 => [ - 'name_start' => 9, - 'name_end' => 12, + 'class' => [ 'name' => 'class', + 'name_token' => 11, 'start' => 13, 'end' => 14, 'raw' => '$value', ], - 3 => [ - 'name_start' => 16, - 'name_end' => 19, + 'const' => [ 'name' => 'const', + 'name_token' => 18, 'start' => 20, 'end' => 21, 'raw' => '$value', ], - 4 => [ - 'name_start' => 23, - 'name_end' => 26, + 'function' => [ 'name' => 'function', + 'name_token' => 25, 'start' => 27, 'end' => 28, 'raw' => '$value', ], - 5 => [ - 'name_start' => 30, - 'name_end' => 33, + 'iterable' => [ 'name' => 'iterable', + 'name_token' => 32, 'start' => 34, 'end' => 35, 'raw' => '$value', ], - 6 => [ - 'name_start' => 37, - 'name_end' => 40, + 'match' => [ 'name' => 'match', + 'name_token' => 39, 'start' => 41, 'end' => 42, 'raw' => '$value', ], - 7 => [ - 'name_start' => 44, - 'name_end' => 47, + 'protected' => [ 'name' => 'protected', + 'name_token' => 46, 'start' => 48, 'end' => 49, 'raw' => '$value', ], - 8 => [ - 'name_start' => 51, - 'name_end' => 54, + 'object' => [ 'name' => 'object', + 'name_token' => 53, 'start' => 55, 'end' => 56, 'raw' => '$value', ], - 9 => [ - 'name_start' => 58, - 'name_end' => 61, + 'parent' => [ 'name' => 'parent', + 'name_token' => 60, 'start' => 62, 'end' => 63, 'raw' => '$value', diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 68d4b315..484f2930 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -96,4 +96,9 @@ /Tests/BackCompat/BCFile/*Test\.php$ + + + /Tests/Utils/PassedParameters/GetParametersNamedTest\.php$ + +