diff --git a/.github/workflows/basics.yml b/.github/workflows/basics.yml index 602d0f43..55457d68 100644 --- a/.github/workflows/basics.yml +++ b/.github/workflows/basics.yml @@ -46,9 +46,6 @@ jobs: composer remove --no-update --dev phpunit/phpunit --no-scripts # Using PHPCS `master` as an early detection system for bugs upstream. composer require --no-update squizlabs/php_codesniffer:"dev-master" - # Add PHPCSDevCS - this is the CS ruleset we use. - # This is not in the composer.json as it has different minimum PHPCS reqs and would conflict. - composer require --no-update --dev phpcsstandards/phpcsdevcs:"^1.1.3" # Install dependencies and handle caching in one go. # @link https://github.com/marketplace/actions/install-composer-dependencies diff --git a/.github/workflows/quicktest.yml b/.github/workflows/quicktest.yml index 4b118da4..62d82ab5 100644 --- a/.github/workflows/quicktest.yml +++ b/.github/workflows/quicktest.yml @@ -27,16 +27,14 @@ jobs: quicktest: runs-on: ubuntu-latest + env: + # - COMPOSER_ROOT_VERSION is needed to get round the recursive dependency when using CI. + COMPOSER_ROOT_VERSION: '1.99.99' + strategy: matrix: php: ['5.4', 'latest'] - phpcs_version: ['dev-master'] - - include: - - php: '7.3' - phpcs_version: '2.9.2' - - php: '5.4' - phpcs_version: '2.6.0' + phpcs_version: ['3.7.1', 'dev-master'] name: "QTest${{ matrix.phpcs_version == 'dev-master' && ' + Lint' || '' }}: PHP ${{ matrix.php }} - PHPCS ${{ matrix.phpcs_version }}" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 47f69136..ba510db8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,6 +19,10 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +env: + # - COMPOSER_ROOT_VERSION is needed to get round the recursive dependency when using CI. + COMPOSER_ROOT_VERSION: '1.99.99' + jobs: lint: if: ${{ github.ref != 'refs/heads/develop' }} @@ -76,53 +80,24 @@ jobs: # https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix # # IMPORTANT: test runs shouldn't fail because of PHPCS being incompatible with a PHP version. - # - PHPCS will run without errors on PHP 5.4 - 7.2 on any version. - # - PHP 7.3 needs PHPCS 2.9.2 and 3.3.1+ to run without notices. - # As deprecations are ignored for older PHPCS versions, our tests still shouldn't fail. - # - PHP 7.4 needs PHPCS 3.5.0+ to run without notices. - # As deprecations are ignored for older PHPCS versions, our tests still shouldn't fail. - # - PHP 8.0 needs PHPCS 3.5.0+ to run without (fatal) errors. - # To run reliably though, PHPCS 3.5.6 is needed, which undoes the PHP 8.0 comment tokenization changes is needed. - # - PHP 8.1 needs PHPCS 3.5.0+ to run without (fatal) errors. - # To run reliably though, PHPCS 3.5.6 is needed, which undoes the PHP 8.0 comment tokenization changes is needed. - # Additionally, until the new PHP 8.1 "&" tokenization is accounted for in various functions, - # tests will fail in combination with PHPCS < 3.6.1 (in which the new tokenization was undone). # # The matrix is set up so as not to duplicate the builds which are run for code coverage. - php: ['5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4'] - phpcs_version: ['2.6.0', '2.7.1', '2.8.1', '2.9.2', '3.1.0', '3.2.0', '3.3.1', '3.4.2', '3.5.0', '3.5.6', '3.6.0', 'dev-master'] + php: ['5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0'] + phpcs_version: ['3.7.1', 'dev-master'] risky: [false] experimental: [false] - exclude: - # Remove the builds which will already be run via quicktest/code coverage. - - php: '5.4' - phpcs_version: '2.6.0' - - php: '5.4' - phpcs_version: 'dev-master' - - php: '7.3' - phpcs_version: '2.9.2' - include: - # Add builds against PHP 8.0/8.1, but only against PHPCS versions which won't fatal out. - - php: '8.0' - phpcs_version: '3.5.6' - risky: false - experimental: false - - php: '8.0' - phpcs_version: '3.6.0' + - php: '5.6' + phpcs_version: '3.7.1' risky: false experimental: false + extensions: ':iconv' # Run with iconv disabled. - php: '8.0' phpcs_version: 'dev-master' risky: false experimental: false - extensions: ':iconv' # Run one build with iconv disabled. - - - php: '8.1' - phpcs_version: '3.6.1' # dev-master is run in the code coverage job. - risky: false - experimental: false + extensions: ':iconv' # Run with iconv disabled. # Experimental builds. These are allowed to fail. - php: '8.2' @@ -176,6 +151,10 @@ jobs: - name: 'Composer: set PHPCS version for tests' run: composer require --no-update squizlabs/php_codesniffer:"${{ matrix.phpcs_version }}" + # Remove PHPCSDevCS as it would (for now) prevent the tests from being able to run against PHPCS 4.x. + - name: 'Composer: remove PHPCSDevCS' + run: composer remove --dev --no-update phpcsstandards/phpcsdevcs + # Install dependencies and handle caching in one go. # @link https://github.com/marketplace/actions/install-composer-dependencies - name: Install Composer dependencies - normal @@ -228,13 +207,13 @@ jobs: include: - php: '8.1' phpcs_version: 'dev-master' - - php: '7.3' - phpcs_version: '2.9.2' + - php: '8.1' + phpcs_version: '3.7.1' extensions: ':iconv' # Run one build with iconv disabled. - php: '5.4' phpcs_version: 'dev-master' - php: '5.4' - phpcs_version: '2.6.0' + phpcs_version: '3.7.1' name: "Coverage: PHP ${{ matrix.php }} - PHPCS ${{ matrix.phpcs_version }}" @@ -304,6 +283,7 @@ jobs: PHPCSUTILS_USE_CACHE: false # Uploading the results with PHP Coveralls v1 won't work from GH Actions, so switch the PHP version. + # Also PHP Coveralls itself (still) isn't fully compatible with PHP 8.0+. - name: Switch to PHP 7.4 if: ${{ success() && matrix.php != '7.4' }} uses: shivammathur/setup-php@v2 diff --git a/PHPCSUtils/AbstractSniffs/AbstractArrayDeclarationSniff.php b/PHPCSUtils/AbstractSniffs/AbstractArrayDeclarationSniff.php index b441536c..91025e0c 100644 --- a/PHPCSUtils/AbstractSniffs/AbstractArrayDeclarationSniff.php +++ b/PHPCSUtils/AbstractSniffs/AbstractArrayDeclarationSniff.php @@ -14,7 +14,6 @@ use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Sniffs\Sniff; use PHP_CodeSniffer\Util\Tokens; -use PHPCSUtils\BackCompat\BCTokens; use PHPCSUtils\Utils\Arrays; use PHPCSUtils\Utils\Numbers; use PHPCSUtils\Utils\PassedParameters; @@ -24,6 +23,7 @@ * Abstract sniff to easily examine all parts of an array declaration. * * @since 1.0.0 + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. */ abstract class AbstractArrayDeclarationSniff implements Sniff { @@ -135,14 +135,14 @@ abstract class AbstractArrayDeclarationSniff implements Sniff final public function __construct() { // Enhance the list of accepted tokens. - $this->acceptedTokens += BCTokens::assignmentTokens(); - $this->acceptedTokens += BCTokens::comparisonTokens(); - $this->acceptedTokens += BCTokens::arithmeticTokens(); - $this->acceptedTokens += BCTokens::operators(); - $this->acceptedTokens += BCTokens::booleanOperators(); - $this->acceptedTokens += BCTokens::castTokens(); - $this->acceptedTokens += BCTokens::bracketTokens(); - $this->acceptedTokens += BCTokens::heredocTokens(); + $this->acceptedTokens += Tokens::$assignmentTokens; + $this->acceptedTokens += Tokens::$comparisonTokens; + $this->acceptedTokens += Tokens::$arithmeticTokens; + $this->acceptedTokens += Tokens::$operators; + $this->acceptedTokens += Tokens::$booleanOperators; + $this->acceptedTokens += Tokens::$castTokens; + $this->acceptedTokens += Tokens::$bracketTokens; + $this->acceptedTokens += Tokens::$heredocTokens; } /** @@ -483,16 +483,9 @@ public function getActualArrayKey(File $phpcsFile, $startPtr, $endPtr) // Take PHP 7.4 numeric literal separators into account. if ($this->tokens[$i]['code'] === \T_LNUMBER || $this->tokens[$i]['code'] === \T_DNUMBER) { - try { - $number = Numbers::getCompleteNumber($phpcsFile, $i); - $content .= $number['content']; - $i = $number['last_token']; - } catch (RuntimeException $e) { - // This must be PHP 3.5.3 with the broken backfill. Let's presume it's a ordinary number. - // If it's not, the sniff will bow out on the following T_STRING anyway if the - // backfill was broken. - $content .= \str_replace('_', '', $this->tokens[$i]['content']); - } + $number = Numbers::getCompleteNumber($phpcsFile, $i); + $content .= $number['content']; + $i = $number['last_token']; continue; } diff --git a/PHPCSUtils/BackCompat/BCFile.php b/PHPCSUtils/BackCompat/BCFile.php index aae0b69b..1ed1298f 100644 --- a/PHPCSUtils/BackCompat/BCFile.php +++ b/PHPCSUtils/BackCompat/BCFile.php @@ -37,11 +37,7 @@ use PHP_CodeSniffer\Exceptions\RuntimeException; use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; -use PHPCSUtils\BackCompat\BCTokens; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; -use PHPCSUtils\Utils\FunctionDeclarations; -use PHPCSUtils\Utils\Parentheses; /** * PHPCS native utility functions. @@ -52,20 +48,7 @@ * * Additionally, this class works round the following tokenizer issues for * any affected utility functions: - * - Array return type declarations were incorrectly tokenized to `T_ARRAY_HINT` - * instead of `T_RETURN_TYPE` in some circumstances prior to PHPCS 2.8.0. - * - `T_NULLABLE` was not available prior to PHPCS 2.8.0 and utility functions did - * not take nullability of types into account. - * - The PHPCS native ignore annotations were not available prior to PHPCS 3.2.0. - * - The way return types were tokenized has changed in PHPCS 3.3.0. - * Previously a lot of them were tokenized as `T_RETURN_HINT`. For namespaced - * classnames this only tokenized the classname, not the whole return type. - * Now tokenization is "normalized" with most tokens being `T_STRING`, including - * array return type declarations. - * - Typed properties were not recognized prior to PHPCS 3.5.0, including the - * `?` nullability token not being converted to `T_NULLABLE`. - * - Arrow functions were not recognized properly until PHPCS 3.5.3/4. - * - General PHP cross-version incompatibilities. + * - None at this time. * * Most functions in this class will have a related twin-function in the relevant * class in the `PHPCSUtils\Utils` namespace. @@ -80,107 +63,41 @@ * @see \PHP_CodeSniffer\Files\File Original source of these utility methods. * * @since 1.0.0 + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. */ class BCFile { /** - * Returns the declaration names for classes, interfaces, traits, and functions. + * Returns the declaration name for classes, interfaces, traits, enums, and functions. * * PHPCS cross-version compatible version of the `File::getDeclarationName()` method. * * Changelog for the PHPCS native function: * - Introduced in PHPCS 0.0.5. - * - PHPCS 2.8.0: Returns `null` when passed an anonymous class. Previously, the method - * would throw a "_token not of an accepted type_" exception. - * - PHPCS 2.9.0: Returns `null` when passed a PHP closure. Previously, the method - * would throw a "_token not of an accepted type_" exception. - * - PHPCS 3.0.0: Added support for ES6 class/method syntax. - * - PHPCS 3.0.0: The Exception thrown changed from a `PHP_CodeSniffer_Exception` to - * `\PHP_CodeSniffer\Exceptions\RuntimeException`. - * - PHPCS 3.5.3: Allow for functions to be called `fn` for backwards compatibility. - * Related to PHP 7.4 `T_FN` arrow functions. - * - PHPCS 3.5.5: Remove arrow function work-around which is no longer needed due to - * a change in the tokenization of arrow functions. - * - * Note: - * - For ES6 classes in combination with PHPCS 2.x, passing a `T_STRING` token to - * this method will be accepted for JS files. - * - Support for JS ES6 method syntax has not been back-filled for PHPCS < 3.0.0. - * and sniffing JS files is not officially supported by PHPCSUtils. + * - The upstream method has received no significant updates since PHPCS 3.7.1. * * @see \PHP_CodeSniffer\Files\File::getDeclarationName() Original source. * @see \PHPCSUtils\Utils\ObjectDeclarations::getName() PHPCSUtils native improved version. * * @since 1.0.0 - * @since 1.0.0-alpha2 Added BC support for PHP 7.4 arrow functions. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position of the declaration token * which declared the class, interface, - * trait, or function. + * trait, enum or function. * - * @return string|null The name of the class, interface, trait, or function; + * @return string|null The name of the class, interface, trait, enum, or function; * or `NULL` if the function or class is anonymous or * in case of a parse error/live coding. * * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the specified token is not of type - * `T_FUNCTION`, `T_CLASS`, `T_TRAIT`, or `T_INTERFACE`. + * `T_FUNCTION`, `T_CLASS`, `T_ANON_CLASS`, + * `T_CLOSURE`, `T_TRAIT`, `T_ENUM` or `T_INTERFACE`. */ public static function getDeclarationName(File $phpcsFile, $stackPtr) { - $tokens = $phpcsFile->getTokens(); - $tokenCode = $tokens[$stackPtr]['code']; - - if ($tokenCode === T_ANON_CLASS || $tokenCode === T_CLOSURE) { - return null; - } - - /* - * BC: Work-around JS ES6 classes not being tokenized as T_CLASS in PHPCS < 3.0.0. - */ - if (isset($phpcsFile->tokenizerType) - && $phpcsFile->tokenizerType === 'JS' - && $tokenCode === T_STRING - && $tokens[$stackPtr]['content'] === 'class' - ) { - $tokenCode = T_CLASS; - } - - if ($tokenCode !== T_FUNCTION - && $tokenCode !== T_CLASS - && $tokenCode !== T_INTERFACE - && $tokenCode !== T_TRAIT - ) { - throw new RuntimeException('Token type "' . $tokens[$stackPtr]['type'] . '" is not T_FUNCTION, T_CLASS, T_INTERFACE or T_TRAIT'); - } - - if ($tokenCode === T_FUNCTION - && strtolower($tokens[$stackPtr]['content']) !== 'function' - ) { - // This is a function declared without the "function" keyword. - // So this token is the function name. - return $tokens[$stackPtr]['content']; - } - - $content = null; - for ($i = ($stackPtr + 1); $i < $phpcsFile->numTokens; $i++) { - if ($tokens[$i]['code'] === T_STRING - // BC: PHPCS 3.5.3/3.5.4. - || $tokens[$i]['type'] === 'T_FN' - ) { - /* - * BC: In PHPCS 2.6.0, in case of live coding, the last token in a file will be tokenized - * as T_STRING, but won't have the `content` index set. - */ - if (isset($tokens[$i]['content'])) { - $content = $tokens[$i]['content']; - } - break; - } - } - - return $content; + return $phpcsFile->getDeclarationName($stackPtr); } /** @@ -229,48 +146,13 @@ public static function getDeclarationName(File $phpcsFile, $stackPtr) * * Changelog for the PHPCS native function: * - Introduced in PHPCS 0.0.5. - * - PHPCS 2.8.0: Now recognises `self` as a valid type declaration. - * - PHPCS 2.8.0: The return array now contains a new `"token"` index containing the stack pointer - * to the variable. - * - PHPCS 2.8.0: The return array now contains a new `"content"` index containing the raw content - * of the param definition. - * - PHPCS 2.8.0: Added support for nullable types. - * The return array now contains a new `"nullable_type"` index set to `true` or `false` - * for each method parameter. - * - PHPCS 2.8.0: Added support for closures. - * - PHPCS 3.0.0: The Exception thrown changed from a `PHP_CodeSniffer_Exception` to - * `\PHP_CodeSniffer\Exceptions\TokenizerException`. - * - PHPCS 3.3.0: The return array now contains a new `"type_hint_token"` array index. - * Provides the position in the token stack of the first token in the type declaration. - * - PHPCS 3.3.1: Fixed incompatibility with PHP 7.3. - * - PHPCS 3.5.0: The Exception thrown changed from a `\PHP_CodeSniffer\Exceptions\TokenizerException` - * to `\PHP_CodeSniffer\Exceptions\RuntimeException`. - * - PHPCS 3.5.0: Added support for closure USE groups. - * - PHPCS 3.5.0: The return array now contains yet more more information. - * - If a type hint is specified, the position of the last token in the hint will be - * set in a `"type_hint_end_token"` array index. - * - If a default is specified, the position of the first token in the default value - * will be set in a `"default_token"` array index. - * - If a default is specified, the position of the equals sign will be set in a - * `"default_equal_token"` array index. - * - If the param is not the last, the position of the comma will be set in a - * `"comma_token"` array index. - * - If the param is passed by reference, the position of the reference operator - * will be set in a `"reference_token"` array index. - * - If the param is variable length, the position of the variadic operator will - * be set in a `"variadic_token"` array index. - * - PHPCS 3.5.3: Fixed a bug where the `"type_hint_end_token"` array index for a type hinted - * parameter would bleed through to the next (non-type hinted) parameter. - * - PHPCS 3.5.3: Added support for PHP 7.4 `T_FN` arrow functions. - * - PHPCS 3.5.7: Added support for namespace operators in type declarations. PHPCS#3066. - * - PHPCS 3.6.0: Added support for PHP 8.0 union types. PHPCS#3032. - * - PHPCS 3.6.0: Added support for PHP 8.0 constructor property promotion. PHPCS#3152. + * - The upstream method has received no significant updates since PHPCS 3.7.1. * * @see \PHP_CodeSniffer\Files\File::getMethodParameters() Original source. * @see \PHPCSUtils\Utils\FunctionDeclarations::getParameters() PHPCSUtils native improved version. * * @since 1.0.0 - * @since 1.0.0-alpha2 Added BC support for PHP 7.4 arrow functions. + * @since 1.0.0-alpha2 Added support for PHP 7.4 arrow functions. * @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokens. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. @@ -285,13 +167,10 @@ public static function getDeclarationName(File $phpcsFile, $stackPtr) */ public static function getMethodParameters(File $phpcsFile, $stackPtr) { - $tokens = $phpcsFile->getTokens(); - $arrowOpenClose = FunctionDeclarations::getArrowFunctionOpenClose($phpcsFile, $stackPtr); + $tokens = $phpcsFile->getTokens(); - if ($tokens[$stackPtr]['code'] !== T_FUNCTION - && $tokens[$stackPtr]['code'] !== T_CLOSURE + if (isset(Collections::functionDeclarationTokens()[$tokens[$stackPtr]['code']]) === false && $tokens[$stackPtr]['code'] !== T_USE - && $arrowOpenClose === false ) { throw new RuntimeException('$stackPtr must be of type T_FUNCTION or T_CLOSURE or T_USE or T_FN'); } @@ -305,9 +184,6 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr) ) { throw new RuntimeException('$stackPtr was not a valid T_USE'); } - } elseif ($arrowOpenClose !== false) { - // Arrow function in combination with PHP < 7.4 or PHPCS < 3.5.3/4/5. - $opener = $arrowOpenClose['parenthesis_opener']; } else { if (isset($tokens[$stackPtr]['parenthesis_opener']) === false) { // Live coding or syntax error, so no params to find. @@ -359,23 +235,21 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr) } } - // Changed from checking 'code' to 'type' to allow for T_NULLABLE not existing in PHPCS < 2.8.0. - switch ($tokens[$i]['type']) { - case 'T_BITWISE_AND': + switch ($tokens[$i]['code']) { + case T_BITWISE_AND: if ($defaultStart === null) { $passByReference = true; $referenceToken = $i; } break; - case 'T_VARIABLE': + case T_VARIABLE: $currVar = $i; break; - case 'T_ELLIPSIS': + case T_ELLIPSIS: $variableLength = true; $variadicToken = $i; break; - case 'T_ARRAY_HINT': // PHPCS < 3.3.0. - case 'T_CALLABLE': + case T_CALLABLE: if ($typeHintToken === false) { $typeHintToken = $i; } @@ -383,9 +257,9 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr) $typeHint .= $tokens[$i]['content']; $typeHintEndToken = $i; break; - case 'T_SELF': - case 'T_PARENT': - case 'T_STATIC': + case T_SELF: + case T_PARENT: + case T_STATIC: // Self and parent are valid, static invalid, but was probably intended as type hint. if (isset($defaultStart) === false) { if ($typeHintToken === false) { @@ -396,11 +270,11 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr) $typeHintEndToken = $i; } break; - case 'T_STRING': - case 'T_NAME_QUALIFIED': - case 'T_NAME_FULLY_QUALIFIED': - case 'T_NAME_RELATIVE': - // This is an identifier name, so it may be a type hint, but it could + case T_STRING: + case T_NAME_QUALIFIED: + case T_NAME_FULLY_QUALIFIED: + case T_NAME_RELATIVE: + // This is an identifier name, so it may be a type declaration, but it could // also be a constant used as a default value. $prevComma = false; for ($t = $i; $t >= $opener; $t--) { @@ -433,12 +307,12 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr) $typeHintEndToken = $i; } break; - case 'T_NAMESPACE': - case 'T_NS_SEPARATOR': - case 'T_BITWISE_OR': // Union type separator PHPCS < 3.6.0. - case 'T_TYPE_UNION': // Union type separator PHPCS >= 3.6.0. - case 'T_FALSE': - case 'T_NULL': + case T_NAMESPACE: + case T_NS_SEPARATOR: + case T_TYPE_UNION: + case T_TYPE_INTERSECTION: + case T_FALSE: + case T_NULL: // Part of a type hint or default value. if ($defaultStart === null) { if ($typeHintToken === false) { @@ -449,23 +323,22 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr) $typeHintEndToken = $i; } break; - case 'T_NULLABLE': - case 'T_INLINE_THEN': // PHPCS < 2.8.0. + case T_NULLABLE: if ($defaultStart === null) { $nullableType = true; $typeHint .= $tokens[$i]['content']; $typeHintEndToken = $i; } break; - case 'T_PUBLIC': - case 'T_PROTECTED': - case 'T_PRIVATE': + case T_PUBLIC: + case T_PROTECTED: + case T_PRIVATE: if ($defaultStart === null) { $visibilityToken = $i; } break; - case 'T_CLOSE_PARENTHESIS': - case 'T_COMMA': + case T_CLOSE_PARENTHESIS: + case T_COMMA: // If it's null, then there must be no parameters for this // method. if ($currVar === null) { @@ -520,7 +393,7 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr) ++$paramCount; break; - case 'T_EQUAL': + case T_EQUAL: $defaultStart = $phpcsFile->findNext(Tokens::$emptyTokens, ($i + 1), null, true); $equalToken = $i; break; @@ -556,34 +429,12 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr) * * Changelog for the PHPCS native function: * - Introduced in PHPCS 0.0.5. - * - PHPCS 3.0.0: Removed the `"is_closure"` array index which was always `false` anyway. - * - PHPCS 3.0.0: The Exception thrown changed from a `PHP_CodeSniffer_Exception` to - * `\PHP_CodeSniffer\Exceptions\TokenizerException`. - * - PHPCS 3.3.0: New `"return_type"`, `"return_type_token"` and `"nullable_return_type"` array indexes. - * - The `"return_type"` index contains the return type of the function or closer, - * or a blank string if not specified. - * - If the return type is nullable, the return type will contain the leading `?`. - * - A `"nullable_return_type"` array index in the return value will also be set to `true`. - * - If the return type contains namespace information, it will be cleaned of - * whitespace and comments. - * - To access the original return value string, use the main tokens array. - * - PHPCS 3.4.0: New `"has_body"` array index. - * `false` if the method has no body (as with abstract and interface methods) - * or `true` otherwise. - * - PHPCS 3.5.0: The Exception thrown changed from a `\PHP_CodeSniffer\Exceptions\TokenizerException` - * to `\PHP_CodeSniffer\Exceptions\RuntimeException`. - * - PHPCS 3.5.3: Added support for PHP 7.4 `T_FN` arrow functions. - * - PHPCS 3.5.6: Added support for PHP 8.0 `static` return types. - * - PHPCS 3.5.7: Added support for namespace operators in type declarations. PHPCS#3066. - * - PHPCS 3.6.0: Added support for PHP 8.0 union types. PHPCS#3032. - * - PHPCS 3.6.0: Added new `"return_type_end_token"` index. PHPCS#3153. + * - The upstream method has received no significant updates since PHPCS 3.7.1. * * @see \PHP_CodeSniffer\Files\File::getMethodProperties() Original source. * @see \PHPCSUtils\Utils\FunctionDeclarations::getProperties() PHPCSUtils native improved version. * * @since 1.0.0 - * @since 1.0.0-alpha2 Added BC support for PHP 7.4 arrow functions. - * @since 1.0.0-alpha3 Added support for PHP 8.0 static return type. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position in the stack of the function token to @@ -596,164 +447,7 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr) */ public static function getMethodProperties(File $phpcsFile, $stackPtr) { - $tokens = $phpcsFile->getTokens(); - $arrowOpenClose = FunctionDeclarations::getArrowFunctionOpenClose($phpcsFile, $stackPtr); - - if ($tokens[$stackPtr]['code'] !== T_FUNCTION - && $tokens[$stackPtr]['code'] !== T_CLOSURE - && $arrowOpenClose === false - ) { - throw new RuntimeException('$stackPtr must be of type T_FUNCTION or T_CLOSURE or T_FN'); - } - - if ($tokens[$stackPtr]['code'] === T_FUNCTION) { - $valid = [ - T_PUBLIC => T_PUBLIC, - T_PRIVATE => T_PRIVATE, - T_PROTECTED => T_PROTECTED, - T_STATIC => T_STATIC, - T_FINAL => T_FINAL, - T_ABSTRACT => T_ABSTRACT, - T_WHITESPACE => T_WHITESPACE, - T_COMMENT => T_COMMENT, - T_DOC_COMMENT => T_DOC_COMMENT, - ]; - } else { - $valid = [ - T_STATIC => T_STATIC, - T_WHITESPACE => T_WHITESPACE, - T_COMMENT => T_COMMENT, - T_DOC_COMMENT => T_DOC_COMMENT, - ]; - } - - $scope = 'public'; - $scopeSpecified = false; - $isAbstract = false; - $isFinal = false; - $isStatic = false; - - for ($i = ($stackPtr - 1); $i > 0; $i--) { - if (isset($valid[$tokens[$i]['code']]) === false) { - break; - } - - switch ($tokens[$i]['code']) { - case T_PUBLIC: - $scope = 'public'; - $scopeSpecified = true; - break; - case T_PRIVATE: - $scope = 'private'; - $scopeSpecified = true; - break; - case T_PROTECTED: - $scope = 'protected'; - $scopeSpecified = true; - break; - case T_ABSTRACT: - $isAbstract = true; - break; - case T_FINAL: - $isFinal = true; - break; - case T_STATIC: - $isStatic = true; - break; - } - } - - $returnType = ''; - $returnTypeToken = false; - $nullableReturnType = false; - $returnTypeEndToken = false; - $hasBody = true; - $returnTypeTokens = Collections::returnTypeTokensBC(); - - $parenthesisCloser = null; - if (isset($tokens[$stackPtr]['parenthesis_closer']) === true) { - $parenthesisCloser = $tokens[$stackPtr]['parenthesis_closer']; - } elseif ($arrowOpenClose !== false) { - // Arrow function in combination with PHP < 7.4 or PHPCS < 3.5.3. - $parenthesisCloser = $arrowOpenClose['parenthesis_closer']; - } - - if (isset($parenthesisCloser) === true) { - $scopeOpener = null; - if (isset($tokens[$stackPtr]['scope_opener']) === true) { - $scopeOpener = $tokens[$stackPtr]['scope_opener']; - } elseif ($arrowOpenClose !== false) { - // Arrow function in combination with PHP < 7.4 or PHPCS < 3.5.3. - $scopeOpener = $arrowOpenClose['scope_opener']; - } - - for ($i = $parenthesisCloser; $i < $phpcsFile->numTokens; $i++) { - if (($scopeOpener === null && $tokens[$i]['code'] === T_SEMICOLON) - || ($scopeOpener !== null && $i === $scopeOpener) - ) { - // End of function definition. - break; - } - - /* - * Work-around for a scope map tokenizer bug in PHPCS. - * {@link https://github.com/squizlabs/PHP_CodeSniffer/pull/3066} - */ - if ($scopeOpener === null && $tokens[$i]['code'] === \T_OPEN_CURLY_BRACKET) { - // End of function definition for which the scope opener is incorrectly not set. - $hasBody = true; - break; - } - - if ($tokens[$i]['type'] === 'T_NULLABLE' - // Handle nullable tokens in PHPCS < 2.8.0. - || (defined('T_NULLABLE') === false && $tokens[$i]['code'] === T_INLINE_THEN) - // Handle nullable tokens with arrow functions in PHPCS 2.8.0 - 2.9.0. - || ($arrowOpenClose !== false && $tokens[$i]['code'] === T_INLINE_THEN - && version_compare(Helper::getVersion(), '2.9.1', '<') === true) - ) { - $nullableReturnType = true; - } - - if (isset($returnTypeTokens[$tokens[$i]['code']]) === true) { - if ($returnTypeToken === false) { - $returnTypeToken = $i; - } - - $returnType .= $tokens[$i]['content']; - $returnTypeEndToken = $i; - } - } - - $bodyTokens = [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET]; - if ($arrowOpenClose !== false) { - $bodyTokens = [T_DOUBLE_ARROW => T_DOUBLE_ARROW]; - if (defined('T_FN_ARROW') === true) { - // PHPCS 3.5.3+. - $bodyTokens[T_FN_ARROW] = T_FN_ARROW; - } - } - - $end = $phpcsFile->findNext(($bodyTokens + [T_SEMICOLON]), $parenthesisCloser); - $hasBody = ($end !== false && isset($bodyTokens[$tokens[$end]['code']])); - } - - if ($returnType !== '' && $nullableReturnType === true) { - $returnType = '?' . $returnType; - } - - return [ - 'scope' => $scope, - 'scope_specified' => $scopeSpecified, - 'return_type' => $returnType, - 'return_type_token' => $returnTypeToken, - 'return_type_end_token' => $returnTypeEndToken, - 'nullable_return_type' => $nullableReturnType, - 'is_abstract' => $isAbstract, - 'is_final' => $isFinal, - 'is_static' => $isStatic, - 'has_body' => $hasBody, - ]; + return $phpcsFile->getMethodProperties($stackPtr); } /** @@ -765,6 +459,7 @@ public static function getMethodProperties(File $phpcsFile, $stackPtr) * 'scope' => string, // Public, private, or protected. * 'scope_specified' => boolean, // TRUE if the scope was explicitly specified. * 'is_static' => boolean, // TRUE if the static keyword was found. + * 'is_readonly' => boolean, // TRUE if the readonly keyword was found. * 'type' => string, // The type of the var (empty if no type specified). * 'type_token' => integer, // The stack pointer to the start of the type * // or FALSE if there is no type. @@ -779,24 +474,7 @@ public static function getMethodProperties(File $phpcsFile, $stackPtr) * * Changelog for the PHPCS native function: * - Introduced in PHPCS 0.0.5. - * - PHPCS 3.0.0: The Exception thrown changed from a `PHP_CodeSniffer_Exception` to - * `\PHP_CodeSniffer\Exceptions\TokenizerException`. - * - PHPCS 3.4.0: Fixed method params being recognized as properties, PHPCS#2214. - * - PHPCS 3.5.0: New `"type"`, `"type_token"`, `"type_end_token"` and `"nullable_type"` array indexes. - * - The `"type"` index contains the type of the member var, or a blank string - * if not specified. - * - If the type is nullable, `"type"` will contain the leading `?`. - * - If a type is specified, the position of the first token in the type will - * be set in a `"type_token"` array index. - * - If a type is specified, the position of the last token in the type will - * be set in a `"type_end_token"` array index. - * - If the type is nullable, a `"nullable_type"` array index will also be set to `true`. - * - If the type contains namespace information, it will be cleaned of whitespace - * and comments in the `"type"` value. - * - PHPCS 3.5.0: The Exception thrown changed from a `\PHP_CodeSniffer\Exceptions\TokenizerException` - * to `\PHP_CodeSniffer\Exceptions\RuntimeException`. - * - PHPCS 3.5.7: Added support for namespace operators in type declarations. PHPCS#3066. - * - PHPCS 3.6.0: Added support for PHP 8.0 union types. PHPCS#3032. + * - The upstream method has received no significant updates since PHPCS 3.7.1. * * @see \PHP_CodeSniffer\Files\File::getMemberProperties() Original source. * @see \PHPCSUtils\Utils\Variables::getMemberProperties() PHPCSUtils native improved version. @@ -815,135 +493,7 @@ public static function getMethodProperties(File $phpcsFile, $stackPtr) */ public static function getMemberProperties(File $phpcsFile, $stackPtr) { - $tokens = $phpcsFile->getTokens(); - - if ($tokens[$stackPtr]['code'] !== T_VARIABLE) { - throw new RuntimeException('$stackPtr must be of type T_VARIABLE'); - } - - $conditions = array_keys($tokens[$stackPtr]['conditions']); - $ptr = array_pop($conditions); - if (isset($tokens[$ptr]) === false - || ($tokens[$ptr]['code'] !== T_CLASS - && $tokens[$ptr]['code'] !== T_ANON_CLASS - && $tokens[$ptr]['code'] !== T_TRAIT) - ) { - if (isset($tokens[$ptr]) === true - && $tokens[$ptr]['code'] === T_INTERFACE - ) { - // T_VARIABLEs in interfaces can actually be method arguments - // but they wont be seen as being inside the method because there - // are no scope openers and closers for abstract methods. If it is in - // parentheses, we can be pretty sure it is a method argument. - if (isset($tokens[$stackPtr]['nested_parenthesis']) === false - || empty($tokens[$stackPtr]['nested_parenthesis']) === true - ) { - $error = 'Possible parse error: interfaces may not include member vars'; - $phpcsFile->addWarning($error, $stackPtr, 'Internal.ParseError.InterfaceHasMemberVar'); - return []; - } - } else { - throw new RuntimeException('$stackPtr is not a class member var'); - } - } - - // Make sure it's not a method parameter. - if (empty($tokens[$stackPtr]['nested_parenthesis']) === false) { - $parenthesis = array_keys($tokens[$stackPtr]['nested_parenthesis']); - $deepestOpen = array_pop($parenthesis); - if ($deepestOpen > $ptr - && isset($tokens[$deepestOpen]['parenthesis_owner']) === true - && $tokens[$tokens[$deepestOpen]['parenthesis_owner']]['code'] === T_FUNCTION - ) { - throw new RuntimeException('$stackPtr is not a class member var'); - } - } - - $valid = Collections::propertyModifierKeywords(); - $valid += Tokens::$emptyTokens; - - $scope = 'public'; - $scopeSpecified = false; - $isStatic = false; - - $startOfStatement = $phpcsFile->findPrevious( - [ - T_SEMICOLON, - T_OPEN_CURLY_BRACKET, - T_CLOSE_CURLY_BRACKET, - ], - ($stackPtr - 1) - ); - - for ($i = ($startOfStatement + 1); $i < $stackPtr; $i++) { - if (isset($valid[$tokens[$i]['code']]) === false) { - break; - } - - switch ($tokens[$i]['code']) { - case T_PUBLIC: - $scope = 'public'; - $scopeSpecified = true; - break; - case T_PRIVATE: - $scope = 'private'; - $scopeSpecified = true; - break; - case T_PROTECTED: - $scope = 'protected'; - $scopeSpecified = true; - break; - case T_STATIC: - $isStatic = true; - break; - } - } - - $type = ''; - $typeToken = false; - $typeEndToken = false; - $nullableType = false; - $propertyTypeTokens = Collections::propertyTypeTokensBC(); - - if ($i < $stackPtr) { - // We've found a type. - for ($i; $i < $stackPtr; $i++) { - if ($tokens[$i]['code'] === T_VARIABLE) { - // Hit another variable in a group definition. - break; - } - - if ($tokens[$i]['type'] === 'T_NULLABLE' - // Handle nullable property types in PHPCS < 3.5.0. - || $tokens[$i]['code'] === T_INLINE_THEN - ) { - $nullableType = true; - } - - if (isset($propertyTypeTokens[$tokens[$i]['code']]) === true) { - $typeEndToken = $i; - if ($typeToken === false) { - $typeToken = $i; - } - - $type .= $tokens[$i]['content']; - } - } - - if ($type !== '' && $nullableType === true) { - $type = '?' . $type; - } - } - - return [ - 'scope' => $scope, - 'scope_specified' => $scopeSpecified, - 'is_static' => $isStatic, - 'type' => $type, - 'type_token' => $typeToken, - 'type_end_token' => $typeEndToken, - 'nullable_type' => $nullableType, - ]; + return $phpcsFile->getMemberProperties($stackPtr); } /** @@ -961,10 +511,7 @@ public static function getMemberProperties(File $phpcsFile, $stackPtr) * * Changelog for the PHPCS native function: * - Introduced in PHPCS 1.3.0. - * - PHPCS 3.0.0: The Exception thrown changed from a `PHP_CodeSniffer_Exception` to - * `\PHP_CodeSniffer\Exceptions\TokenizerException`. - * - PHPCS 3.5.0: The Exception thrown changed from a `\PHP_CodeSniffer\Exceptions\TokenizerException` - * to`\PHP_CodeSniffer\Exceptions\RuntimeException`. + * - The upstream method has received no significant updates since PHPCS 3.7.1. * * @see \PHP_CodeSniffer\Files\File::getClassProperties() Original source. * @see \PHPCSUtils\Utils\ObjectDeclarations::getClassProperties() PHPCSUtils native improved version. @@ -982,43 +529,7 @@ public static function getMemberProperties(File $phpcsFile, $stackPtr) */ public static function getClassProperties(File $phpcsFile, $stackPtr) { - $tokens = $phpcsFile->getTokens(); - - if ($tokens[$stackPtr]['code'] !== T_CLASS) { - throw new RuntimeException('$stackPtr must be of type T_CLASS'); - } - - $valid = [ - T_FINAL => T_FINAL, - T_ABSTRACT => T_ABSTRACT, - T_WHITESPACE => T_WHITESPACE, - T_COMMENT => T_COMMENT, - T_DOC_COMMENT => T_DOC_COMMENT, - ]; - - $isAbstract = false; - $isFinal = false; - - for ($i = ($stackPtr - 1); $i > 0; $i--) { - if (isset($valid[$tokens[$i]['code']]) === false) { - break; - } - - switch ($tokens[$i]['code']) { - case T_ABSTRACT: - $isAbstract = true; - break; - - case T_FINAL: - $isFinal = true; - break; - } - } - - return [ - 'is_abstract' => $isAbstract, - 'is_final' => $isFinal, - ]; + return $phpcsFile->getClassProperties($stackPtr); } /** @@ -1028,26 +539,12 @@ public static function getClassProperties(File $phpcsFile, $stackPtr) * * Changelog for the PHPCS native function: * - Introduced in PHPCS 0.0.5. - * - PHPCS 3.1.1: Bug fix: misidentification of reference vs bitwise operator, PHPCS#1604/#1609. - * - An array assignment of a calculated value with a bitwise and operator in it, - * was being misidentified as a reference. - * - A calculated default value for a function parameter with a bitwise and operator - * in it, was being misidentified as a reference. - * - New by reference was not recognized as a reference. - * - References to class properties with `self::`, `parent::`, `static::`, - * `namespace\ClassName::`, `classname::` were not recognized as references. - * - PHPCS 3.5.3: Added support for PHP 7.4 `T_FN` arrow functions returning by reference. - * - PHPCS 3.5.6: Bug fix: the reference operator for closures declared to return by reference was - * not recognized as a reference. PHPCS#2977. - * - PHPCS 3.5.7: Bug fix: Parameters passed by reference in arrow functions are recognized correctly. - * PHPCS #3049/#3103 + * - The upstream method has received no significant updates since PHPCS 3.7.1. * * @see \PHP_CodeSniffer\Files\File::isReference() Original source. * @see \PHPCSUtils\Utils\Operators::isReference() PHPCSUtils native improved version. * * @since 1.0.0 - * @since 1.0.0-alpha2 Added BC support for PHP 7.4 arrow functions. - * @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokens. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position of the `T_BITWISE_AND` token. @@ -1057,107 +554,7 @@ public static function getClassProperties(File $phpcsFile, $stackPtr) */ public static function isReference(File $phpcsFile, $stackPtr) { - $tokens = $phpcsFile->getTokens(); - - if ($tokens[$stackPtr]['code'] !== T_BITWISE_AND) { - return false; - } - - $tokenBefore = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true); - - if ($tokens[$tokenBefore]['code'] === T_FUNCTION - || $tokens[$tokenBefore]['code'] === T_CLOSURE - || FunctionDeclarations::isArrowFunction($phpcsFile, $tokenBefore) === true - ) { - // Function returns a reference. - return true; - } - - if ($tokens[$tokenBefore]['code'] === T_DOUBLE_ARROW) { - // Inside a foreach loop or array assignment, this is a reference. - return true; - } - - if ($tokens[$tokenBefore]['code'] === T_AS) { - // Inside a foreach loop, this is a reference. - return true; - } - - if (isset(BCTokens::assignmentTokens()[$tokens[$tokenBefore]['code']]) === true) { - // This is directly after an assignment. It's a reference. Even if - // it is part of an operation, the other tests will handle it. - return true; - } - - $tokenAfter = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true); - - if ($tokens[$tokenAfter]['code'] === T_NEW) { - return true; - } - - if (isset($tokens[$stackPtr]['nested_parenthesis']) === true) { - $lastBracket = Parentheses::getLastOpener($phpcsFile, $stackPtr); - if ($lastBracket !== false) { - $owner = Parentheses::getOwner($phpcsFile, $lastBracket); - if (isset(Collections::functionDeclarationTokensBC()[$tokens[$owner]['code']]) === true) { - $params = self::getMethodParameters($phpcsFile, $owner); - foreach ($params as $param) { - if ($param['reference_token'] === $stackPtr) { - // Function parameter declared to be passed by reference. - return true; - } - } - } - } else { - $prev = false; - for ($t = ($tokens[$lastBracket]['parenthesis_opener'] - 1); $t >= 0; $t--) { - if ($tokens[$t]['code'] !== T_WHITESPACE) { - $prev = $t; - break; - } - } - - if ($prev !== false && $tokens[$prev]['code'] === T_USE) { - // Closure use by reference. - return true; - } - } - } - - // Pass by reference in function calls and assign by reference in arrays. - if ($tokens[$tokenBefore]['code'] === T_OPEN_PARENTHESIS - || $tokens[$tokenBefore]['code'] === T_COMMA - || $tokens[$tokenBefore]['code'] === T_OPEN_SHORT_ARRAY - ) { - if ($tokens[$tokenAfter]['code'] === T_VARIABLE) { - return true; - } else { - $skip = Tokens::$emptyTokens; - - // BC for PHP 8 in combination with PHPCS < 3.5.7. - $skip += Collections::nameTokens(); - - $skip[] = T_NS_SEPARATOR; - $skip[] = T_SELF; - $skip[] = T_PARENT; - $skip[] = T_STATIC; - $skip[] = T_STRING; - $skip[] = T_NAMESPACE; - $skip[] = T_DOUBLE_COLON; - - $nextSignificantAfter = $phpcsFile->findNext( - $skip, - ($stackPtr + 1), - null, - true - ); - if ($tokens[$nextSignificantAfter]['code'] === T_VARIABLE) { - return true; - } - } - } - - return false; + return $phpcsFile->isReference($stackPtr); } /** @@ -1168,12 +565,7 @@ public static function isReference(File $phpcsFile, $stackPtr) * * Changelog for the PHPCS native function: * - Introduced in PHPCS 0.0.5. - * - PHPCS 3.3.0: New `$origContent` parameter to optionally return original - * (non tab-replaced) content. - * - PHPCS 3.4.0: - * - Now throws a `RuntimeException` if the `$start` param is invalid. - * This stops an infinite loop when the function is passed invalid data. - * - If the `$length` param is invalid, an empty string will be returned. + * - The upstream method has received no significant updates since PHPCS 3.7.1. * * @see \PHP_CodeSniffer\Files\File::getTokensAsString() Original source. * @see \PHPCSUtils\Utils\GetTokensAsString Related set of functions. @@ -1192,33 +584,7 @@ public static function isReference(File $phpcsFile, $stackPtr) */ public static function getTokensAsString(File $phpcsFile, $start, $length, $origContent = false) { - $tokens = $phpcsFile->getTokens(); - - if (is_int($start) === false || isset($tokens[$start]) === false) { - throw new RuntimeException('The $start position for getTokensAsString() must exist in the token stack'); - } - - if (is_int($length) === false || $length <= 0) { - return ''; - } - - $str = ''; - $end = ($start + $length); - if ($end > $phpcsFile->numTokens) { - $end = $phpcsFile->numTokens; - } - - for ($i = $start; $i < $end; $i++) { - // If tabs are being converted to spaces by the tokeniser, the - // original content should be used instead of the converted content. - if ($origContent === true && isset($tokens[$i]['orig_content']) === true) { - $str .= $tokens[$i]['orig_content']; - } else { - $str .= $tokens[$i]['content']; - } - } - - return $str; + return $phpcsFile->getTokensAsString($start, $length, $origContent); } /** @@ -1228,14 +594,11 @@ public static function getTokensAsString(File $phpcsFile, $start, $length, $orig * * Changelog for the PHPCS native function: * - Introduced in PHPCS 2.1.0. - * - PHPCS 2.6.2: New optional `$ignore` parameter to selectively ignore stop points. - * - PHPCS 3.5.5: Added support for PHP 7.4 `T_FN` arrow functions. - * - PHPCS 3.5.7: Bug fix: Heredoc/Nowdoc was not always handled correctly. PHPCS#2883 + * - The upstream method has received no significant updates since PHPCS 3.7.1. * * @see \PHP_CodeSniffer\Files\File::findStartOfStatement() Original source. * * @since 1.0.0 - * @since 1.0.0-alpha2 Added BC support for PHP 7.4 arrow functions. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $start The position to start searching from in the token stack. @@ -1245,60 +608,7 @@ public static function getTokensAsString(File $phpcsFile, $start, $length, $orig */ public static function findStartOfStatement(File $phpcsFile, $start, $ignore = null) { - $tokens = $phpcsFile->getTokens(); - - $endTokens = Tokens::$blockOpeners; - - $endTokens[T_COLON] = true; - $endTokens[T_COMMA] = true; - $endTokens[T_DOUBLE_ARROW] = true; - $endTokens[T_SEMICOLON] = true; - $endTokens[T_OPEN_TAG] = true; - $endTokens[T_CLOSE_TAG] = true; - $endTokens[T_OPEN_SHORT_ARRAY] = true; - - if ($ignore !== null) { - $ignore = (array) $ignore; - foreach ($ignore as $code) { - unset($endTokens[$code]); - } - } - - $lastNotEmpty = $start; - - for ($i = $start; $i >= 0; $i--) { - if (isset($endTokens[$tokens[$i]['code']]) === true) { - // Found the end of the previous statement. - return $lastNotEmpty; - } - - if (isset($tokens[$i]['scope_opener']) === true - && $i === $tokens[$i]['scope_closer'] - && $tokens[$i]['code'] !== T_CLOSE_PARENTHESIS - && $tokens[$i]['code'] !== T_END_NOWDOC - && $tokens[$i]['code'] !== T_END_HEREDOC - ) { - // Found the end of the previous scope block. - return $lastNotEmpty; - } - - // Skip nested statements. - if (isset($tokens[$i]['bracket_opener']) === true - && $i === $tokens[$i]['bracket_closer'] - ) { - $i = $tokens[$i]['bracket_opener']; - } elseif (isset($tokens[$i]['parenthesis_opener']) === true - && $i === $tokens[$i]['parenthesis_closer'] - ) { - $i = $tokens[$i]['parenthesis_opener']; - } - - if (isset(Tokens::$emptyTokens[$tokens[$i]['code']]) === false) { - $lastNotEmpty = $i; - } - } - - return 0; + return $phpcsFile->findStartOfStatement($start, $ignore); } /** @@ -1308,18 +618,11 @@ public static function findStartOfStatement(File $phpcsFile, $start, $ignore = n * * Changelog for the PHPCS native function: * - Introduced in PHPCS 2.1.0. - * - PHPCS 2.6.2: New optional `$ignore` parameter to selectively ignore stop points. - * - PHPCS 2.7.1: Improved handling of short arrays, PHPCS #1203. - * - PHPCS 3.3.0: Bug fix: end of statement detection when passed a scope opener, PHPCS #1863. - * - PHPCS 3.5.0: Improved handling of group use statements. - * - PHPCS 3.5.3: Added support for PHP 7.4 `T_FN` arrow functions. - * - PHPCS 3.5.4: Improved support for PHP 7.4 `T_FN` arrow functions. - * - PHPCS 3.5.5: Improved support for PHP 7.4 `T_FN` arrow functions, PHPCS #2895. + * - The upstream method has received no significant updates since PHPCS 3.7.1. * * @see \PHP_CodeSniffer\Files\File::findEndOfStatement() Original source. * * @since 1.0.0 - * @since 1.0.0-alpha2 Added BC support for PHP 7.4 arrow functions. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $start The position to start searching from in the token stack. @@ -1329,98 +632,7 @@ public static function findStartOfStatement(File $phpcsFile, $start, $ignore = n */ public static function findEndOfStatement(File $phpcsFile, $start, $ignore = null) { - $tokens = $phpcsFile->getTokens(); - - $endTokens = [ - T_COLON => true, - T_COMMA => true, - T_DOUBLE_ARROW => true, - T_SEMICOLON => true, - T_CLOSE_PARENTHESIS => true, - T_CLOSE_SQUARE_BRACKET => true, - T_CLOSE_CURLY_BRACKET => true, - T_CLOSE_SHORT_ARRAY => true, - T_OPEN_TAG => true, - T_CLOSE_TAG => true, - ]; - - if ($ignore !== null) { - $ignore = (array) $ignore; - foreach ($ignore as $code) { - unset($endTokens[$code]); - } - } - - $lastNotEmpty = $start; - for ($i = $start; $i < $phpcsFile->numTokens; $i++) { - if ($i !== $start && isset($endTokens[$tokens[$i]['code']]) === true) { - // Found the end of the statement. - if ($tokens[$i]['code'] === T_CLOSE_PARENTHESIS - || $tokens[$i]['code'] === T_CLOSE_SQUARE_BRACKET - || $tokens[$i]['code'] === T_CLOSE_CURLY_BRACKET - || $tokens[$i]['code'] === T_CLOSE_SHORT_ARRAY - || $tokens[$i]['code'] === T_OPEN_TAG - || $tokens[$i]['code'] === T_CLOSE_TAG - ) { - return $lastNotEmpty; - } - - return $i; - } - - // Skip nested statements. - if (isset($tokens[$i]['scope_closer']) === true - && ($i === $tokens[$i]['scope_opener'] - || $i === $tokens[$i]['scope_condition']) - ) { - if ($tokens[$i]['type'] === 'T_FN') { - $lastNotEmpty = $tokens[$i]['scope_closer']; - - // Minus 1 as the closer can be shared. - $i = ($tokens[$i]['scope_closer'] - 1); - continue; - } - - if ($i === $start && isset(Tokens::$scopeOpeners[$tokens[$i]['code']]) === true) { - return $tokens[$i]['scope_closer']; - } - - $i = $tokens[$i]['scope_closer']; - } elseif (isset($tokens[$i]['bracket_closer']) === true - && $i === $tokens[$i]['bracket_opener'] - ) { - $i = $tokens[$i]['bracket_closer']; - } elseif (isset($tokens[$i]['parenthesis_closer']) === true - && $i === $tokens[$i]['parenthesis_opener'] - ) { - $i = $tokens[$i]['parenthesis_closer']; - } elseif ($tokens[$i]['code'] === T_OPEN_USE_GROUP) { - $end = $phpcsFile->findNext(T_CLOSE_USE_GROUP, ($i + 1)); - if ($end !== false) { - $i = $end; - } - } elseif (isset(Collections::arrowFunctionTokensBC()[$tokens[$i]['code']]) === true) { - // Potentially a PHP 7.4 arrow function in combination with PHP < 7.4 or PHPCS < 3.5.3/3.5.4. - $arrowFunctionOpenClose = FunctionDeclarations::getArrowFunctionOpenClose($phpcsFile, $i); - if ($arrowFunctionOpenClose !== false) { - if ($i === $start) { - return $arrowFunctionOpenClose['scope_closer']; - } - - $lastNotEmpty = $arrowFunctionOpenClose['scope_closer']; - - // Minus 1 as the closer can be shared. - $i = ($arrowFunctionOpenClose['scope_closer'] - 1); - continue; - } - } - - if (isset(Tokens::$emptyTokens[$tokens[$i]['code']]) === false) { - $lastNotEmpty = $i; - } - } - - return ($phpcsFile->numTokens - 1); + return $phpcsFile->findEndOfStatement($start, $ignore); } /** @@ -1430,7 +642,7 @@ public static function findEndOfStatement(File $phpcsFile, $start, $ignore = nul * * Changelog for the PHPCS native function: * - Introduced in PHPCS 0.0.5. - * - This method has received no significant code updates since PHPCS 2.6.0. + * - The upstream method has received no significant updates since PHPCS 3.7.1. * * @see \PHP_CodeSniffer\Files\File::hasCondition() Original source. * @see \PHPCSUtils\Utils\Conditions::hasCondition() PHPCSUtils native alternative. @@ -1455,14 +667,12 @@ public static function hasCondition(File $phpcsFile, $stackPtr, $types) * * Changelog for the PHPCS native function: * - Introduced in PHPCS 1.3.0. - * - PHPCS 3.5.4: New `$first` parameter which allows for the closest matching token to be returned. - * By default, it continues to return the first matched token found from the top of the file. + * - The upstream method has received no significant updates since PHPCS 3.7.1. * * @see \PHP_CodeSniffer\Files\File::getCondition() Original source. * @see \PHPCSUtils\Utils\Conditions::getCondition() More versatile alternative. * * @since 1.0.0 - * @since 1.0.0-alpha2 Added support for the PHPCS 3.5.4 `$first` parameter. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position of the token we are checking. @@ -1477,30 +687,7 @@ public static function hasCondition(File $phpcsFile, $stackPtr, $types) */ public static function getCondition(File $phpcsFile, $stackPtr, $type, $first = true) { - $tokens = $phpcsFile->getTokens(); - - // Check for the existence of the token. - if (isset($tokens[$stackPtr]) === false) { - return false; - } - - // Make sure the token has conditions. - if (isset($tokens[$stackPtr]['conditions']) === false) { - return false; - } - - $conditions = $tokens[$stackPtr]['conditions']; - if ($first === false) { - $conditions = array_reverse($conditions, true); - } - - foreach ($conditions as $token => $condition) { - if ($condition === $type) { - return $token; - } - } - - return false; + return $phpcsFile->getCondition($stackPtr, $type, $first); } /** @@ -1511,16 +698,12 @@ public static function getCondition(File $phpcsFile, $stackPtr, $type, $first = * * Changelog for the PHPCS native function: * - Introduced in PHPCS 1.2.0. - * - PHPCS 2.8.0: Now supports anonymous classes. - * - PHPCS 3.1.0: Now supports interfaces extending interfaces (incorrectly, only supporting - * single interface extension). - * - PHPCS 3.3.2: Fixed bug causing bleed through with nested classes, PHPCS#2127. + * - The upstream method has received no significant updates since PHPCS 3.7.1. * * @see \PHP_CodeSniffer\Files\File::findExtendedClassName() Original source. * @see \PHPCSUtils\Utils\ObjectDeclarations::findExtendedClassName() PHPCSUtils native improved version. * * @since 1.0.0 - * @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokens. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The stack position of the class or interface. @@ -1530,116 +713,31 @@ public static function getCondition(File $phpcsFile, $stackPtr, $type, $first = */ public static function findExtendedClassName(File $phpcsFile, $stackPtr) { - $tokens = $phpcsFile->getTokens(); - - // Check for the existence of the token. - if (isset($tokens[$stackPtr]) === false) { - return false; - } - - if ($tokens[$stackPtr]['code'] !== T_CLASS - && $tokens[$stackPtr]['code'] !== T_ANON_CLASS - && $tokens[$stackPtr]['code'] !== T_INTERFACE - ) { - return false; - } - - if (isset($tokens[$stackPtr]['scope_opener']) === false) { - return false; - } - - $classOpenerIndex = $tokens[$stackPtr]['scope_opener']; - $extendsIndex = $phpcsFile->findNext(T_EXTENDS, $stackPtr, $classOpenerIndex); - if ($extendsIndex === false) { - return false; - } - - $find = [ - T_NS_SEPARATOR => T_NS_SEPARATOR, - T_STRING => T_STRING, - T_WHITESPACE => T_WHITESPACE, - ]; - - // BC for PHP 8 in combination with PHPCS < 3.5.7. - $find += Collections::nameTokens(); - - $end = $phpcsFile->findNext($find, ($extendsIndex + 1), ($classOpenerIndex + 1), true); - $name = $phpcsFile->getTokensAsString(($extendsIndex + 1), ($end - $extendsIndex - 1)); - $name = trim($name); - - if ($name === '') { - return false; - } - - return $name; + return $phpcsFile->findExtendedClassName($stackPtr); } /** - * Returns the names of the interfaces that the specified class implements. + * Returns the names of the interfaces that the specified class or enum implements. * * PHPCS cross-version compatible version of the `File::findImplementedInterfaceNames()` method. * * Changelog for the PHPCS native function: * - Introduced in PHPCS 2.7.0. - * - PHPCS 2.8.0: Now supports anonymous classes. + * - The upstream method has received no significant updates since PHPCS 3.7.1. * * @see \PHP_CodeSniffer\Files\File::findImplementedInterfaceNames() Original source. * @see \PHPCSUtils\Utils\ObjectDeclarations::findImplementedInterfaceNames() PHPCSUtils native improved version. * * @since 1.0.0 - * @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokens. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. - * @param int $stackPtr The stack position of the class. + * @param int $stackPtr The stack position of the class or enum token. * * @return array|false Array with names of the implemented interfaces or `FALSE` on * error or if there are no implemented interface names. */ public static function findImplementedInterfaceNames(File $phpcsFile, $stackPtr) { - $tokens = $phpcsFile->getTokens(); - - // Check for the existence of the token. - if (isset($tokens[$stackPtr]) === false) { - return false; - } - - if ($tokens[$stackPtr]['code'] !== T_CLASS - && $tokens[$stackPtr]['code'] !== T_ANON_CLASS - ) { - return false; - } - - if (isset($tokens[$stackPtr]['scope_closer']) === false) { - return false; - } - - $classOpenerIndex = $tokens[$stackPtr]['scope_opener']; - $implementsIndex = $phpcsFile->findNext(T_IMPLEMENTS, $stackPtr, $classOpenerIndex); - if ($implementsIndex === false) { - return false; - } - - $find = [ - T_NS_SEPARATOR => T_NS_SEPARATOR, - T_STRING => T_STRING, - T_WHITESPACE => T_WHITESPACE, - T_COMMA => T_COMMA, - ]; - - // BC for PHP 8 in combination with PHPCS < 3.5.7. - $find += Collections::nameTokens(); - - $end = $phpcsFile->findNext($find, ($implementsIndex + 1), ($classOpenerIndex + 1), true); - $name = $phpcsFile->getTokensAsString(($implementsIndex + 1), ($end - $implementsIndex - 1)); - $name = trim($name); - - if ($name === '') { - return false; - } else { - $names = explode(',', $name); - $names = array_map('trim', $names); - return $names; - } + return $phpcsFile->findImplementedInterfaceNames($stackPtr); } } diff --git a/PHPCSUtils/BackCompat/BCTokens.php b/PHPCSUtils/BackCompat/BCTokens.php index 945fecae..20ba13d9 100644 --- a/PHPCSUtils/BackCompat/BCTokens.php +++ b/PHPCSUtils/BackCompat/BCTokens.php @@ -13,7 +13,6 @@ use PHP_CodeSniffer\Util\Tokens; use PHPCSUtils\Exceptions\InvalidTokenArray; use PHPCSUtils\Tokens\Collections; -use PHPCSUtils\Tokens\TokenHelper; /** * Token arrays related utility methods. @@ -43,96 +42,39 @@ * the token arrays returned by this class. * * @since 1.0.0 + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. * - * @method static array blockOpeners() Tokens that open code blocks. - * @method static array booleanOperators() Tokens that perform boolean operations. - * @method static array bracketTokens() Tokens that represent brackets and parenthesis. - * @method static array castTokens() Tokens that represent type casting. - * @method static array commentTokens() Tokens that are comments. - * @method static array emptyTokens() Tokens that don't represent code. - * @method static array equalityTokens() Tokens that represent equality comparisons. - * @method static array heredocTokens() Tokens that make up a heredoc string. - * @method static array includeTokens() Tokens that include files. - * @method static array methodPrefixes() Tokens that can prefix a method name. - * @method static array scopeModifiers() Tokens that represent scope modifiers. - * @method static array stringTokens() Tokens that represent strings. - * Note that `T_STRING`s are NOT represented in this list as this list - * is about _text_ strings. + * @method static array arithmeticTokens() Tokens that represent arithmetic operators. + * @method static array assignmentTokens() Tokens that represent assignments. + * @method static array blockOpeners() Tokens that open code blocks. + * @method static array booleanOperators() Tokens that perform boolean operations. + * @method static array bracketTokens() Tokens that represent brackets and parenthesis. + * @method static array castTokens() Tokens that represent type casting. + * @method static array commentTokens() Tokens that are comments. + * @method static array comparisonTokens() Tokens that represent comparison operator. + * @method static array emptyTokens() Tokens that don't represent code. + * @method static array equalityTokens() Tokens that represent equality comparisons. + * @method static array heredocTokens() Tokens that make up a heredoc string. + * @method static array includeTokens() Tokens that include files. + * @method static array magicConstants() Tokens representing PHP magic constants. + * @method static array methodPrefixes() Tokens that can prefix a method name. + * @method static array ooScopeTokens() Tokens that open class and object scopes. + * @method static array operators() Tokens that perform operations. + * @method static array parenthesisOpeners() Token types that open parenthesis. + * @method static array phpcsCommentTokens() Tokens that are comments containing PHPCS instructions. + * @method static array scopeModifiers() Tokens that represent scope modifiers. + * @method static array scopeOpeners() Tokens that are allowed to open scopes. + * @method static array stringTokens() Tokens that represent strings. + * Note that `T_STRING`s are NOT represented in this list as this list + * is about _text_ strings. + * @method static array textStringTokens() Tokens that represent text strings. */ class BCTokens { - /** - * Token types that are comments containing PHPCS instructions. - * - * @since 1.0.0 - * @since 1.0.0-alpha3 Visibility changed from `protected` to `private`. - * - * @var string[] - */ - private static $phpcsCommentTokensTypes = [ - 'T_PHPCS_ENABLE', - 'T_PHPCS_DISABLE', - 'T_PHPCS_SET', - 'T_PHPCS_IGNORE', - 'T_PHPCS_IGNORE_FILE', - ]; - - /** - * Tokens that open class and object scopes. - * - * @since 1.0.0 - * @since 1.0.0-alpha3 Visibility changed from `protected` to `private`. - * - * {@internal Note: T_ENUM is missing from this array and will be added dynamically - * in the ooScopeTokens() method when available.} - * - * @var array => - */ - private static $ooScopeTokens = [ - \T_CLASS => \T_CLASS, - \T_ANON_CLASS => \T_ANON_CLASS, - \T_INTERFACE => \T_INTERFACE, - \T_TRAIT => \T_TRAIT, - ]; - - /** - * Tokens that represent text strings. - * - * @since 1.0.0 - * @since 1.0.0-alpha3 Visibility changed from `protected` to `private`. - * - * @var array => - */ - private static $textStringTokens = [ - \T_CONSTANT_ENCAPSED_STRING => \T_CONSTANT_ENCAPSED_STRING, - \T_DOUBLE_QUOTED_STRING => \T_DOUBLE_QUOTED_STRING, - \T_INLINE_HTML => \T_INLINE_HTML, - \T_HEREDOC => \T_HEREDOC, - \T_NOWDOC => \T_NOWDOC, - ]; - - /** - * Tokens representing PHP magic constants. - * - * @since 1.0.0-alpha4 - * - * @var array => - */ - private static $magicConstants = [ - \T_CLASS_C => \T_CLASS_C, - \T_DIR => \T_DIR, - \T_FILE => \T_FILE, - \T_FUNC_C => \T_FUNC_C, - \T_LINE => \T_LINE, - \T_METHOD_C => \T_METHOD_C, - \T_NS_C => \T_NS_C, - \T_TRAIT_C => \T_TRAIT_C, - ]; - /** * Handle calls to (undeclared) methods for token arrays which haven't received any - * changes since PHPCS 2.6.0. + * changes since PHPCS 3.7.1. * * @since 1.0.0 * @@ -154,272 +96,6 @@ public static function __callStatic($name, $args) throw InvalidTokenArray::create($name); } - /** - * Tokens that represent assignment operators. - * - * Retrieve the PHPCS assignment tokens array in a cross-version compatible manner. - * - * Changelog for the PHPCS native array: - * - Introduced in PHPCS 0.0.5. - * - PHPCS 2.9.0: The PHP 7.4 `T_COALESCE_EQUAL` token was added to the array. - * The `T_COALESCE_EQUAL` token was introduced in PHPCS 2.8.1. - * - PHPCS 3.2.0: The JS `T_ZSR_EQUAL` token was added to the array. - * The `T_ZSR_EQUAL` token was introduced in PHPCS 2.8.0. - * - * @see \PHP_CodeSniffer\Util\Tokens::$assignmentTokens Original array. - * - * @since 1.0.0 - * - * @return array => Token array. - */ - public static function assignmentTokens() - { - $tokens = Tokens::$assignmentTokens; - - /* - * The `T_COALESCE_EQUAL` token may be available pre-PHPCS 2.8.1 depending on - * the PHP version used to run PHPCS. - */ - if (TokenHelper::tokenExists('T_COALESCE_EQUAL')) { - $tokens[\T_COALESCE_EQUAL] = \T_COALESCE_EQUAL; - } - - if (\defined('T_ZSR_EQUAL')) { - $tokens[\T_ZSR_EQUAL] = \T_ZSR_EQUAL; - } - - return $tokens; - } - - /** - * Tokens that represent comparison operators. - * - * Retrieve the PHPCS comparison tokens array in a cross-version compatible manner. - * - * Changelog for the PHPCS native array: - * - Introduced in PHPCS 0.5.0. - * - PHPCS 2.9.0: The PHP 7.0 `T_COALESCE` token was added to the array. - * The `T_COALESCE` token was introduced in PHPCS 2.6.1. - * - PHPCS 2.9.0: The PHP 7.0 `T_SPACESHIP` token was added to the array. - * The `T_SPACESHIP` token was introduced in PHPCS 2.5.1. - * - * @see \PHP_CodeSniffer\Util\Tokens::$comparisonTokens Original array. - * - * @since 1.0.0 - * - * @return array => Token array. - */ - public static function comparisonTokens() - { - $tokens = Tokens::$comparisonTokens + [\T_SPACESHIP => \T_SPACESHIP]; - - if (\defined('T_COALESCE')) { - $tokens[\T_COALESCE] = \T_COALESCE; - } - - return $tokens; - } - - /** - * Tokens that represent arithmetic operators. - * - * Retrieve the PHPCS arithmetic tokens array in a cross-version compatible manner. - * - * Changelog for the PHPCS native array: - * - Introduced in PHPCS 0.5.0. - * - PHPCS 2.9.0: The PHP 5.6 `T_POW` token was added to the array. - * The `T_POW` token was introduced in PHPCS 2.4.0. - * - * @see \PHP_CodeSniffer\Util\Tokens::$arithmeticTokens Original array. - * - * @since 1.0.0 - * - * @return array => Token array or an empty array for PHPCS versions in - * which the PHPCS native comment tokens did not exist yet. - */ - public static function arithmeticTokens() - { - return Tokens::$arithmeticTokens + [\T_POW => \T_POW]; - } - - /** - * Tokens that perform operations. - * - * Retrieve the PHPCS operator tokens array in a cross-version compatible manner. - * - * Changelog for the PHPCS native array: - * - Introduced in PHPCS 0.0.5. - * - PHPCS 2.6.1: The PHP 7.0 `T_COALESCE` token was backfilled and added to the array. - * - PHPCS 2.8.1: The PHP 7.4 `T_COALESCE_EQUAL` token was backfilled and (incorrectly) - * added to the array. - * - PHPCS 2.9.0: The `T_COALESCE_EQUAL` token was removed from the array. - * - * @see \PHP_CodeSniffer\Util\Tokens::$operators Original array. - * - * @since 1.0.0 - * - * @return array => Token array. - */ - public static function operators() - { - $tokens = Tokens::$operators; - - /* - * The `T_COALESCE` token may be available pre-PHPCS 2.6.1 depending on the PHP version - * used to run PHPCS. - */ - if (\defined('T_COALESCE')) { - $tokens[\T_COALESCE] = \T_COALESCE; - } - - if (TokenHelper::tokenExists('T_COALESCE_EQUAL')) { - unset($tokens[\T_COALESCE_EQUAL]); - } - - return $tokens; - } - - /** - * Token types that open parentheses. - * - * Retrieve the PHPCS parenthesis openers tokens array in a cross-version compatible manner. - * - * Changelog for the PHPCS native array: - * - Introduced in PHPCS 0.0.5. - * - PHPCS 3.5.0: `T_LIST` and `T_ANON_CLASS` added to the array. - * - PHPCS 3.6.0: `T_MATCH` added to the array. - * - * Note: While `T_LIST` and `T_ANON_CLASS` will be included in the return value for this - * method, the associated parentheses will not have the `'parenthesis_owner'` index set - * until PHPCS 3.5.0. Use the {@see \PHPCSUtils\Utils\Parentheses::getOwner()} - * or {@see \PHPCSUtils\Utils\Parentheses::hasOwner()} methods if you need to check for - * a `T_LIST` or `T_ANON_CLASS` parentheses owner. - * - * @see \PHP_CodeSniffer\Util\Tokens::$parenthesisOpeners Original array. - * @see \PHPCSUtils\Utils\Parentheses Class holding utility methods for - * working with the `'parenthesis_...'` - * index keys in a token array. - * - * @since 1.0.0 - * - * @return array => Token array. - */ - public static function parenthesisOpeners() - { - $tokens = Tokens::$parenthesisOpeners; - $tokens[\T_LIST] = \T_LIST; - $tokens[\T_ANON_CLASS] = \T_ANON_CLASS; - - /* - * The `T_MATCH` token may be available pre-PHPCS 3.6.0 depending on the PHP version - * used to run PHPCS. - */ - if (TokenHelper::tokenExists('T_MATCH')) { - $tokens[\T_MATCH] = \T_MATCH; - } - - return $tokens; - } - - /** - * Tokens that are allowed to open scopes. - * - * Retrieve the PHPCS scope openers tokens array in a cross-version compatible manner. - * - * Changelog for the PHPCS native array: - * - Introduced in PHPCS 0.0.5. - * - PHPCS 3.6.0: `T_MATCH` added to the array. - * - PHPCS 3.7.0: `T_ENUM` added to the array. - * - * @since 1.0.0-alpha4 - * - * @return array => Token array. - */ - public static function scopeOpeners() - { - $tokens = Tokens::$scopeOpeners; - - /* - * The `T_MATCH` token may be available pre-PHPCS 3.6.0 depending on the PHP version - * used to run PHPCS. - */ - if (TokenHelper::tokenExists('T_MATCH')) { - $tokens[\T_MATCH] = \T_MATCH; - } - - /* - * The `T_ENUM` token may be available pre-PHPCS 3.7.0 depending on the PHP version - * used to run PHPCS. - */ - if (TokenHelper::tokenExists('T_ENUM')) { - $tokens[\T_ENUM] = \T_ENUM; - } - - return $tokens; - } - - /** - * Tokens that are comments containing PHPCS instructions. - * - * Retrieve the PHPCS comment tokens array in a cross-version compatible manner. - * - * Changelog for the PHPCS native array: - * - Introduced in PHPCS 3.2.3. The PHPCS comment tokens, however, were introduced in - * PHPCS 3.2.0. - * - * @see \PHP_CodeSniffer\Util\Tokens::$phpcsCommentTokens Original array. - * - * @since 1.0.0 - * - * @return array => Token array or an empty array for PHPCS - * versions in which the PHPCS native annotation - * tokens did not exist yet. - */ - public static function phpcsCommentTokens() - { - static $tokenArray = []; - - if (isset(Tokens::$phpcsCommentTokens)) { - return Tokens::$phpcsCommentTokens; - } - - if (\defined('T_PHPCS_IGNORE')) { - // PHPCS 3.2.0 - 3.2.2. - if (empty($tokenArray)) { - foreach (self::$phpcsCommentTokensTypes as $type) { - $tokenArray[\constant($type)] = \constant($type); - } - } - - return $tokenArray; - } - - return []; - } - - /** - * Tokens that represent text strings. - * - * Retrieve the PHPCS text string tokens array in a cross-version compatible manner. - * - * Changelog for the PHPCS native array: - * - Introduced in PHPCS 2.9.0. - * - * @see \PHP_CodeSniffer\Util\Tokens::$textStringTokens Original array. - * - * @since 1.0.0 - * - * @return array => Token array. - */ - public static function textStringTokens() - { - if (isset(Tokens::$textStringTokens)) { - return Tokens::$textStringTokens; - } - - return self::$textStringTokens; - } - /** * Tokens that represent the names of called functions. * @@ -427,7 +103,6 @@ public static function textStringTokens() * * Changelog for the PHPCS native array: * - Introduced in PHPCS 2.3.3. - * - PHPCS 3.1.0: `T_SELF` and `T_STATIC` added to the array. * - PHPCS 3.7.2: `T_PARENT` added to the array. * - PHPCS 4.0.0: `T_NAME_QUALIFIED`, `T_NAME_FULLY_QUALIFIED` and `T_NAME_RELATIVE` added to the array. * @@ -446,65 +121,6 @@ public static function functionNameTokens() return $tokens; } - /** - * Tokens that open class and object scopes. - * - * Retrieve the OO scope tokens array in a cross-version compatible manner. - * - * Changelog for the PHPCS native array: - * - Introduced in PHPCS 3.1.0. - * - PHPCS 3.7.0: `T_ENUM` added to the array. - * - * @see \PHP_CodeSniffer\Util\Tokens::$ooScopeTokens Original array. - * - * @since 1.0.0 - * - * @return array => Token array. - */ - public static function ooScopeTokens() - { - $tokens = self::$ooScopeTokens; - - if (isset(Tokens::$ooScopeTokens)) { - $tokens = Tokens::$ooScopeTokens; - } - - /* - * The `T_ENUM` token may be available pre-PHPCS 3.7.0 depending on the PHP version - * used to run PHPCS. - */ - if (TokenHelper::tokenExists('T_ENUM')) { - $tokens[\T_ENUM] = \T_ENUM; - } - - return $tokens; - } - - /** - * Tokens representing PHP magic constants. - * - * Retrieve the PHP magic constants tokens array in a cross-version compatible manner. - * - * Changelog for the PHPCS native array: - * - Introduced in PHPCS 3.5.6. - * - * @see \PHP_CodeSniffer\Util\Tokens::$magicConstants Original array. - * - * @link https://www.php.net/language.constants.predefined PHP Manual on magic constants - * - * @since 1.0.0-alpha4 - * - * @return array => - */ - public static function magicConstants() - { - if (isset(Tokens::$magicConstants)) { - return Tokens::$magicConstants; - } - - return self::$magicConstants; - } - /** * Given a token, returns the name of the token. * @@ -523,11 +139,6 @@ public static function magicConstants() */ public static function tokenName($token) { - if (\is_string($token) === false) { - // PHP-supplied token name. - return \token_name($token); - } - - return \substr($token, 6); + return Tokens::tokenName($token); } } diff --git a/PHPCSUtils/BackCompat/Helper.php b/PHPCSUtils/BackCompat/Helper.php index ac1b186e..e1017a8f 100644 --- a/PHPCSUtils/BackCompat/Helper.php +++ b/PHPCSUtils/BackCompat/Helper.php @@ -10,21 +10,18 @@ namespace PHPCSUtils\BackCompat; +use PHP_CodeSniffer\Config; use PHP_CodeSniffer\Exceptions\RuntimeException; use PHP_CodeSniffer\Files\File; /** * Utility methods to retrieve (configuration) information from PHP_CodeSniffer. * - * PHP_CodeSniffer cross-version compatibility helper for PHPCS 2.x vs PHPCS 3.x. + * PHP_CodeSniffer cross-version compatibility helper. * - * A number of PHPCS classes were split up into several classes in PHPCS 3.x - * Those classes cannot be aliased as they don't represent the same object. - * This class provides helper methods for functions which were contained in - * one of these classes and which are commonly used by external standards. - * - * @since 1.0.0 The initial methods in this class have been ported over from - * the external PHPCompatibility & WPCS standards. + * @since 1.0.0 The initial methods in this class have been ported over from + * the external PHPCompatibility & WPCS standards. + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. */ class Helper { @@ -47,13 +44,7 @@ class Helper */ public static function getVersion() { - if (\defined('\PHP_CodeSniffer\Config::VERSION') === false) { - // PHPCS 2.x. - return \PHP_CodeSniffer::VERSION; - } - - // PHPCS 3.x. - return \PHP_CodeSniffer\Config::VERSION; + return Config::VERSION; } /** @@ -76,11 +67,6 @@ public static function getVersion() */ public static function setConfigData($key, $value, $temp = false, $config = null) { - if (\method_exists('\PHP_CodeSniffer\Config', 'setConfigData') === false) { - // PHPCS 2.x. - return \PHP_CodeSniffer::setConfigData($key, $value, $temp); - } - if (isset($config) === true) { // PHPCS 3.x and 4.x. return $config->setConfigData($key, $value, $temp); @@ -91,7 +77,7 @@ public static function setConfigData($key, $value, $temp = false, $config = null } // PHPCS 3.x. - return \PHP_CodeSniffer\Config::setConfigData($key, $value, $temp); + return Config::setConfigData($key, $value, $temp); } /** @@ -108,13 +94,7 @@ public static function setConfigData($key, $value, $temp = false, $config = null */ public static function getConfigData($key) { - if (\method_exists('\PHP_CodeSniffer\Config', 'getConfigData') === false) { - // PHPCS 2.x. - return \PHP_CodeSniffer::getConfigData($key); - } - - // PHPCS 3.x. - return \PHP_CodeSniffer\Config::getConfigData($key); + return Config::getConfigData($key); } /** @@ -132,18 +112,8 @@ public static function getConfigData($key) */ public static function getCommandLineData(File $phpcsFile, $key) { - if (\class_exists('\PHP_CodeSniffer\Config') === false) { - // PHPCS 2.x. - $config = $phpcsFile->phpcs->cli->getCommandLineValues(); - if (isset($config[$key])) { - return $config[$key]; - } - } else { - // PHPCS 3.x. - $config = $phpcsFile->config; - if (isset($config->{$key})) { - return $config->{$key}; - } + if (isset($phpcsFile->config->{$key})) { + return $phpcsFile->config->{$key}; } return null; @@ -178,15 +148,11 @@ public static function getTabWidth(File $phpcsFile) * @param \PHP_CodeSniffer\Files\File|null $phpcsFile Optional. The current file being processed. * * @return string Encoding. Defaults to the PHPCS native default, which is 'utf-8' - * for PHPCS 3.x and was 'iso-8859-1' for PHPCS 2.x. + * for PHPCS 3.x. */ public static function getEncoding(File $phpcsFile = null) { $default = 'utf-8'; - if (\version_compare(self::getVersion(), '2.99.99', '<=') === true) { - // In PHPCS 2.x, the default encoding is `iso-8859-1`. - $default = 'iso-8859-1'; - } if ($phpcsFile instanceof File) { // Most reliable. @@ -218,17 +184,11 @@ public static function getEncoding(File $phpcsFile = null) */ public static function ignoreAnnotations(File $phpcsFile = null) { - if (\class_exists('\PHP_CodeSniffer\Config') === false) { - // PHPCS 2.x does not support `--ignore-annotations`. - return false; - } - - // PHPCS 3.x. if (isset($phpcsFile, $phpcsFile->config->annotations)) { return ! $phpcsFile->config->annotations; } - $annotations = \PHP_CodeSniffer\Config::getConfigData('annotations'); + $annotations = Config::getConfigData('annotations'); if (isset($annotations)) { return ! $annotations; } diff --git a/PHPCSUtils/TestUtils/UtilityMethodTestCase.php b/PHPCSUtils/TestUtils/UtilityMethodTestCase.php index 98b4afd5..8d5a5a93 100644 --- a/PHPCSUtils/TestUtils/UtilityMethodTestCase.php +++ b/PHPCSUtils/TestUtils/UtilityMethodTestCase.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\TestUtils; -use PHP_CodeSniffer\Exceptions\RuntimeException; use PHP_CodeSniffer\Exceptions\TokenizerException; use PHPCSUtils\BackCompat\Helper; use PHPUnit\Framework\TestCase; @@ -20,7 +19,8 @@ /** * Base class for use when testing utility methods for PHP_CodeSniffer. * - * This class is compatible with PHP_CodeSniffer 2.x as well as 3.x. + * This class is compatible with PHP_CodeSniffer 3.x and contains preliminary compatibility with 4.x + * based on its currently known state/roadmap. * * This class is compatible with {@link http://phpunit.de/ PHPUnit} 4.5 - 9.x providing the PHPCSUtils * autoload file is included in the test bootstrap. For more information about that, please consult @@ -97,6 +97,7 @@ * for the PHPCSUtils utility functions themselves. * * @since 1.0.0 + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. */ abstract class UtilityMethodTestCase extends TestCase { @@ -205,59 +206,39 @@ public static function setUpTestFile() $contents = \file_get_contents($caseFile); - if (\version_compare(self::$phpcsVersion, '2.99.99', '>')) { - // PHPCS 3.x. - $config = new \PHP_CodeSniffer\Config(); + $config = new \PHP_CodeSniffer\Config(); - /* - * We just need to provide a standard so PHPCS will tokenize the file. - * The standard itself doesn't actually matter for testing utility methods, - * so use the smallest one to get the fastest results. - */ - $config->standards = ['PSR1']; + /* + * We just need to provide a standard so PHPCS will tokenize the file. + * The standard itself doesn't actually matter for testing utility methods, + * so use the smallest one to get the fastest results. + */ + $config->standards = ['PSR1']; - /* - * Limiting the run to just one sniff will make it, yet again, slightly faster. - * Picked the simplest/fastest sniff available which is registered in PSR1. - */ - $config->sniffs = static::$selectedSniff; + /* + * Limiting the run to just one sniff will make it, yet again, slightly faster. + * Picked the simplest/fastest sniff available which is registered in PSR1. + */ + $config->sniffs = static::$selectedSniff; - // Disable caching. - $config->cache = false; + // Disable caching. + $config->cache = false; - // Also set a tab-width to enable testing tab-replaced vs `orig_content`. - $config->tabWidth = static::$tabWidth; + // Also set a tab-width to enable testing tab-replaced vs `orig_content`. + $config->tabWidth = static::$tabWidth; - $ruleset = new \PHP_CodeSniffer\Ruleset($config); + $ruleset = new \PHP_CodeSniffer\Ruleset($config); - // Make sure the file gets parsed correctly based on the file type. - $contents = 'phpcs_input_file: ' . $caseFile . \PHP_EOL . $contents; + // Make sure the file gets parsed correctly based on the file type. + $contents = 'phpcs_input_file: ' . $caseFile . \PHP_EOL . $contents; - self::$phpcsFile = new \PHP_CodeSniffer\Files\DummyFile($contents, $ruleset, $config); + self::$phpcsFile = new \PHP_CodeSniffer\Files\DummyFile($contents, $ruleset, $config); - // Only tokenize the file, do not process it. - try { - self::$phpcsFile->parse(); - } catch (TokenizerException $e) { - // PHPCS 3.5.0 and higher. - } catch (RuntimeException $e) { - // PHPCS 3.0.0 < 3.5.0. - } - } else { - // PHPCS 2.x. - $phpcs = new \PHP_CodeSniffer(null, static::$tabWidth); - self::$phpcsFile = new \PHP_CodeSniffer_File( - $caseFile, - [], - [], - $phpcs - ); - - /* - * Using error silencing to drown out "undefined index" notices for tokenizer - * issues in PHPCS 2.x which won't get fixed anymore anyway. - */ - @self::$phpcsFile->start($contents); + // Only tokenize the file, do not process it. + try { + self::$phpcsFile->parse(); + } catch (TokenizerException $e) { + // PHPCS 3.5.0 and higher. This is handled below. } // Fail the test if the case file failed to tokenize. @@ -335,15 +316,7 @@ public static function resetTestFile() */ public static function usesPhp8NameTokens() { - $version = Helper::getVersion(); - if ((\version_compare(\PHP_VERSION_ID, '80000', '>=') === true - && \version_compare($version, '3.5.7', '<') === true) - || \version_compare($version, '4.0.0', '>=') === true - ) { - return true; - } - - return false; + return \version_compare(Helper::getVersion(), '3.99.99', '>='); } /** diff --git a/PHPCSUtils/Tokens/Collections.php b/PHPCSUtils/Tokens/Collections.php index a98640d7..2f782d3d 100644 --- a/PHPCSUtils/Tokens/Collections.php +++ b/PHPCSUtils/Tokens/Collections.php @@ -10,8 +10,6 @@ namespace PHPCSUtils\Tokens; -use PHPCSUtils\Tokens\TokenHelper; - /** * Collections of related tokens as often used and needed for sniffs. * @@ -22,6 +20,7 @@ * @see \PHPCSUtils\BackCompat\BCTokens Backward compatible version of the PHPCS native token groups. * * @since 1.0.0 + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. */ class Collections { @@ -234,18 +233,42 @@ class Collections \T_CLOSE_TAG => \T_CLOSE_TAG, ]; + /** + * Tokens used for "names", be it namespace, OO, function or constant names. + * + * Includes the tokens introduced in PHP 8.0 for "Namespaced names as single token". + * + * Note: the PHP 8.0 namespaced name tokens are backfilled in PHPCS since PHPCS 3.5.7, + * but are not used yet (the PHP 8.0 tokenization is "undone" in PHPCS). + * As of PHPCS 4.0.0, these tokens _will_ be used and the PHP 8.0 tokenization is respected. + * + * @link https://wiki.php.net/rfc/namespaced_names_as_token + * + * @since 1.0.0-alpha4 Use the {@see Collections::nameTokens()} method for access. + * + * @return array => + */ + private static $nameTokens = [ + \T_STRING => \T_STRING, + \T_NAME_QUALIFIED => \T_NAME_QUALIFIED, + \T_NAME_FULLY_QUALIFIED => \T_NAME_FULLY_QUALIFIED, + \T_NAME_RELATIVE => \T_NAME_RELATIVE, + ]; + /** * DEPRECATED: Object operators. * * @since 1.0.0-alpha3 + * @since 1.0.0-alpha4 Added the PHP 8.0 T_NULLSAFE_OBJECT_OPERATOR token. * * @deprecated 1.0.0-alpha4 Use the {@see Collections::objectOperators()} method instead. * * @var array => */ public static $objectOperators = [ - \T_OBJECT_OPERATOR => \T_OBJECT_OPERATOR, - \T_DOUBLE_COLON => \T_DOUBLE_COLON, + \T_DOUBLE_COLON => \T_DOUBLE_COLON, + \T_OBJECT_OPERATOR => \T_OBJECT_OPERATOR, + \T_NULLSAFE_OBJECT_OPERATOR => \T_NULLSAFE_OBJECT_OPERATOR, ]; /** @@ -341,9 +364,9 @@ class Collections * DEPRECATED: Token types which can be encountered in a parameter type declaration. * * @since 1.0.0-alpha1 + * @since 1.0.0-alpha4 Added the T_TYPE_UNION, T_FALSE, T_NULL tokens for PHP 8.0 union type support. * - * @deprecated 1.0.0-alpha4 Use the {@see Collections::parameterTypeTokens()} or - * {@see Collections::parameterTypeTokensBC()} method instead. + * @deprecated 1.0.0-alpha4 Use the {@see Collections::parameterTypeTokens()} method instead. * * @var array => */ @@ -351,8 +374,11 @@ class Collections \T_CALLABLE => \T_CALLABLE, \T_SELF => \T_SELF, \T_PARENT => \T_PARENT, + \T_FALSE => \T_FALSE, + \T_NULL => \T_NULL, \T_STRING => \T_STRING, \T_NS_SEPARATOR => \T_NS_SEPARATOR, + \T_TYPE_UNION => \T_TYPE_UNION, ]; /** @@ -376,9 +402,9 @@ class Collections * DEPRECATED: Token types which can be encountered in a property type declaration. * * @since 1.0.0-alpha1 + * @since 1.0.0-alpha4 Added the T_TYPE_UNION, T_FALSE, T_NULL tokens for PHP 8.0 union type support. * - * @deprecated 1.0.0-alpha4 Use the {@see Collections::propertyTypeTokens()} or - * {@see Collections::propertyTypeTokensBC()} method instead. + * @deprecated 1.0.0-alpha4 Use the {@see Collections::propertyTypeTokens()} method instead. * * @var array => */ @@ -386,27 +412,33 @@ class Collections \T_CALLABLE => \T_CALLABLE, \T_SELF => \T_SELF, \T_PARENT => \T_PARENT, + \T_FALSE => \T_FALSE, + \T_NULL => \T_NULL, \T_STRING => \T_STRING, \T_NS_SEPARATOR => \T_NS_SEPARATOR, + \T_TYPE_UNION => \T_TYPE_UNION, ]; /** * DEPRECATED: Token types which can be encountered in a return type declaration. * * @since 1.0.0-alpha1 + * @since 1.0.0-alpha4 Added the T_TYPE_UNION, T_FALSE, T_NULL tokens for PHP 8.0 union type support. * - * @deprecated 1.0.0-alpha4 Use the {@see Collections::returnTypeTokens()} or - * {@see Collections::returnTypeTokensBC()} method instead. + * @deprecated 1.0.0-alpha4 Use the {@see Collections::returnTypeTokens()} method instead. * * @var array => */ public static $returnTypeTokens = [ - \T_STRING => \T_STRING, \T_CALLABLE => \T_CALLABLE, \T_SELF => \T_SELF, \T_PARENT => \T_PARENT, \T_STATIC => \T_STATIC, + \T_FALSE => \T_FALSE, + \T_NULL => \T_NULL, + \T_STRING => \T_STRING, \T_NS_SEPARATOR => \T_NS_SEPARATOR, + \T_TYPE_UNION => \T_TYPE_UNION, ]; /** @@ -487,6 +519,32 @@ class Collections \T_DOUBLE_QUOTED_STRING => \T_DOUBLE_QUOTED_STRING, ]; + /** + * Throw a deprecation notice with a standardized deprecation message. + * + * @since 1.0.0-alpha4 + * + * @param string $method The name of the method which is deprecated. + * @param string $version The version since which the method is deprecated. + * @param string $replacement What to use instead. + * + * @return void + */ + private static function triggerDeprecation($method, $version, $replacement) + { + \trigger_error( + \sprintf( + 'The %1$s::%2$s() method is deprecated since PHPCSUtils %3$s.' + . ' Use %4$s instead.', + __CLASS__, + $method, + $version, + $replacement + ), + \E_USER_DEPRECATED + ); + } + /** * Tokens for control structures which can use the alternative control structure syntax. * @@ -567,32 +625,19 @@ public static function arrayTokensBC() } /** - * Tokens which can represent the arrow function keyword. - * - * Note: this is a method, not a property as the `T_FN` token for arrow functions may not exist. - * - * @see \PHPCSUtils\Utils\FunctionDeclarations::isArrowFunction() Determine whether an arbitrary token - * is in actual fact an arrow function - * keyword. - * @see \PHPCSUtils\Utils\FunctionDeclarations::getArrowFunctionOpenClose() Get an arrow function's parentheses - * and scope openers and closers. + * DEPRECATED: Tokens which can represent the arrow function keyword. * * @since 1.0.0-alpha2 * + * @deprecated 1.0.0-alpha4 Use the `T_FN` token constant instead. + * * @return array => */ public static function arrowFunctionTokensBC() { - $tokens = [ - \T_STRING => \T_STRING, - ]; + self::triggerDeprecation(__FUNCTION__, '1.0.0-alpha4', 'the `T_FN` token'); - if (TokenHelper::tokenExists('T_FN') === true) { - // PHP 7.4 or PHPCS 3.5.3+. - $tokens[\T_FN] = \T_FN; - } - - return $tokens; + return [\T_FN => \T_FN]; } /** @@ -649,7 +694,7 @@ public static function controlStructureTokens() public static function functionCallTokens() { // Function calls and class instantiation. - $tokens = self::nameTokens(); + $tokens = self::$nameTokens; $tokens[\T_VARIABLE] = \T_VARIABLE; // Class instantiation only. @@ -662,69 +707,37 @@ public static function functionCallTokens() /** * Tokens which can represent a keyword which starts a function declaration. * - * Note: this is a method, not a property as the `T_FN` token for arrow functions may not exist. - * - * Sister-method to the {@see Collections::functionDeclarationTokensBC()} method. - * This method supports PHPCS 3.5.3 and up. - * The {@see Collections::functionDeclarationTokensBC()} method supports PHPCS 2.6.0 and up. - * - * @see \PHPCSUtils\Tokens\Collections::functionDeclarationTokensBC() Related method (PHPCS 2.6.0+). - * * @since 1.0.0-alpha3 * * @return array => */ public static function functionDeclarationTokens() { - $tokens = [ + return [ \T_FUNCTION => \T_FUNCTION, \T_CLOSURE => \T_CLOSURE, + \T_FN => \T_FN, ]; - - if (TokenHelper::tokenExists('T_FN') === true) { - // PHP 7.4 or PHPCS 3.5.3+. - $tokens[\T_FN] = \T_FN; - } - - return $tokens; } /** - * Tokens which can represent a keyword which starts a function declaration. - * - * Note: this is a method, not a property as the `T_FN` token for arrow functions may not exist. - * - * Sister-method to the {@see Collections::functionDeclarationTokens()} method. - * The {@see Collections::functionDeclarationTokens()} method supports PHPCS 3.5.3 and up. - * This method supports PHPCS 2.6.0 and up. - * - * Notable difference: - * - This method accounts for when the `T_FN` token doesn't exist. - * - * Note: if this method is used, the {@see \PHPCSUtils\Utils\FunctionDeclarations::isArrowFunction()} - * method needs to be used on arrow function tokens to verify whether it really is an arrow function - * declaration or not. - * - * It is recommended to use the {@see Collections::functionDeclarationTokens()} method instead of - * this method if a standard does not need to support PHPCS < 3.5.3. - * - * @see \PHPCSUtils\Tokens\Collections::functionDeclarationTokens() Related method (PHPCS 3.5.3+). - * @see \PHPCSUtils\Utils\FunctionDeclarations::isArrowFunction() Arrow function verification. + * DEPRECATED: Tokens which represent a keyword which starts a function declaration. * * @since 1.0.0-alpha3 * + * @deprecated 1.0.0-alpha4 Use the {@see Collections::functionDeclarationTokens()} method instead. + * * @return array => */ public static function functionDeclarationTokensBC() { - $tokens = [ - \T_FUNCTION => \T_FUNCTION, - \T_CLOSURE => \T_CLOSURE, - ]; - - $tokens += self::arrowFunctionTokensBC(); + self::triggerDeprecation( + __FUNCTION__, + '1.0.0-alpha4', + \sprintf('the %s::functionDeclarationTokens() method', __CLASS__) + ); - return $tokens; + return self::functionDeclarationTokens(); } /** @@ -805,7 +818,7 @@ public static function namespacedNameTokens() \T_NAMESPACE => \T_NAMESPACE, ]; - $tokens += self::nameTokens(); + $tokens += self::$nameTokens; return $tokens; } @@ -813,9 +826,11 @@ public static function namespacedNameTokens() /** * The tokens used for "names", be it namespace, OO, function or constant names. * - * Includes the tokens introduced in PHP 8.0 for "Namespaced names as single token" when available. + * Includes the tokens introduced in PHP 8.0 for "Namespaced names as single token". * - * Note: this is a method, not a property as the PHP 8.0 identifier name tokens may not exist. + * Note: the PHP 8.0 namespaced name tokens are backfilled in PHPCS since PHPCS 3.5.7, + * but are not used yet (the PHP 8.0 tokenization is "undone" in PHPCS). + * As of PHPCS 4.0.0, these tokens _will_ be used and the PHP 8.0 tokenization is respected. * * @link https://wiki.php.net/rfc/namespaced_names_as_token * @@ -825,141 +840,20 @@ public static function namespacedNameTokens() */ public static function nameTokens() { - $tokens = [ - \T_STRING => \T_STRING, - ]; - - /* - * PHP >= 8.0 in combination with PHPCS < 3.5.7 and all PHP versions in combination - * with PHPCS >= 3.5.7, though when using PHPCS 3.5.7 < 4.0.0, these tokens are - * not yet in use, i.e. the PHP 8.0 change is "undone" for PHPCS 3.x. - */ - if (TokenHelper::tokenExists('T_NAME_QUALIFIED') === true) { - $tokens[\T_NAME_QUALIFIED] = \T_NAME_QUALIFIED; - } - - if (TokenHelper::tokenExists('T_NAME_FULLY_QUALIFIED') === true) { - $tokens[\T_NAME_FULLY_QUALIFIED] = \T_NAME_FULLY_QUALIFIED; - } - - if (TokenHelper::tokenExists('T_NAME_RELATIVE') === true) { - $tokens[\T_NAME_RELATIVE] = \T_NAME_RELATIVE; - } - - return $tokens; - } - - /** - * Tokens which can represent the nullsafe object operator. - * - * This method will return the appropriate tokens based on the PHP/PHPCS version used. - * - * Note: this is a method, not a property as the `T_NULLSAFE_OBJECT_OPERATOR` token may not exist. - * - * Note: if this method is used, the {@see \PHPCSUtils\Utils\Operators::isNullsafeObjectOperator()} - * method needs to be used on potential nullsafe object operator tokens to verify whether it really - * is a nullsafe object operator or not. - * - * @see \PHPCSUtils\Utils\Operators::isNullsafeObjectOperator() Nullsafe object operator detection for - * PHPCS < 3.5.7. - * - * @since 1.0.0-alpha4 - * - * @return array => - */ - public static function nullsafeObjectOperatorBC() - { - if (TokenHelper::tokenExists('T_NULLSAFE_OBJECT_OPERATOR') === true) { - // PHP >= 8.0 / PHPCS >= 3.5.7. - return [ - \T_NULLSAFE_OBJECT_OPERATOR => \T_NULLSAFE_OBJECT_OPERATOR, - ]; - } - - return [ - \T_INLINE_THEN => \T_INLINE_THEN, - \T_OBJECT_OPERATOR => \T_OBJECT_OPERATOR, - ]; + return self::$nameTokens; } /** * Object operators. * - * Note: this is a method, not a property as the `T_NULLSAFE_OBJECT_OPERATOR` token may not exist. - * - * Sister-method to the {@see Collections::objectOperatorsBC()} method. - * This method supports PHPCS 3.5.7 and up. - * The {@see Collections::objectOperatorsBC()} method supports PHPCS 2.6.0 and up. - * - * This method can also safely be used if the token collection is only used when looking back - * via `$phpcsFile->findPrevious()` as in that case, a non-backfilled nullsafe object operator - * will still match the "normal" object operator. - * - * @see \PHPCSUtils\Tokens\Collections::objectOperatorsBC() Related method (PHPCS 2.6.0+). - * * @since 1.0.0-alpha4 This method replaces the {@see Collections::$objectOperators} property. + * @since 1.0.0-alpha4 Added the PHP 8.0 T_NULLSAFE_OBJECT_OPERATOR token. * * @return array => */ public static function objectOperators() { - $tokens = [ - \T_OBJECT_OPERATOR => \T_OBJECT_OPERATOR, - \T_DOUBLE_COLON => \T_DOUBLE_COLON, - ]; - - if (TokenHelper::tokenExists('T_NULLSAFE_OBJECT_OPERATOR') === true) { - // PHP >= 8.0 or PHPCS >= 3.5.7. - $tokens[\T_NULLSAFE_OBJECT_OPERATOR] = \T_NULLSAFE_OBJECT_OPERATOR; - } - - return $tokens; - } - - /** - * Object operators. - * - * Note: this is a method, not a property as the `T_NULLSAFE_OBJECT_OPERATOR` token may not exist. - * - * Sister-method to the {@see Collections::objectOperators()} method. - * The {@see Collections::objectOperators()} method supports PHPCS 3.5.7 and up. - * This method supports PHPCS 2.6.0 and up. - * - * Notable difference: - * - This method accounts for tokens which may be encountered when the `T_NULLSAFE_OBJECT_OPERATOR` token - * doesn't exist. - * - * It is recommended to use the {@see Collections::objectOperators()} method instead of - * this method if a standard does not need to support PHPCS < 3.5.7. - * - * The {@see Collections::objectOperators()} method can also safely be used if the token collection - * is only used when looking back via `$phpcsFile->findPrevious()` as in that case, a non-backfilled - * nullsafe object operator will still match the "normal" object operator. - * - * Note: if this method is used, the {@see \PHPCSUtils\Utils\Operators::isNullsafeObjectOperator()} - * method needs to be used on potential nullsafe object operator tokens to verify whether it really - * is a nullsafe object operator or not. - * - * @see \PHPCSUtils\Tokens\Collections::objectOperators() Related method (PHPCS 3.5.7+). - * @see \PHPCSUtils\Tokens\Collections::nullsafeObjectOperatorBC() Tokens which can represent a - * nullsafe object operator. - * @see \PHPCSUtils\Utils\Operators::isNullsafeObjectOperator() Nullsafe object operator detection for - * PHPCS < 3.5.7. - * - * @since 1.0.0-alpha4 - * - * @return array => - */ - public static function objectOperatorsBC() - { - $tokens = [ - \T_OBJECT_OPERATOR => \T_OBJECT_OPERATOR, - \T_DOUBLE_COLON => \T_DOUBLE_COLON, - ]; - - $tokens += self::nullsafeObjectOperatorBC(); - - return $tokens; + return self::$objectOperators; } /** @@ -1055,82 +949,40 @@ public static function parameterPassingTokens() /** * Token types which can be encountered in a parameter type declaration. * - * Note: this is a method, not a property as the `T_TYPE_UNION` token for PHP 8.0 union types may not exist. - * - * Sister-method to the {@see Collections::parameterTypeTokensBC()} method. - * This method supports PHPCS 3.3.0 and up. - * The {@see Collections::parameterTypeTokensBC()} method supports PHPCS 2.6.0 and up. - * - * Notable difference: - * - The {@see Collections::parameterTypeTokensBC()} method will include the `T_ARRAY_HINT` token - * when used with PHPCS 2.x and 3.x. - * This token constant will no longer exist in PHPCS 4.x. - * - * It is recommended to use this method instead of the {@see Collections::parameterTypeTokensBC()} - * method if a standard does not need to support PHPCS < 3.3.0. - * - * @see \PHPCSUtils\Tokens\Collections::parameterTypeTokensBC() Related method (cross-version). - * * @since 1.0.0-alpha4 This method replaces the {@see Collections::$parameterTypeTokens} property. - * @since 1.0.0-alpha4 Added support for PHP 8.0 union types. + * @since 1.0.0-alpha4 Added the T_TYPE_UNION, T_FALSE, T_NULL tokens for PHP 8.0 union type support. * @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokens. - * @since 1.0.0-alpha4 Added the T_TYPE_UNION token for union type support in PHPCS > 3.6.0. * * @return array => */ public static function parameterTypeTokens() { - $tokens = [ - \T_CALLABLE => \T_CALLABLE, - \T_SELF => \T_SELF, - \T_PARENT => \T_PARENT, - \T_FALSE => \T_FALSE, // Union types only. - \T_NULL => \T_NULL, // Union types only. - \T_BITWISE_OR => \T_BITWISE_OR, // Union types for PHPCS < 3.6.0. - ]; - + $tokens = self::$parameterTypeTokens; $tokens += self::namespacedNameTokens(); - // PHPCS > 3.6.0: a new token was introduced for the union type separator. - if (\defined('T_TYPE_UNION') === true) { - $tokens[\T_TYPE_UNION] = \T_TYPE_UNION; - } - return $tokens; } /** - * Token types which can be encountered in a parameter type declaration (cross-version). - * - * Sister-method to the {@see Collections::parameterTypeTokens()} method. - * The {@see Collections::parameterTypeTokens()} method supports PHPCS 3.3.0 and up. - * This method supports PHPCS 2.6.0 and up. - * - * Notable difference: - * - This method will include the `T_ARRAY_HINT` token when used with PHPCS 2.x and 3.x. - * This token constant will no longer exist in PHPCS 4.x. - * - * It is recommended to use {@see Collections::parameterTypeTokens()} method instead of - * this method if a standard does not need to support PHPCS < 3.3.0. + * DEPRECATED: Token types which can be encountered in a parameter type declaration (cross-version). * * @see \PHPCSUtils\Tokens\Collections::parameterTypeTokens() Related method (PHPCS 3.3.0+). * * @since 1.0.0-alpha3 - * @since 1.0.0-alpha4 Added support for PHP 8.0 union types. - * @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokens. + * + * @deprecated 1.0.0-alpha4 Use the {@see Collections::parameterTypeTokens()} method instead. * * @return array => */ public static function parameterTypeTokensBC() { - $tokens = self::parameterTypeTokens(); + self::triggerDeprecation( + __FUNCTION__, + '1.0.0-alpha4', + \sprintf('the %s::parameterTypeTokens() method', __CLASS__) + ); - // PHPCS < 4.0; Needed for support of PHPCS < 3.3.0. As of PHPCS 3.3.0+ the constant is no longer used. - if (\defined('T_ARRAY_HINT') === true) { - $tokens[\T_ARRAY_HINT] = \T_ARRAY_HINT; - } - - return $tokens; + return self::parameterTypeTokens(); } /** @@ -1163,175 +1015,80 @@ public static function propertyModifierKeywords() /** * Token types which can be encountered in a property type declaration. * - * Note: this is a method, not a property as the `T_TYPE_UNION` token for PHP 8.0 union types may not exist. - * - * Sister-method to the {@see Collections::propertyTypeTokensBC()} method. - * This method supports PHPCS 3.3.0 and up. - * The {@see Collections::propertyTypeTokensBC()} method supports PHPCS 2.6.0 and up. - * - * Notable difference: - * - The {@see Collections::propertyTypeTokensBC()} method will include the `T_ARRAY_HINT` token - * when used with PHPCS 2.x and 3.x. - * This token constant will no longer exist in PHPCS 4.x. - * - * It is recommended to use this method instead of the {@see Collections::propertyTypeTokensBC()} - * method if a standard does not need to support PHPCS < 3.3.0. - * - * @see \PHPCSUtils\Tokens\Collections::propertyTypeTokensBC() Related method (cross-version). - * * @since 1.0.0-alpha4 This method replaces the {@see Collections::$propertyTypeTokens} property. - * @since 1.0.0-alpha4 Added support for PHP 8.0 union types. + * @since 1.0.0-alpha4 Added the T_TYPE_UNION, T_FALSE, T_NULL tokens for PHP 8.0 union type support. * @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokens. - * @since 1.0.0-alpha4 Added the T_TYPE_UNION token for union type support in PHPCS > 3.6.0. * * @return array => */ public static function propertyTypeTokens() { - $tokens = [ - \T_CALLABLE => \T_CALLABLE, - \T_SELF => \T_SELF, - \T_PARENT => \T_PARENT, - \T_FALSE => \T_FALSE, // Union types only. - \T_NULL => \T_NULL, // Union types only. - \T_BITWISE_OR => \T_BITWISE_OR, // Union types for PHPCS < 3.6.0. - ]; - + $tokens = self::$propertyTypeTokens; $tokens += self::namespacedNameTokens(); - // PHPCS > 3.6.0: a new token was introduced for the union type separator. - if (\defined('T_TYPE_UNION') === true) { - $tokens[\T_TYPE_UNION] = \T_TYPE_UNION; - } - return $tokens; } /** - * Token types which can be encountered in a property type declaration (cross-version). - * - * Sister-method to the {@see Collections::propertyTypeTokens()} method. - * The {@see Collections::propertyTypeTokens()} method supports PHPCS 3.3.0 and up. - * This method supports PHPCS 2.6.0 and up. - * - * Notable difference: - * - This method will include the `T_ARRAY_HINT` token when used with PHPCS 2.x and 3.x. - * This token constant will no longer exist in PHPCS 4.x. - * - * It is recommended to use the {@see Collections::propertyTypeTokens()} method instead of - * this method if a standard does not need to support PHPCS < 3.3.0. + * DEPRECATED: Token types which can be encountered in a property type declaration (cross-version). * * @see \PHPCSUtils\Tokens\Collections::propertyTypeTokens() Related method (PHPCS 3.3.0+). * * @since 1.0.0-alpha3 - * @since 1.0.0-alpha4 Added support for PHP 8.0 union types. - * @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokens. + * + * @deprecated 1.0.0-alpha4 Use the {@see Collections::propertyTypeTokens()} method instead. * * @return array => */ public static function propertyTypeTokensBC() { - $tokens = self::propertyTypeTokens(); - - // PHPCS < 4.0; Needed for support of PHPCS < 3.3.0. For PHPCS 3.3.0+ the constant is no longer used. - if (\defined('T_ARRAY_HINT') === true) { - $tokens[\T_ARRAY_HINT] = \T_ARRAY_HINT; - } + self::triggerDeprecation( + __FUNCTION__, + '1.0.0-alpha4', + \sprintf('the %s::propertyTypeTokens() method', __CLASS__) + ); - return $tokens; + return self::propertyTypeTokens(); } /** * Token types which can be encountered in a return type declaration. * - * Note: this is a method, not a property as the `T_TYPE_UNION` token for PHP 8.0 union types may not exist. - * - * Sister-method to the {@see Collections::returnTypeTokensBC()} method. - * This method supports PHPCS 3.3.0 and up. - * The {@see Collections::returnTypeTokensBC()} method supports PHPCS 2.6.0 and up. - * - * Notable differences: - * - The {@see Collections::returnTypeTokensBC()} method will include the `T_ARRAY_HINT` - * and the `T_RETURN_TYPE` tokens when used with PHPCS 2.x and 3.x. - * These token constants will no longer exist in PHPCS 4.x. - * - * It is recommended to use this method instead of the {@see Collections::returnTypeTokensBC()} - * method if a standard does not need to support PHPCS < 3.3.0. - * - * @see \PHPCSUtils\Tokens\Collections::returnTypeTokensBC() Related method (cross-version). - * * @since 1.0.0-alpha4 This method replaces the {@see Collections::$returnTypeTokens} property. - * @since 1.0.0-alpha4 Added support for PHP 8.0 union types. + * @since 1.0.0-alpha4 Added the T_TYPE_UNION, T_FALSE, T_NULL tokens for PHP 8.0 union type support. * @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokens. - * @since 1.0.0-alpha4 Added the T_TYPE_UNION token for union type support in PHPCS > 3.6.0. * * @return array => */ public static function returnTypeTokens() { - $tokens = [ - \T_CALLABLE => \T_CALLABLE, - \T_FALSE => \T_FALSE, // Union types only. - \T_NULL => \T_NULL, // Union types only. - \T_ARRAY => \T_ARRAY, // Arrow functions PHPCS < 3.5.4 + union types. - \T_BITWISE_OR => \T_BITWISE_OR, // Union types for PHPCS < 3.6.0. - ]; - + $tokens = self::$returnTypeTokens; $tokens += self::ooHierarchyKeywords(); $tokens += self::namespacedNameTokens(); - // PHPCS > 3.6.0: a new token was introduced for the union type separator. - if (\defined('T_TYPE_UNION') === true) { - $tokens[\T_TYPE_UNION] = \T_TYPE_UNION; - } - return $tokens; } /** - * Token types which can be encountered in a return type declaration (cross-version). - * - * Sister-method to the {@see Collections::returnTypeTokens()} method. - * The {@see Collections::returnTypeTokens()} method supports PHPCS 3.3.0 and up. - * This method supports PHPCS 2.6.0 and up. - * - * Notable differences: - * - This method will include the `T_ARRAY_HINT` and the `T_RETURN_TYPE` tokens when - * used with PHPCS 2.x and 3.x. - * These token constants will no longer exist in PHPCS 4.x. - * - * It is recommended to use the {@see Collections::returnTypeTokens()} method instead of - * this method if a standard does not need to support PHPCS < 3.3.0. + * DEPRECATED: Token types which can be encountered in a return type declaration (cross-version). * * @see \PHPCSUtils\Tokens\Collections::returnTypeTokens() Related method (PHPCS 3.3.0+). * * @since 1.0.0-alpha3 - * @since 1.0.0-alpha4 Added support for PHP 8.0 union types. - * @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokens. + * + * @deprecated 1.0.0-alpha4 Use the {@see Collections::returnTypeTokens()} method instead. * * @return array => */ public static function returnTypeTokensBC() { - $tokens = self::returnTypeTokens(); - - /* - * PHPCS < 4.0. Needed for support of PHPCS 2.4.0 < 3.3.0. - * For PHPCS 3.3.0+ the constant is no longer used. - */ - if (\defined('T_RETURN_TYPE') === true) { - $tokens[\T_RETURN_TYPE] = \T_RETURN_TYPE; - } - - /* - * PHPCS < 4.0. Needed for support of PHPCS < 2.8.0 / PHPCS < 3.5.3 for arrow functions. - * For PHPCS 3.5.3+ the constant is no longer used. - */ - if (\defined('T_ARRAY_HINT') === true) { - $tokens[\T_ARRAY_HINT] = \T_ARRAY_HINT; - } + self::triggerDeprecation( + __FUNCTION__, + '1.0.0-alpha4', + \sprintf('the %s::returnTypeTokens() method', __CLASS__) + ); - return $tokens; + return self::returnTypeTokens(); } /** diff --git a/PHPCSUtils/Utils/Arrays.php b/PHPCSUtils/Utils/Arrays.php index 859811c0..fb47b48e 100644 --- a/PHPCSUtils/Utils/Arrays.php +++ b/PHPCSUtils/Utils/Arrays.php @@ -13,17 +13,16 @@ use PHP_CodeSniffer\Exceptions\RuntimeException; use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; -use PHPCSUtils\BackCompat\BCTokens; use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Internal\Cache; use PHPCSUtils\Tokens\Collections; -use PHPCSUtils\Utils\FunctionDeclarations; use PHPCSUtils\Utils\Lists; /** * Utility functions for use when examining arrays. * * @since 1.0.0 + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. */ class Arrays { @@ -31,18 +30,19 @@ class Arrays /** * The tokens to target to find the double arrow in an array item. * - * Note: this array does not contain the `T_FN` token as it may or may not exist. - * If it exists, it will be added in the `getDoubleArrowPtr()` function. - * * @since 1.0.0 * * @var array => */ private static $doubleArrowTargets = [ \T_DOUBLE_ARROW => \T_DOUBLE_ARROW, + + // Nested arrays. \T_ARRAY => \T_ARRAY, \T_OPEN_SHORT_ARRAY => \T_OPEN_SHORT_ARRAY, - \T_STRING => \T_STRING, // BC for T_FN token in PHPCS < 3.5.3 icw PHP < 7.4. + + // Inline function and control structures to skip over. + \T_FN => \T_FN, ]; /** @@ -171,7 +171,7 @@ public static function isShortArray(File $phpcsFile, $stackPtr) * * @link https://github.com/squizlabs/PHP_CodeSniffer/pull/3013 */ - if (isset(BCTokens::magicConstants()[$tokens[$prevNonEmpty]['code']]) === true) { + if (isset(Tokens::$magicConstants[$tokens[$prevNonEmpty]['code']]) === true) { Cache::set($phpcsFile, __METHOD__, $stackPtr, false); return false; } @@ -322,7 +322,6 @@ public static function getDoubleArrowPtr(File $phpcsFile, $start, $end) $targets = self::$doubleArrowTargets; $targets += Collections::closedScopes(); - $targets += Collections::arrowFunctionTokensBC(); $doubleArrow = ($start - 1); $returnValue = false; @@ -343,33 +342,16 @@ public static function getDoubleArrowPtr(File $phpcsFile, $start, $end) break; } - /* - * BC: work-around a bug in PHPCS 3.5.4 where the double arrow is incorrectly tokenized as T_STRING. - * - * @link https://github.com/squizlabs/PHP_CodeSniffer/issues/2865 - */ - if ($tokens[$doubleArrow]['code'] === \T_STRING && $tokens[$doubleArrow]['content'] === '=>') { - $returnValue = $doubleArrow; - break; - } - // Skip over closed scopes which may contain foreach structures or generators. - if (isset(Collections::closedScopes()[$tokens[$doubleArrow]['code']]) === true + if ((isset(Collections::closedScopes()[$tokens[$doubleArrow]['code']]) === true + || $tokens[$doubleArrow]['code'] === \T_FN) && isset($tokens[$doubleArrow]['scope_closer']) === true ) { $doubleArrow = $tokens[$doubleArrow]['scope_closer']; continue; } - // BC for PHP 7.4 arrow functions with PHPCS < 3.5.3. - if (isset(Collections::arrowFunctionTokensBC()[$tokens[$doubleArrow]['code']]) === true - && FunctionDeclarations::isArrowFunction($phpcsFile, $doubleArrow) === false - ) { - // Not an arrow function, continue looking. - continue; - } - - // Start of nested long/short array or arrow function. + // Start of nested long/short array. break; } while ($doubleArrow < $end); diff --git a/PHPCSUtils/Utils/ControlStructures.php b/PHPCSUtils/Utils/ControlStructures.php index d7594506..f351ed83 100644 --- a/PHPCSUtils/Utils/ControlStructures.php +++ b/PHPCSUtils/Utils/ControlStructures.php @@ -13,13 +13,13 @@ use PHP_CodeSniffer\Exceptions\RuntimeException; use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; -use PHPCSUtils\Internal\Cache; use PHPCSUtils\Tokens\Collections; /** * Utility functions for use when examining control structures. * * @since 1.0.0 + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. */ class ControlStructures { @@ -67,16 +67,6 @@ public static function hasBody(File $phpcsFile, $stackPtr, $allowEmpty = true) } } - // Deal with declare alternative syntax without scope opener. - if ($tokens[$stackPtr]['code'] === \T_DECLARE && isset($tokens[$stackPtr]['scope_opener']) === false) { - $declareOpenClose = self::getDeclareScopeOpenClose($phpcsFile, $stackPtr); - if ($declareOpenClose !== false) { - // Set the opener + closer in the tokens array. This will only affect our local copy. - $tokens[$stackPtr]['scope_opener'] = $declareOpenClose['opener']; - $tokens[$stackPtr]['scope_closer'] = $declareOpenClose['closer']; - } - } - /* * The scope markers are set. This is the simplest situation. */ @@ -210,15 +200,12 @@ public static function isElseIf(File $phpcsFile, $stackPtr) * In the first case, the statement - correctly - won't have a scope opener/closer. * In the second case, the statement will have the scope opener/closer indexes. * In the last case, due to a bug in the PHPCS Tokenizer, it won't have the scope opener/closer indexes, - * while it really should. This bug is fixed in PHPCS 3.5.4. - * - * In other words, if a sniff needs to support PHPCS < 3.5.4 and needs to take the alternative - * control structure syntax into account, this method can be used to retrieve the - * scope opener/closer for the declare statement. + * while it really should. This bug was fixed in PHPCS 3.5.4. * * @link https://github.com/squizlabs/PHP_CodeSniffer/pull/2843 PHPCS PR #2843 * - * @since 1.0.0 + * @since 1.0.0 + * @deprecated 1.0.0-alpha4 Check the scope_opener/scope_closer instead. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position of the token we are checking. @@ -235,6 +222,15 @@ public static function isElseIf(File $phpcsFile, $stackPtr) */ public static function getDeclareScopeOpenClose(File $phpcsFile, $stackPtr) { + \trigger_error( + \sprintf( + 'The %s() function is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Check for the "scope_opener"/"scope_closer" keys instead.', + __METHOD__ + ), + \E_USER_DEPRECATED + ); + $tokens = $phpcsFile->getTokens(); if (isset($tokens[$stackPtr]) === false @@ -250,107 +246,7 @@ public static function getDeclareScopeOpenClose(File $phpcsFile, $stackPtr) ]; } - if (Cache::isCached($phpcsFile, __METHOD__, $stackPtr) === true) { - return Cache::get($phpcsFile, __METHOD__, $stackPtr); - } - - $declareCount = 0; - $opener = null; - $closer = null; - $returnValue = false; - - for ($i = $stackPtr; $i < $phpcsFile->numTokens; $i++) { - if ($tokens[$i]['code'] !== \T_DECLARE && $tokens[$i]['code'] !== \T_ENDDECLARE) { - continue; - } - - if ($tokens[$i]['code'] === \T_ENDDECLARE) { - --$declareCount; - - if ($declareCount !== 0) { - continue; - } - - // OK, we reached the target enddeclare. - $closer = $i; - break; - } - - if ($tokens[$i]['code'] === \T_DECLARE) { - ++$declareCount; - - // Find the scope opener - if (isset($tokens[$i]['parenthesis_closer']) === false) { - // Parse error or live coding, nothing to do. - break; - } - - $scopeOpener = $phpcsFile->findNext( - Tokens::$emptyTokens, - ($tokens[$i]['parenthesis_closer'] + 1), - null, - true - ); - - if ($scopeOpener === false) { - // Live coding, nothing to do. - break; - } - - // Remember the scope opener for our target declare. - if ($declareCount === 1) { - $opener = $scopeOpener; - } - - $i = $scopeOpener; - - switch ($tokens[$scopeOpener]['code']) { - case \T_COLON: - // Nothing particular to do. Just continue the loop. - break; - - case \T_OPEN_CURLY_BRACKET: - /* - * Live coding or nested declare statement with curlies. - */ - - if (isset($tokens[$scopeOpener]['scope_closer']) === false) { - // Live coding, nothing to do. - break 2; - } - - // Jump over the statement. - $i = $tokens[$scopeOpener]['scope_closer']; - --$declareCount; - - break; - - case \T_SEMICOLON: - case \T_CLOSE_TAG: - // Nested single line declare statement. - --$declareCount; - break; - - default: - // This is an unexpected token. Most likely a parse error. Bow out. - break 2; - } - } - - if ($declareCount === 0) { - break; - } - } - - if (isset($opener, $closer)) { - $returnValue = [ - 'opener' => $opener, - 'closer' => $closer, - ]; - } - - Cache::set($phpcsFile, __METHOD__, $stackPtr, $returnValue); - return $returnValue; + return false; } /** diff --git a/PHPCSUtils/Utils/FunctionDeclarations.php b/PHPCSUtils/Utils/FunctionDeclarations.php index 51611a70..0ad5247d 100644 --- a/PHPCSUtils/Utils/FunctionDeclarations.php +++ b/PHPCSUtils/Utils/FunctionDeclarations.php @@ -13,9 +13,6 @@ use PHP_CodeSniffer\Exceptions\RuntimeException; use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; -use PHPCSUtils\BackCompat\BCTokens; -use PHPCSUtils\BackCompat\Helper; -use PHPCSUtils\Internal\Cache; use PHPCSUtils\Tokens\Collections; use PHPCSUtils\Utils\GetTokensAsString; use PHPCSUtils\Utils\ObjectDeclarations; @@ -25,12 +22,13 @@ /** * Utility functions for use when examining function declaration statements. * - * @since 1.0.0 The `FunctionDeclarations::getProperties()` and the - * `FunctionDeclarations::getParameters()` methods are based on and - * inspired by respectively the `getMethodProperties()` - * and `getMethodParameters()` methods in the PHPCS native - * `PHP_CodeSniffer\Files\File` class. - * Also see {@see \PHPCSUtils\BackCompat\BCFile}. + * @since 1.0.0 The `FunctionDeclarations::getProperties()` and the + * `FunctionDeclarations::getParameters()` methods are based on and + * inspired by respectively the `getMethodProperties()` + * and `getMethodParameters()` methods in the PHPCS native + * `PHP_CodeSniffer\Files\File` class. + * Also see {@see \PHPCSUtils\BackCompat\BCFile}. + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. */ class FunctionDeclarations { @@ -113,25 +111,6 @@ class FunctionDeclarations '__soapcall' => 'SOAPClient', ]; - /** - * Tokens which can be the end token of an arrow function. - * - * @since 1.0.0 - * - * @var array => - */ - private static $arrowFunctionEndTokens = [ - \T_COLON => true, - \T_COMMA => true, - \T_SEMICOLON => true, - \T_CLOSE_PARENTHESIS => true, - \T_CLOSE_SQUARE_BRACKET => true, - \T_CLOSE_CURLY_BRACKET => true, - \T_CLOSE_SHORT_ARRAY => true, - \T_OPEN_TAG => true, - \T_CLOSE_TAG => true, - ]; - /** * Returns the declaration name for a function. * @@ -168,15 +147,13 @@ public static function getName(File $phpcsFile, $stackPtr) * parse errors or live coding. * - Defensive coding against incorrect calls to this method. * - More efficient checking whether a function has a body. - * - To allow for backward compatible handling of arrow functions, this method will also accept - * `T_STRING` tokens and examine them to check if these are arrow functions. * - Support for PHP 8.0 identifier name tokens in return types, cross-version PHP & PHPCS. * * @see \PHP_CodeSniffer\Files\File::getMethodProperties() Original source. * @see \PHPCSUtils\BackCompat\BCFile::getMethodProperties() Cross-version compatible version of the original. * * @since 1.0.0 - * @since 1.0.0-alpha2 Added BC support for PHP 7.4 arrow functions. + * @since 1.0.0-alpha2 Added support for PHP 7.4 arrow functions. * @since 1.0.0-alpha3 Added support for PHP 8.0 static return type. * @since 1.0.0-alpha4 Added support for PHP 8.0 union types. * @@ -209,13 +186,10 @@ public static function getName(File $phpcsFile, $stackPtr) */ public static function getProperties(File $phpcsFile, $stackPtr) { - $tokens = $phpcsFile->getTokens(); - $arrowOpenClose = self::getArrowFunctionOpenClose($phpcsFile, $stackPtr); + $tokens = $phpcsFile->getTokens(); if (isset($tokens[$stackPtr]) === false - || ($tokens[$stackPtr]['code'] !== \T_FUNCTION - && $tokens[$stackPtr]['code'] !== \T_CLOSURE - && $arrowOpenClose === false) + || isset(Collections::functionDeclarationTokens()[$tokens[$stackPtr]['code']]) === false ) { throw new RuntimeException('$stackPtr must be of type T_FUNCTION or T_CLOSURE or an arrow function'); } @@ -269,23 +243,17 @@ public static function getProperties(File $phpcsFile, $stackPtr) $returnTypeEndToken = false; $nullableReturnType = false; $hasBody = false; - $returnTypeTokens = Collections::returnTypeTokensBC(); + $returnTypeTokens = Collections::returnTypeTokens(); $parenthesisCloser = null; if (isset($tokens[$stackPtr]['parenthesis_closer']) === true) { $parenthesisCloser = $tokens[$stackPtr]['parenthesis_closer']; - } elseif ($arrowOpenClose !== false) { - // Arrow function in combination with PHP < 7.4 or PHPCS < 3.5.3. - $parenthesisCloser = $arrowOpenClose['parenthesis_closer']; } if (isset($parenthesisCloser) === true) { $scopeOpener = null; if (isset($tokens[$stackPtr]['scope_opener']) === true) { $scopeOpener = $tokens[$stackPtr]['scope_opener']; - } elseif ($arrowOpenClose !== false) { - // Arrow function in combination with PHP < 7.4 or PHPCS < 3.5.3. - $scopeOpener = $arrowOpenClose['scope_opener']; } for ($i = $parenthesisCloser; $i < $phpcsFile->numTokens; $i++) { @@ -300,23 +268,7 @@ public static function getProperties(File $phpcsFile, $stackPtr) break; } - /* - * Work-around for a scope map tokenizer bug in PHPCS. - * {@link https://github.com/squizlabs/PHP_CodeSniffer/pull/3066} - */ - if ($scopeOpener === null && $tokens[$i]['code'] === \T_OPEN_CURLY_BRACKET) { - // End of function definition for which the scope opener is incorrectly not set. - $hasBody = true; - break; - } - - if ($tokens[$i]['type'] === 'T_NULLABLE' - // Handle nullable tokens in PHPCS < 2.8.0. - || (\defined('T_NULLABLE') === false && $tokens[$i]['code'] === \T_INLINE_THEN) - // Handle nullable tokens with arrow functions in PHPCS 2.8.0 - 2.9.0. - || ($arrowOpenClose !== false && $tokens[$i]['code'] === \T_INLINE_THEN - && \version_compare(Helper::getVersion(), '2.9.1', '<') === true) - ) { + if ($tokens[$i]['code'] === \T_NULLABLE) { $nullableReturnType = true; } @@ -397,15 +349,13 @@ public static function getProperties(File $phpcsFile, $stackPtr) * - More efficient and more stable checking whether a `T_USE` token is a closure use. * - More efficient and more stable looping of the default value. * - Clearer exception message when a non-closure use token was passed to the function. - * - To allow for backward compatible handling of arrow functions, this method will also accept - * `T_STRING` tokens and examine them to check if these are arrow functions. * - Support for PHP 8.0 identifier name tokens in parameter types, cross-version PHP & PHPCS. * * @see \PHP_CodeSniffer\Files\File::getMethodParameters() Original source. * @see \PHPCSUtils\BackCompat\BCFile::getMethodParameters() Cross-version compatible version of the original. * * @since 1.0.0 - * @since 1.0.0-alpha2 Added BC support for PHP 7.4 arrow functions. + * @since 1.0.0-alpha2 Added support for PHP 7.4 arrow functions. * @since 1.0.0-alpha4 Added support for PHP 8.0 union types. * @since 1.0.0-alpha4 Added support for PHP 8.0 constructor property promotion. * @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokenization. @@ -424,14 +374,11 @@ public static function getProperties(File $phpcsFile, $stackPtr) */ public static function getParameters(File $phpcsFile, $stackPtr) { - $tokens = $phpcsFile->getTokens(); - $arrowOpenClose = self::getArrowFunctionOpenClose($phpcsFile, $stackPtr); + $tokens = $phpcsFile->getTokens(); if (isset($tokens[$stackPtr]) === false - || ($tokens[$stackPtr]['code'] !== \T_FUNCTION - && $tokens[$stackPtr]['code'] !== \T_CLOSURE - && $tokens[$stackPtr]['code'] !== \T_USE - && $arrowOpenClose === false) + || (isset(Collections::functionDeclarationTokens()[$tokens[$stackPtr]['code']]) === false + && $tokens[$stackPtr]['code'] !== \T_USE) ) { throw new RuntimeException('$stackPtr must be of type T_FUNCTION, T_CLOSURE or T_USE or an arrow function'); } @@ -445,9 +392,6 @@ public static function getParameters(File $phpcsFile, $stackPtr) ) { throw new RuntimeException('$stackPtr was not a valid closure T_USE'); } - } elseif ($arrowOpenClose !== false) { - // Arrow function in combination with PHP < 7.4 or PHPCS < 3.5.3/4/5. - $opener = $arrowOpenClose['parenthesis_opener']; } else { if (isset($tokens[$stackPtr]['parenthesis_opener']) === false) { // Live coding or syntax error, so no params to find. @@ -481,60 +425,48 @@ public static function getParameters(File $phpcsFile, $stackPtr) $visibilityToken = null; for ($i = $paramStart; $i <= $closer; $i++) { - // Changed from checking 'code' to 'type' to allow for T_NULLABLE not existing in PHPCS < 2.8.0. - switch ($tokens[$i]['type']) { - case 'T_BITWISE_AND': + if (isset(Collections::parameterTypeTokens()[$tokens[$i]['code']]) === true + // Self and parent are valid, static invalid, but was probably intended as type declaration. + || $tokens[$i]['code'] === \T_STATIC + ) { + if ($typeHintToken === false) { + $typeHintToken = $i; + } + + $typeHint .= $tokens[$i]['content']; + $typeHintEndToken = $i; + continue; + } + + switch ($tokens[$i]['code']) { + case \T_BITWISE_AND: $passByReference = true; $referenceToken = $i; break; - case 'T_VARIABLE': + case \T_VARIABLE: $currVar = $i; break; - case 'T_ELLIPSIS': + case \T_ELLIPSIS: $variableLength = true; $variadicToken = $i; break; - case 'T_ARRAY_HINT': // PHPCS < 3.3.0. - case 'T_CALLABLE': - case 'T_SELF': - case 'T_PARENT': - case 'T_STATIC': // Self and parent are valid, static invalid, but was probably intended as type hint. - case 'T_FALSE': // Union types. - case 'T_NULL': // Union types. - case 'T_STRING': - case 'T_NAMESPACE': - case 'T_NS_SEPARATOR': - case 'T_NAME_QUALIFIED': - case 'T_NAME_FULLY_QUALIFIED': - case 'T_NAME_RELATIVE': - case 'T_BITWISE_OR': // Union type separator PHPCS < 3.6.0. - case 'T_TYPE_UNION': // Union type separator PHPCS >= 3.6.0. - if ($typeHintToken === false) { - $typeHintToken = $i; - } - - $typeHint .= $tokens[$i]['content']; - $typeHintEndToken = $i; - break; - - case 'T_NULLABLE': - case 'T_INLINE_THEN': // PHPCS < 2.8.0. + case \T_NULLABLE: $nullableType = true; $typeHint .= $tokens[$i]['content']; $typeHintEndToken = $i; break; - case 'T_PUBLIC': - case 'T_PROTECTED': - case 'T_PRIVATE': + case \T_PUBLIC: + case \T_PROTECTED: + case \T_PRIVATE: $visibilityToken = $i; break; - case 'T_CLOSE_PARENTHESIS': - case 'T_COMMA': + case \T_CLOSE_PARENTHESIS: + case \T_COMMA: // If it's null, then there must be no parameters for this // method. if ($currVar === null) { @@ -594,7 +526,7 @@ public static function getParameters(File $phpcsFile, $stackPtr) ++$paramCount; break; - case 'T_EQUAL': + case \T_EQUAL: $defaultStart = $phpcsFile->findNext(Tokens::$emptyTokens, ($i + 1), null, true); $equalToken = $i; @@ -635,26 +567,12 @@ public static function getParameters(File $phpcsFile, $stackPtr) * Check if an arbitrary token is the "fn" keyword for a PHP 7.4 arrow function. * * Helper function for cross-version compatibility with both PHP as well as PHPCS. - * - PHP 7.4+ will tokenize most tokens with the content "fn" as `T_FN`, even when it isn't an arrow function. - * - PHPCS < 3.5.3 will tokenize arrow functions keywords as `T_STRING`. - * - PHPCS 3.5.3/3.5.4 will tokenize the keyword differently depending on which PHP version is used - * and similar to PHP will tokenize most tokens with the content "fn" as `T_FN`, even when it's not an - * arrow function. - * > Note: the tokens tokenized by PHPCS 3.5.3 - 3.5.4 as `T_FN` are not 100% the same as those tokenized - * by PHP 7.4+ as `T_FN`. - * - * Either way, the `T_FN` token is not a reliable search vector for finding or examining - * arrow functions, at least not until PHPCS 3.5.5. - * This function solves that and will give reliable results in the same way as this is now - * solved in PHPCS 3.5.5. - * - * > Note: Bugs are still being found and reported about how PHPCS tokenizes the arrow functions. - * This method will keep up with upstream changes and backport them, in as far possible, to allow - * for sniffing arrow functions in PHPCS < current. + * As of PHPCS 3.5.6, this function is no longer be needed. * * @see \PHPCSUtils\Utils\FunctionDeclarations::getArrowFunctionOpenClose() Related function. * - * @since 1.0.0 + * @since 1.0.0 + * @deprecated 1.0.0-alpha4 Use the T_FN token constant instead. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. * @param int $stackPtr The token to check. Typically a T_FN or @@ -666,28 +584,25 @@ public static function getParameters(File $phpcsFile, $stackPtr) */ public static function isArrowFunction(File $phpcsFile, $stackPtr) { + \trigger_error( + \sprintf( + 'The %s() function is deprecated since PHPCSUtils 1.0.0-alpha4. Use the `T_FN` token instead.', + __METHOD__ + ), + \E_USER_DEPRECATED + ); + $tokens = $phpcsFile->getTokens(); if (isset($tokens[$stackPtr]) === false) { return false; } - if ($tokens[$stackPtr]['type'] === 'T_FN' + if ($tokens[$stackPtr]['code'] === \T_FN && isset($tokens[$stackPtr]['scope_closer']) === true ) { return true; } - if (isset(Collections::arrowFunctionTokensBC()[$tokens[$stackPtr]['code']]) === false - || \strtolower($tokens[$stackPtr]['content']) !== 'fn' - ) { - return false; - } - - $openClose = self::getArrowFunctionOpenClose($phpcsFile, $stackPtr); - if ($openClose !== false && isset($openClose['scope_closer'])) { - return true; - } - return false; } @@ -696,14 +611,12 @@ public static function isArrowFunction(File $phpcsFile, $stackPtr) * for an arrow function. * * Helper function for cross-version compatibility with both PHP as well as PHPCS. - * In PHPCS versions prior to PHPCS 3.5.3/3.5.4, the `T_FN` token is not yet backfilled - * and does not have parenthesis opener/closer nor scope opener/closer indexes assigned - * in the `$tokens` array. + * As of PHPCS 3.5.6, this function is no longer be needed. * * @see \PHPCSUtils\Utils\FunctionDeclarations::isArrowFunction() Related function. * - * @since 1.0.0 - * @since 1.0.0-alpha4 Handling of PHP 8.0 identifier name tokens in return types, cross-version PHP & PHPCS. + * @since 1.0.0 + * @deprecated 1.0.0-alpha4 Use the T_FN token constant instead. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. * @param int $stackPtr The token to retrieve the openers/closers for. @@ -723,19 +636,23 @@ public static function isArrowFunction(File $phpcsFile, $stackPtr) */ public static function getArrowFunctionOpenClose(File $phpcsFile, $stackPtr) { + \trigger_error( + \sprintf( + 'The %s() function is deprecated since PHPCSUtils 1.0.0-alpha4. Use the `T_FN` token instead.', + __METHOD__ + ), + \E_USER_DEPRECATED + ); + $tokens = $phpcsFile->getTokens(); if (isset($tokens[$stackPtr]) === false - || isset(Collections::arrowFunctionTokensBC()[$tokens[$stackPtr]['code']]) === false - || \strtolower($tokens[$stackPtr]['content']) !== 'fn' + || $tokens[$stackPtr]['code'] !== \T_FN ) { return false; } - if ($tokens[$stackPtr]['type'] === 'T_FN' - && isset($tokens[$stackPtr]['scope_closer']) === true - && \version_compare(Helper::getVersion(), '3.5.4', '>') === true - ) { + if (isset($tokens[$stackPtr]['scope_closer']) === true) { // The keys will either all be set or none will be set, so no additional checks needed. return [ 'parenthesis_opener' => $tokens[$stackPtr]['parenthesis_opener'], @@ -745,137 +662,7 @@ public static function getArrowFunctionOpenClose(File $phpcsFile, $stackPtr) ]; } - /* - * This is either a T_STRING token pre-PHP 7.4, or T_FN on PHP 7.4 in combination - * with PHPCS < 3.5.3/4/5. - * - * Now see about finding the relevant arrow function tokens. - */ - if (Cache::isCached($phpcsFile, __METHOD__, $stackPtr) === true) { - return Cache::get($phpcsFile, __METHOD__, $stackPtr); - } - - $returnValue = []; - - $nextNonEmpty = $phpcsFile->findNext( - (Tokens::$emptyTokens + [\T_BITWISE_AND]), - ($stackPtr + 1), - null, - true - ); - if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== \T_OPEN_PARENTHESIS) { - Cache::set($phpcsFile, __METHOD__, $stackPtr, false); - return false; - } - - $returnValue['parenthesis_opener'] = $nextNonEmpty; - if (isset($tokens[$nextNonEmpty]['parenthesis_closer']) === false) { - // Shouldn't be possible, but just in case. - // @codeCoverageIgnoreStart - Cache::set($phpcsFile, __METHOD__, $stackPtr, false); - return false; - // @codeCoverageIgnoreEnd - } - - $returnValue['parenthesis_closer'] = $tokens[$nextNonEmpty]['parenthesis_closer']; - - $ignore = Tokens::$emptyTokens; - $ignore += Collections::returnTypeTokensBC(); - $ignore[\T_COLON] = \T_COLON; - $ignore[\T_INLINE_ELSE] = \T_INLINE_ELSE; // Return type colon on PHPCS < 2.9.1. - $ignore[\T_INLINE_THEN] = \T_INLINE_THEN; // Nullable type indicator on PHPCS < 2.9.1. - - if (\defined('T_NULLABLE') === true) { - $ignore[\T_NULLABLE] = \T_NULLABLE; - } - - $arrow = $phpcsFile->findNext( - $ignore, - ($tokens[$nextNonEmpty]['parenthesis_closer'] + 1), - null, - true - ); - - if ($arrow === false - || ($tokens[$arrow]['code'] !== \T_DOUBLE_ARROW && $tokens[$arrow]['type'] !== 'T_FN_ARROW') - ) { - Cache::set($phpcsFile, __METHOD__, $stackPtr, false); - return false; - } - - $returnValue['scope_opener'] = $arrow; - $inTernary = false; - $lastEndToken = null; - - for ($scopeCloser = ($arrow + 1); $scopeCloser < $phpcsFile->numTokens; $scopeCloser++) { - if (isset(self::$arrowFunctionEndTokens[$tokens[$scopeCloser]['code']]) === true - // BC for misidentified ternary else in some PHPCS versions. - && ($tokens[$scopeCloser]['code'] !== \T_COLON || $inTernary === false) - ) { - if ($lastEndToken !== null - && $tokens[$scopeCloser]['code'] === \T_CLOSE_PARENTHESIS - && $tokens[$scopeCloser]['parenthesis_opener'] < $arrow - ) { - $scopeCloser = $lastEndToken; - } - - break; - } - - if (isset(Collections::arrowFunctionTokensBC()[$tokens[$scopeCloser]['code']]) === true) { - $nested = self::getArrowFunctionOpenClose($phpcsFile, $scopeCloser); - if ($nested !== false && isset($nested['scope_closer'])) { - // We minus 1 here in case the closer can be shared with us. - $scopeCloser = ($nested['scope_closer'] - 1); - continue; - } - } - - if (isset($tokens[$scopeCloser]['scope_closer']) === true - && $tokens[$scopeCloser]['code'] !== \T_INLINE_ELSE - && $tokens[$scopeCloser]['code'] !== \T_END_HEREDOC - && $tokens[$scopeCloser]['code'] !== \T_END_NOWDOC - ) { - // We minus 1 here in case the closer can be shared with us. - $scopeCloser = ($tokens[$scopeCloser]['scope_closer'] - 1); - continue; - } - - if (isset($tokens[$scopeCloser]['parenthesis_closer']) === true) { - $scopeCloser = $tokens[$scopeCloser]['parenthesis_closer']; - $lastEndToken = $scopeCloser; - continue; - } - - if (isset($tokens[$scopeCloser]['bracket_closer']) === true) { - $scopeCloser = $tokens[$scopeCloser]['bracket_closer']; - $lastEndToken = $scopeCloser; - continue; - } - - if ($tokens[$scopeCloser]['code'] === \T_INLINE_THEN) { - $inTernary = true; - continue; - } - - if ($tokens[$scopeCloser]['code'] === \T_INLINE_ELSE) { - if ($inTernary === false) { - break; - } - - $inTernary = false; - } - } - - if ($scopeCloser === $phpcsFile->numTokens) { - Cache::set($phpcsFile, __METHOD__, $stackPtr, false); - return false; - } - - $returnValue['scope_closer'] = $scopeCloser; - - Cache::set($phpcsFile, __METHOD__, $stackPtr, $returnValue); - return $returnValue; + return []; } /** @@ -992,7 +779,7 @@ public static function isPHPDoubleUnderscoreMethod(File $phpcsFile, $stackPtr) return false; } - $scopePtr = Scopes::validDirectScope($phpcsFile, $stackPtr, BCTokens::ooScopeTokens()); + $scopePtr = Scopes::validDirectScope($phpcsFile, $stackPtr, Tokens::$ooScopeTokens); if ($scopePtr === false) { return false; } diff --git a/PHPCSUtils/Utils/Lists.php b/PHPCSUtils/Utils/Lists.php index 4ebfa000..898434b1 100644 --- a/PHPCSUtils/Utils/Lists.php +++ b/PHPCSUtils/Utils/Lists.php @@ -13,7 +13,6 @@ use PHP_CodeSniffer\Exceptions\RuntimeException; use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; -use PHPCSUtils\BackCompat\BCTokens; use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Internal\Cache; use PHPCSUtils\Tokens\Collections; @@ -24,6 +23,7 @@ * Utility functions to retrieve information when working with lists. * * @since 1.0.0 + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. */ class Lists { @@ -159,7 +159,7 @@ public static function isShortList(File $phpcsFile, $stackPtr) * * @link https://github.com/squizlabs/PHP_CodeSniffer/pull/3013 */ - if (isset(BCTokens::magicConstants()[$tokens[$prevNonEmpty]['code']]) === true) { + if (isset(Tokens::$magicConstants[$tokens[$prevNonEmpty]['code']]) === true) { Cache::set($phpcsFile, __METHOD__, $stackPtr, false); return false; } @@ -296,20 +296,11 @@ public static function getOpenClose(File $phpcsFile, $stackPtr, $isShortList = n switch ($tokens[ $stackPtr ]['code']) { case \T_LIST: if (isset($tokens[$stackPtr]['parenthesis_opener'])) { - // PHPCS 3.5.0. $opener = $tokens[$stackPtr]['parenthesis_opener']; - } else { - // PHPCS < 3.5.0. - $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true); - if ($nextNonEmpty !== false - && $tokens[$nextNonEmpty]['code'] === \T_OPEN_PARENTHESIS - ) { - $opener = $nextNonEmpty; - } - } - if (isset($opener, $tokens[$opener]['parenthesis_closer'])) { - $closer = $tokens[$opener]['parenthesis_closer']; + if (isset($tokens[$opener]['parenthesis_closer'])) { + $closer = $tokens[$opener]['parenthesis_closer']; + } } break; diff --git a/PHPCSUtils/Utils/MessageHelper.php b/PHPCSUtils/Utils/MessageHelper.php index af9b52dc..9c1353d2 100644 --- a/PHPCSUtils/Utils/MessageHelper.php +++ b/PHPCSUtils/Utils/MessageHelper.php @@ -11,7 +11,6 @@ namespace PHPCSUtils\Utils; use PHP_CodeSniffer\Files\File; -use PHPCSUtils\BackCompat\Helper; /** * Helper functions for creating PHPCS error/warning messages. @@ -109,20 +108,6 @@ public static function stringToErrorcode($text) return \preg_replace('`[^a-z0-9_]`i', '_', $text); } - /** - * Check whether PHPCS can properly handle new lines in violation messages. - * - * @link https://github.com/squizlabs/PHP_CodeSniffer/pull/2093 - * - * @since 1.0.0-alpha4 - * - * @return bool - */ - public static function hasNewLineSupport() - { - return \version_compare(Helper::getVersion(), '3.3.1', '>='); - } - /** * Make the whitespace escape codes used in an arbitrary text string visible. * diff --git a/PHPCSUtils/Utils/Namespaces.php b/PHPCSUtils/Utils/Namespaces.php index 88453cac..fa64e458 100644 --- a/PHPCSUtils/Utils/Namespaces.php +++ b/PHPCSUtils/Utils/Namespaces.php @@ -14,7 +14,6 @@ use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; use PHPCSUtils\BackCompat\BCFile; -use PHPCSUtils\BackCompat\BCTokens; use PHPCSUtils\Internal\Cache; use PHPCSUtils\Tokens\Collections; use PHPCSUtils\Utils\Conditions; @@ -28,6 +27,7 @@ * @link https://www.php.net/language.namespaces PHP Manual on namespaces. * * @since 1.0.0 + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. */ class Namespaces { @@ -58,9 +58,9 @@ public static function getType(File $phpcsFile, $stackPtr) * Set up array of tokens which can only be used in combination with the keyword as operator * and which cannot be confused with other keywords. */ - $findAfter = BCTokens::assignmentTokens() - + BCTokens::comparisonTokens() - + BCTokens::operators() + $findAfter = Tokens::$assignmentTokens + + Tokens::$comparisonTokens + + Tokens::$operators + Tokens::$castTokens + Tokens::$blockOpeners + Collections::incrementDecrementOperators() @@ -100,14 +100,14 @@ public static function getType(File $phpcsFile, $stackPtr) $start = BCFile::findStartOfStatement($phpcsFile, $stackPtr); if ($start === $stackPtr && ($tokens[$next]['code'] === \T_STRING - || $tokens[$next]['type'] === 'T_NAME_QUALIFIED' + || $tokens[$next]['code'] === \T_NAME_QUALIFIED || $tokens[$next]['code'] === \T_OPEN_CURLY_BRACKET) ) { return 'declaration'; } if (($tokens[$next]['code'] === \T_NS_SEPARATOR - || $tokens[$next]['type'] === 'T_NAME_FULLY_QUALIFIED') // PHP 8.0 parse error. + || $tokens[$next]['code'] === \T_NAME_FULLY_QUALIFIED) // PHP 8.0 parse error. && ($start !== $stackPtr || $phpcsFile->findNext($findAfter, ($stackPtr + 1), null, false, null, true) !== false) ) { @@ -298,12 +298,6 @@ public static function findNamespacePtr(File $phpcsFile, $stackPtr) // Stop if we encounter a scoped namespace declaration as we already know we're not in one. if (isset($tokens[$prev]['scope_condition']) === true && $tokens[$tokens[$prev]['scope_condition']]['code'] === \T_NAMESPACE - /* - * BC: Work around a bug where curlies for variable variables received an incorrect - * and irrelevant scope condition in PHPCS < 3.3.0. - * {@link https://github.com/squizlabs/PHP_CodeSniffer/issues/1882} - */ - && self::isDeclaration($phpcsFile, $tokens[$prev]['scope_condition']) === true ) { break; } diff --git a/PHPCSUtils/Utils/Numbers.php b/PHPCSUtils/Utils/Numbers.php index c8a5e1e2..0dfa1595 100644 --- a/PHPCSUtils/Utils/Numbers.php +++ b/PHPCSUtils/Utils/Numbers.php @@ -12,22 +12,15 @@ use PHP_CodeSniffer\Exceptions\RuntimeException; use PHP_CodeSniffer\Files\File; -use PHPCSUtils\BackCompat\Helper; /** * Utility functions for working with integer/float tokens. * - * PHP 7.4 introduced numeric literal separators which break number tokenization in older PHP versions. - * PHPCS backfills this since PHPCS 3.5.3/4. + * PHP 7.4 introduced numeric literal separators. PHPCS backfills this since PHPCS 3.5.3/4. + * PHP 8.1 introduced an explicit octal notation. This is backfilled in PHPCS since PHPCS 3.7.0. * - * Along the same lines, PHP 8.1 introduced an explicit octal notation which also breaks number tokenization - * in older PHP versions. This is backfilled in PHPCS since PHPCS 3.7.0. - * - * In other words, if an external standard intends to support PHPCS < 3.7.0 and PHP < 8.1, working - * with number tokens has suddenly become a challenge. - * - * The functions in this class have been put in place to ease that pain and it is - * *strongly* recommended to always use these functions when sniffing for and examining the + * While there are currently no unsupported numeric syntaxes, the methods in this class + * can still be useful for external standards which need to examine the * contents of `T_LNUMBER` or `T_DNUMBER` tokens. * * @link https://www.php.net/migration74.new-features.php#migration74.new-features.core.numeric-literal-separator @@ -36,6 +29,11 @@ * PHP Manual on the introduction of the integer octal literal prefix. * * @since 1.0.0 + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. + * @since 1.0.0-alpha4 Removed the following class constants: + * - `Numbers::REGEX_NUMLIT_STRING` + * - `Numbers::REGEX_HEX_NUMLIT_STRING` + * - `Numbers::UNSUPPORTED_PHPCS_VERSION` */ class Numbers { @@ -103,83 +101,11 @@ class Numbers `ixD'; /** - * Regex to determine if a T_STRING following a T_[DL]NUMBER is part of a numeric literal sequence. - * - * Cross-version compatibility helper for PHP 7.4 numeric literals with underscore separators. - * - * @since 1.0.0 - * - * @var string - */ - const REGEX_NUMLIT_STRING = '`^((? true, - \T_DNUMBER => true, - \T_STRING => true, - ]; - - /** - * Retrieve information about a number token in a cross-version compatible manner. + * Retrieve information about a number token. * * Helper function to deal with numeric literals, potentially with underscore separators * and/or explicit octal notation. * - * PHP < 7.4 does not tokenize numeric literals containing underscores correctly. - * As of PHPCS 3.5.3, PHPCS contains a backfill, but this backfill was buggy in the initial - * implementation. A fix for this broken backfill is included in PHPCS 3.5.4. - * - * PHP < 8.1 does not tokenize explicit octal notation for literal integers correctly. - * PHPCS backfills this as of PHPCS 3.7.0. - * - * Either way, this function can be used with all PHPCS/PHP combinations and will, if necessary, - * provide a backfill for PHPCS/PHP combinations where PHP 7.4 numbers with underscore separators - * and/or octals using the explicit octal prefix, are tokenized incorrectly - with the exception - * of PHPCS 3.5.3 as the buggyness of the original backfill implementation makes it impossible - * to provide reliable results. - * - * Note: invalid explicit octals will be handled correctly by the method, but may result - * in a content "split" for the "last token". - * > Example: - * > In PHP < 8.1 `0o282` will tokenize as `T_LNUMBER` 0 + `T_STRING` `o282`. - * > This method will return `'0o2'` as the complete number content and the second token as the - * > `'last_token'`, even though there is still a part of the content of the second token - * > which is not included. - * - * @link https://github.com/squizlabs/PHP_CodeSniffer/issues/2546 PHPCS issue #2546 - * @link https://github.com/squizlabs/PHP_CodeSniffer/pull/2771 PHPCS PR #2771 - * @link https://github.com/squizlabs/PHP_CodeSniffer/pull/3481 PHPCS PR #3481 - * @link https://github.com/squizlabs/PHP_CodeSniffer/pull/3552 PHPCS PR #3552 - * * @since 1.0.0 * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. @@ -189,10 +115,8 @@ class Numbers * The format of the array return value is: * ```php * array( - * 'orig_content' => string, // The (potentially concatenated) original - * // content of the tokens; - * 'content' => string, // The (potentially concatenated) content, - * // underscore(s) removed; + * 'orig_content' => string, // The original content of the token(s); + * 'content' => string, // The content, underscore(s) removed; * 'code' => int, // The token code of the number, either * // T_LNUMBER or T_DNUMBER. * 'type' => string, // The token type, either 'T_LNUMBER' @@ -200,21 +124,17 @@ class Numbers * 'decimal' => string, // The decimal value of the number; * 'last_token' => int, // The stackPtr to the last token which was * // part of the number. - * // This will be the same as the original - * // stackPtr if it is not a PHP 7.4 number - * // with underscores. + * // At this time, this will be always be the original + * // stackPtr. This may change in the future if + * // new numeric syntaxes would be added to PHP. * ) * ``` * * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the specified token is not of type * `T_LNUMBER` or `T_DNUMBER`. - * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If this function is called in combination - * with an unsupported PHPCS version. */ public static function getCompleteNumber(File $phpcsFile, $stackPtr) { - static $php74, $php81, $phpcsVersion, $phpcsWithBackfill, $phpcsWithOctalSupport; - $tokens = $phpcsFile->getTokens(); if (isset($tokens[$stackPtr]) === false @@ -225,26 +145,8 @@ public static function getCompleteNumber(File $phpcsFile, $stackPtr) ); } - if (isset($php74, $php81, $phpcsVersion, $phpcsWithBackfill, $phpcsWithOctalSupport) === false) { - $php74 = \version_compare(\PHP_VERSION_ID, '70399', '>'); - $php81 = \version_compare(\PHP_VERSION_ID, '80099', '>'); - $phpcsVersion = Helper::getVersion(); - $phpcsWithBackfill = \version_compare($phpcsVersion, self::UNSUPPORTED_PHPCS_VERSION, '>'); - $phpcsWithOctalSupport = \version_compare($phpcsVersion, '3.7.0', '>='); - } - - /* - * Bow out for PHPCS version(s) with broken tokenization of PHP 7.4 numeric literals with - * separators, including for PHP 7.4, as the backfill kicks in for PHP 7.4 while it shouldn't. - * - * @link https://github.com/squizlabs/PHP_CodeSniffer/issues/2546 - */ - if (\version_compare($phpcsVersion, self::UNSUPPORTED_PHPCS_VERSION, '==') === true) { - throw new RuntimeException('The ' . __METHOD__ . '() method does not support PHPCS ' . $phpcsVersion); - } - $content = $tokens[$stackPtr]['content']; - $result = [ + return [ 'orig_content' => $content, 'content' => \str_replace('_', '', $content), 'code' => $tokens[$stackPtr]['code'], @@ -252,136 +154,6 @@ public static function getCompleteNumber(File $phpcsFile, $stackPtr) 'decimal' => self::getDecimalValue($content), 'last_token' => $stackPtr, ]; - - /* - * When things are already correctly tokenized for both situations handled by this method, - * there's not much to do. - */ - if ($php81 === true || $phpcsWithOctalSupport === true) { - return $result; - } - - /* - * Potentially handle explicit octal notation. - */ - if (isset($tokens[($stackPtr + 1)]) === true - && $tokens[($stackPtr + 1)]['code'] === \T_STRING - && \strtolower($tokens[($stackPtr + 1)]['content'][0]) === 'o' - && $tokens[($stackPtr + 1)]['content'][1] !== '_' - && \preg_match('`^(o[0-7]+(?:_[0-7]+)?)[0-9_]*`i', $tokens[($stackPtr + 1)]['content'], $matches) === 1 - ) { - $content .= $matches[1]; - $result = self::updateResult($result, $content, ($stackPtr + 1), true); - } - - /* - * Check if numeric literal notation needs handling. - */ - if ($php74 === true - || $phpcsWithBackfill === true - || isset($tokens[($result['last_token'] + 1)]) === false - || $tokens[($result['last_token'] + 1)]['code'] !== \T_STRING - || $tokens[($result['last_token'] + 1)]['content'][0] !== '_' - ) { - return $result; - } - - $hex = false; - if (\strpos($content, '0x') === 0) { - $hex = true; - } - - $lastChar = \substr($content, -1); - if (\preg_match('`[0-9]`', $lastChar) !== 1) { - if ($hex === false || \preg_match('`[A-F]`i', $lastChar) !== 1) { - // Last character not valid for numeric literal sequence with underscores. - // No need to look any further. - return $result; - } - } - - /* - * OK, so this could potentially be a PHP 7.4 number with an underscore separator with PHPCS - * being run on PHP < 7.4. - */ - - $regex = self::REGEX_NUMLIT_STRING; - if ($hex === true) { - $regex = self::REGEX_HEX_NUMLIT_STRING; - } - - $next = $result['last_token']; - $lastToken = $result['last_token']; - - while (isset($tokens[++$next], self::$numericLiteralAcceptedTokens[$tokens[$next]['code']]) === true) { - if ($tokens[$next]['code'] === \T_STRING - && \preg_match($regex, $tokens[$next]['content']) !== 1 - ) { - break; - } - - $content .= $tokens[$next]['content']; - $lastToken = $next; - $lastChar = \substr(\strtolower($content), -1); - - // Support floats. - if ($lastChar === 'e' - && isset($tokens[($next + 1)], $tokens[($next + 2)]) === true - && ($tokens[($next + 1)]['code'] === \T_MINUS - || $tokens[($next + 1)]['code'] === \T_PLUS) - && $tokens[($next + 2)]['code'] === \T_LNUMBER - ) { - $content .= $tokens[($next + 1)]['content']; - $content .= $tokens[($next + 2)]['content']; - $next += 2; - $lastToken = $next; - } - - // Don't look any further if the last char is not valid before a separator. - if (\preg_match('`[0-9]`', $lastChar) !== 1) { - if ($hex === false || \preg_match('`[a-f]`i', $lastChar) !== 1) { - break; - } - } - } - - return self::updateResult($result, $content, $lastToken, $hex); - } - - /** - * Helper function to update the result array for the getCompleteNumber() method. - * - * @param array $result Current result array. - * @param string $newContent The new content for the number to update the array for. - * @param int $lastToken Stack pointer to the last token for the accumulated content. - * @param bool $isInt Whether we know for sure this is not a float. - * - * @return array - */ - private static function updateResult(array $result, $newContent, $lastToken, $isInt = false) - { - $result['orig_content'] = $newContent; - $result['content'] = \str_replace('_', '', $newContent); - $result['decimal'] = self::getDecimalValue($result['content']); - $result['last_token'] = $lastToken; - - // Determine actual token type. - $type = $result['type']; - if ($type === 'T_LNUMBER') { - if ($isInt === false - && (\strpos($result['content'], '.') !== false - || \stripos($result['content'], 'e') !== false) - ) { - $type = 'T_DNUMBER'; - } elseif (($result['decimal'] + 0) > \PHP_INT_MAX) { - $type = 'T_DNUMBER'; - } - } - - $result['code'] = \constant($type); - $result['type'] = $type; - - return $result; } /** diff --git a/PHPCSUtils/Utils/ObjectDeclarations.php b/PHPCSUtils/Utils/ObjectDeclarations.php index 8a835ec9..f4ee969b 100644 --- a/PHPCSUtils/Utils/ObjectDeclarations.php +++ b/PHPCSUtils/Utils/ObjectDeclarations.php @@ -19,12 +19,13 @@ /** * Utility functions for use when examining object declaration statements. * - * @since 1.0.0 The `ObjectDeclarations::get(Declaration)Name()`, - * `ObjectDeclarations::getClassProperties()`, `ObjectDeclarations::findExtendedClassName()` - * and `ObjectDeclarations::findImplementedInterfaceNames()` methods are based on and - * inspired by the methods of the same name in the PHPCS native - * `PHP_CodeSniffer\Files\File` class. - * Also see {@see \PHPCSUtils\BackCompat\BCFile}. + * @since 1.0.0 The `ObjectDeclarations::get(Declaration)Name()`, + * `ObjectDeclarations::getClassProperties()`, `ObjectDeclarations::findExtendedClassName()` + * and `ObjectDeclarations::findImplementedInterfaceNames()` methods are based on and + * inspired by the methods of the same name in the PHPCS native + * `PHP_CodeSniffer\Files\File` class. + * Also see {@see \PHPCSUtils\BackCompat\BCFile}. + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. */ class ObjectDeclarations { @@ -43,11 +44,6 @@ class ObjectDeclarations * Using this version of the utility method, either the complete name (invalid or not) will * be returned or `null` in case of no name (parse error). * - * Note: - * - For ES6 classes in combination with PHPCS 2.x, passing a `T_STRING` token to - * this method will be accepted for JS files. - * - Support for JS ES6 method syntax has not been back-filled for PHPCS < 3.0.0. - * * @see \PHP_CodeSniffer\Files\File::getDeclarationName() Original source. * @see \PHPCSUtils\BackCompat\BCFile::getDeclarationName() Cross-version compatible version of the original. * @@ -77,17 +73,6 @@ public static function getName(File $phpcsFile, $stackPtr) $tokenCode = $tokens[$stackPtr]['code']; - /* - * BC: Work-around JS ES6 classes not being tokenized as T_CLASS in PHPCS < 3.0.0. - */ - if (isset($phpcsFile->tokenizerType) - && $phpcsFile->tokenizerType === 'JS' - && $tokenCode === \T_STRING - && $tokens[$stackPtr]['content'] === 'class' - ) { - $tokenCode = \T_CLASS; - } - if ($tokenCode !== \T_FUNCTION && $tokenCode !== \T_CLASS && $tokenCode !== \T_INTERFACE @@ -133,17 +118,7 @@ public static function getName(File $phpcsFile, $stackPtr) $tokenAfterNameEnd = $phpcsFile->findNext($exclude, $nameStart, $stopPoint); if ($tokenAfterNameEnd === false) { - $content = null; - - /* - * BC: In PHPCS 2.6.0, in case of live coding, the last token in a file will be tokenized - * as T_STRING, but won't have the `content` index set. - */ - if (isset($tokens[$nameStart]['content'])) { - $content = $tokens[$nameStart]['content']; - } - - return $content; + return $tokens[$nameStart]['content']; } // Name starts with number, so is composed of multiple tokens. @@ -330,24 +305,13 @@ private static function findNames(File $phpcsFile, $stackPtr, $keyword, array $a if (isset($tokens[$stackPtr]) === false || isset($allowedFor[$tokens[$stackPtr]['code']]) === false + || isset($tokens[$stackPtr]['scope_opener']) === false ) { return false; } - if (isset($tokens[$stackPtr]['scope_opener']) === true) { - $scopeOpener = $tokens[$stackPtr]['scope_opener']; - } else { - /* - * Work-around for a scope map tokenizer bug in PHPCS. - * {@link https://github.com/squizlabs/PHP_CodeSniffer/pull/3066} - */ - $scopeOpener = $phpcsFile->findNext(\T_OPEN_CURLY_BRACKET, ($stackPtr + 1), null); - if ($scopeOpener === false) { - return false; - } - } - - $keywordPtr = $phpcsFile->findNext($keyword, ($stackPtr + 1), $scopeOpener); + $scopeOpener = $tokens[$stackPtr]['scope_opener']; + $keywordPtr = $phpcsFile->findNext($keyword, ($stackPtr + 1), $scopeOpener); if ($keywordPtr === false) { return false; } diff --git a/PHPCSUtils/Utils/Operators.php b/PHPCSUtils/Utils/Operators.php index af3ddc01..4f768a87 100644 --- a/PHPCSUtils/Utils/Operators.php +++ b/PHPCSUtils/Utils/Operators.php @@ -12,23 +12,21 @@ use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; -use PHPCSUtils\BackCompat\BCTokens; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPCSUtils\Utils\FunctionDeclarations; use PHPCSUtils\Utils\Parentheses; -use PHPCSUtils\Utils\Scopes; /** * Utility functions for use when working with operators. * * @link https://www.php.net/language.operators PHP manual on operators. * - * @since 1.0.0 The `isReference()` method is based on and inspired by - * the method of the same name in the PHPCS native `File` class. - * Also see {@see \PHPCSUtils\BackCompat\BCFile}. - * The `isUnaryPlusMinus()` method is, in part, inspired by the - * `Squiz.WhiteSpace.OperatorSpacing` sniff. + * @since 1.0.0 The `isReference()` method is based on and inspired by + * the method of the same name in the PHPCS native `File` class. + * Also see {@see \PHPCSUtils\BackCompat\BCFile}. + * The `isUnaryPlusMinus()` method is, in part, inspired by the + * `Squiz.WhiteSpace.OperatorSpacing` sniff. + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. */ class Operators { @@ -58,6 +56,8 @@ class Operators \T_INLINE_THEN => true, \T_INLINE_ELSE => true, \T_CASE => true, + \T_FN_ARROW => true, + \T_MATCH_ARROW => true, ]; /** @@ -65,13 +65,12 @@ class Operators * * Main differences with the PHPCS version: * - Defensive coding against incorrect calls to this method. - * - Improved handling of select tokenizer errors involving short lists/short arrays. * * @see \PHP_CodeSniffer\Files\File::isReference() Original source. * @see \PHPCSUtils\BackCompat\BCFile::isReference() Cross-version compatible version of the original. * * @since 1.0.0 - * @since 1.0.0-alpha2 Added BC support for PHP 7.4 arrow functions. + * @since 1.0.0-alpha2 Added support for PHP 7.4 arrow functions. * @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokenization. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. @@ -90,10 +89,7 @@ public static function isReference(File $phpcsFile, $stackPtr) $tokenBefore = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true); - if ($tokens[$tokenBefore]['code'] === \T_FUNCTION - || $tokens[$tokenBefore]['code'] === \T_CLOSURE - || FunctionDeclarations::isArrowFunction($phpcsFile, $tokenBefore) === true - ) { + if (isset(Collections::functionDeclarationTokens()[$tokens[$tokenBefore]['code']]) === true) { // Function returns a reference. return true; } @@ -108,7 +104,7 @@ public static function isReference(File $phpcsFile, $stackPtr) return true; } - if (isset(BCTokens::assignmentTokens()[$tokens[$tokenBefore]['code']]) === true) { + if (isset(Tokens::$assignmentTokens[$tokens[$tokenBefore]['code']]) === true) { // This is directly after an assignment. It's a reference. Even if // it is part of an operation, the other tests will handle it. return true; @@ -124,7 +120,7 @@ public static function isReference(File $phpcsFile, $stackPtr) if ($lastOpener !== false) { $lastOwner = Parentheses::getOwner($phpcsFile, $lastOpener); - if (isset(Collections::functionDeclarationTokensBC()[$tokens[$lastOwner]['code']]) === true + if (isset(Collections::functionDeclarationTokens()[$tokens[$lastOwner]['code']]) === true // As of PHPCS 4.x, `T_USE` is a parenthesis owner. || $tokens[$lastOwner]['code'] === \T_USE ) { @@ -140,12 +136,11 @@ public static function isReference(File $phpcsFile, $stackPtr) /* * Pass by reference in function calls, assign by reference in arrays and - * closure use by reference in PHPCS 2.x and 3.x. + * closure use by reference in PHPCS 3.x. */ if ($tokens[$tokenBefore]['code'] === \T_OPEN_PARENTHESIS || $tokens[$tokenBefore]['code'] === \T_COMMA || $tokens[$tokenBefore]['code'] === \T_OPEN_SHORT_ARRAY - || $tokens[$tokenBefore]['code'] === \T_OPEN_SQUARE_BRACKET // PHPCS 2.8.0 < 3.3.0. ) { if ($tokens[$tokenAfter]['code'] === \T_VARIABLE) { return true; @@ -170,230 +165,6 @@ public static function isReference(File $phpcsFile, $stackPtr) return false; } - /** - * Determine if the passed token is a type union separator. - * - * The `T_BITWISE_OR` token is used in PHP as bitwise or, but as of PHP 8.0, also as the - * separator in union type declarations. - * - * As of PHPCS 3.6.0, the type union separator will be tokenized as `T_TYPE_UNION` in PHPCS. - * However, for any standard which needs to support PHPCS < 3.6.0, this method can analyze - * whether a T_BITWISE_OR token is a type union separator or an actual bitwise or operator. - * - * @link https://github.com/squizlabs/PHP_CodeSniffer/pull/3032 - * - * @since 1.0.0-alpha4 - * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the `T_BITWISE_OR` token. - * - * @return bool `TRUE` if the specified token position represents a type union separator. - * `FALSE` if the token represents a bitwise operator. - */ - public static function isTypeUnion(File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - - if (isset($tokens[$stackPtr]) === false) { - return false; - } - - if ($tokens[$stackPtr]['type'] === 'T_TYPE_UNION') { - // Just in case. - return true; - } - - if ($tokens[$stackPtr]['code'] !== \T_BITWISE_OR) { - return false; - } - - /* - * Check if it's a union separator in a property or parameter type. - */ - $ignore = Collections::propertyTypeTokensBC(); - $ignore += Collections::parameterTypeTokensBC(); - $ignore += Tokens::$emptyTokens; - $funcDeclTokens = Collections::functionDeclarationTokensBC(); - - $afterType = $phpcsFile->findNext($ignore, ($stackPtr + 1), null, true, null, true); - if ($afterType !== false) { - if ($tokens[$afterType]['code'] !== \T_VARIABLE) { - // Skip past reference and variadic indicators for parameter types. - while (($tokens[$afterType]['code'] === \T_BITWISE_AND - || $tokens[$afterType]['code'] === \T_ELLIPSIS - || isset(Tokens::$emptyTokens[$tokens[$afterType]['code']]) === true) - && ($afterType + 1) < $phpcsFile->numTokens - ) { - ++$afterType; - } - } - - if ($tokens[$afterType]['code'] === \T_VARIABLE) { - if (Scopes::isOOProperty($phpcsFile, $afterType) === true) { - // Union separator in a property type. - return true; - } - - if (Parentheses::lastOwnerIn($phpcsFile, $stackPtr, $funcDeclTokens) !== false) { - // Union separator for a parameter type. - return true; - } - - /* - * This may be an arrow function in combination with PHPCS < 3.5.3. - * Even when on PHP 7.4, the parentheses won't have an owner yet, so the previous - * condition will fall through to this one. - */ - $lastOpen = Parentheses::getLastOpener($phpcsFile, $stackPtr); - if ($lastOpen !== false) { - $maybeArrow = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($lastOpen - 1), null, true); - if ($maybeArrow !== false - && FunctionDeclarations::isArrowFunction($phpcsFile, $maybeArrow) === true - ) { - return true; - } - } - } - } - - /* - * Check if it's a union separator in a return type. - */ - $ignore = Collections::returnTypeTokensBC() + Tokens::$emptyTokens; - - $beforeType = $phpcsFile->findPrevious($ignore, ($stackPtr - 1), null, true); - - // Union types cannot be nullable, but the function should be parse error tolerant. - if ($beforeType !== false - && ($tokens[$beforeType]['type'] === 'T_NULLABLE' - // Handle nullable tokens in PHPCS < 2.8.0 and with arrow functions in PHPCS 2.8.0 - 2.9.0. - || (\version_compare(Helper::getVersion(), '2.9.1', '<') === true - && $tokens[$beforeType]['code'] === \T_INLINE_THEN)) - ) { - $beforeType = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($beforeType - 1), null, true); - } - - if ($beforeType !== false - && ($tokens[$beforeType]['code'] === \T_COLON - // Handle colon mistokenization in various PHPCS versions < 3.5.3. - || $tokens[$beforeType]['code'] === \T_INLINE_ELSE) - ) { - $afterType = $phpcsFile->findNext($ignore, ($stackPtr + 1), null, true, null, true); - if ($afterType !== false) { - if ($tokens[$afterType]['code'] === \T_SEMICOLON) { - // Union separator in a return type in an abstract or interface method. - return true; - } - - if (isset($tokens[$afterType]['scope_condition']) === true - && isset($funcDeclTokens[$tokens[$tokens[$afterType]['scope_condition']]['code']]) - ) { - // Union separator in a return type for a function, closure or arrow function. - return true; - } - - $closeParens = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($beforeType - 1), null, true); - - /* - * This may be a return type using the namespace keyword as an operator in - * combination with PHPCS < 3.5.7 in which the scope indexes won't be set. - * {@link https://github.com/squizlabs/PHP_CodeSniffer/pull/3066} - */ - if ($tokens[$afterType]['code'] === \T_OPEN_CURLY_BRACKET) { - if ($closeParens !== false - && $tokens[$closeParens]['code'] === \T_CLOSE_PARENTHESIS - && isset($tokens[$closeParens]['parenthesis_owner']) === true - && isset($funcDeclTokens[$tokens[$tokens[$closeParens]['parenthesis_owner']]['code']]) === true - ) { - return true; - } - } - - /* - * This may be an arrow function in combination with PHPCS < 3.5.3. - * Even when on PHP 7.4, the double arrow won't have the scope condition set yet, - * so the previous conditions will fall through to this one. - */ - if ($tokens[$afterType]['code'] === \T_DOUBLE_ARROW) { - if ($closeParens !== false - && $tokens[$closeParens]['code'] === \T_CLOSE_PARENTHESIS - && isset($tokens[$closeParens]['parenthesis_opener']) - ) { - $beforeOpen = $phpcsFile->findPrevious( - Tokens::$emptyTokens, - ($tokens[$closeParens]['parenthesis_opener'] - 1), - null, - true - ); - - if ($beforeOpen !== false - && FunctionDeclarations::isArrowFunction($phpcsFile, $beforeOpen) === true - ) { - // Union separator in a return type for an arrow function. - return true; - } - } - } - } - } - - return false; - } - - /** - * Determine whether a token is (part of) a nullsafe object operator. - * - * Helper method for PHP < 8.0 in combination with PHPCS versions in which the - * `T_NULLSAFE_OBJECT_OPERATOR` token is not yet backfilled. - * PHPCS backfills the token as of PHPCS 3.5.7. - * - * @since 1.0.0-alpha4 - * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the T_INLINE_THEN or T_OBJECT_OPERATOR - * token in the stack. - * - * @return bool `TRUE` if nullsafe object operator; or `FALSE` otherwise. - */ - public static function isNullsafeObjectOperator(File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - if (isset($tokens[$stackPtr]) === false) { - return false; - } - - /* - * Safeguard in case this method is used on PHP >= 8.0 or PHPCS >= 3.5.7 - * and the nullsafe object operator would be passed. - */ - if ($tokens[$stackPtr]['type'] === 'T_NULLSAFE_OBJECT_OPERATOR') { - return true; - } - - if (isset(Collections::nullsafeObjectOperatorBC()[$tokens[$stackPtr]['code']]) === false) { - return false; - } - - /* - * Note: not bypassing empty tokens as whitespace and comments are not allowed - * within an operator. - */ - if ($tokens[$stackPtr]['code'] === \T_INLINE_THEN) { - if (isset($tokens[$stackPtr + 1]) && $tokens[$stackPtr + 1]['code'] === \T_OBJECT_OPERATOR) { - return true; - } - } - - if ($tokens[$stackPtr]['code'] === \T_OBJECT_OPERATOR) { - if (isset($tokens[$stackPtr - 1]) && $tokens[$stackPtr - 1]['code'] === \T_INLINE_THEN) { - return true; - } - } - - // Not a nullsafe object operator token. - return false; - } - /** * Determine whether a T_MINUS/T_PLUS token is a unary operator. * @@ -423,7 +194,7 @@ public static function isUnaryPlusMinus(File $phpcsFile, $stackPtr) return false; } - if (isset(BCTokens::operators()[$tokens[$next]['code']]) === true) { + if (isset(Tokens::$operators[$tokens[$next]['code']]) === true) { // Next token is an operator, so this is not a unary. return false; } @@ -433,26 +204,16 @@ public static function isUnaryPlusMinus(File $phpcsFile, $stackPtr) /* * Check the preceeding token for an indication that this is not an arithmetic operation. */ - if (isset(BCTokens::operators()[$tokens[$prev]['code']]) === true - || isset(BCTokens::comparisonTokens()[$tokens[$prev]['code']]) === true + if (isset(Tokens::$operators[$tokens[$prev]['code']]) === true + || isset(Tokens::$comparisonTokens[$tokens[$prev]['code']]) === true || isset(Tokens::$booleanOperators[$tokens[$prev]['code']]) === true - || isset(BCTokens::assignmentTokens()[$tokens[$prev]['code']]) === true + || isset(Tokens::$assignmentTokens[$tokens[$prev]['code']]) === true || isset(Tokens::$castTokens[$tokens[$prev]['code']]) === true || isset(self::$extraUnaryIndicators[$tokens[$prev]['code']]) === true - || $tokens[$prev]['type'] === 'T_FN_ARROW' - || $tokens[$prev]['type'] === 'T_MATCH_ARROW' ) { return true; } - /* - * BC for PHPCS < 3.1.0 in which the PHP 5.5 T_YIELD token was not yet backfilled. - * Note: not accounting for T_YIELD_FROM as that would be a parse error anyway. - */ - if ($tokens[$prev]['code'] === \T_STRING && $tokens[$prev]['content'] === 'yield') { - return true; - } - return false; } diff --git a/PHPCSUtils/Utils/Parentheses.php b/PHPCSUtils/Utils/Parentheses.php index 0d513e62..2c209e28 100644 --- a/PHPCSUtils/Utils/Parentheses.php +++ b/PHPCSUtils/Utils/Parentheses.php @@ -12,9 +12,6 @@ use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; -use PHPCSUtils\Tokens\Collections; -use PHPCSUtils\Tokens\TokenHelper; -use PHPCSUtils\Utils\FunctionDeclarations; /** * Utility functions for use when examining parenthesis tokens and arbitrary tokens wrapped @@ -26,6 +23,7 @@ * @since 1.0.0 * @since 1.0.0-alpha4 Added support for `isset()`, `unset()`, `empty()`, `exit()`, `die()` * and `eval()` as parentheses owners to all applicable functions. + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. */ class Parentheses { @@ -33,7 +31,6 @@ class Parentheses /** * Extra tokens which should be considered parentheses owners. * - * - `T_LIST` and `T_ANON_CLASS` only became parentheses owners in PHPCS 3.5.0. * - `T_ISSET`, `T_UNSET`, `T_EMPTY`, `T_EXIT` and `T_EVAL` are not PHPCS native parentheses * owners, but are considered such for the purposes of this class. * Also {@see https://github.com/squizlabs/PHP_CodeSniffer/issues/3118}. @@ -43,22 +40,18 @@ class Parentheses * @var array => */ private static $extraParenthesesOwners = [ - \T_LIST => \T_LIST, - \T_ISSET => \T_ISSET, - \T_UNSET => \T_UNSET, - \T_EMPTY => \T_EMPTY, - \T_EXIT => \T_EXIT, - \T_EVAL => \T_EVAL, - \T_ANON_CLASS => \T_ANON_CLASS, - // Work-around: anon classes were, in certain circumstances, tokenized as T_CLASS prior to PHPCS 3.4.0. - \T_CLASS => \T_CLASS, + \T_ISSET => \T_ISSET, + \T_UNSET => \T_UNSET, + \T_EMPTY => \T_EMPTY, + \T_EXIT => \T_EXIT, + \T_EVAL => \T_EVAL, ]; /** * Get the stack pointer to the parentheses owner of an open/close parenthesis. * * @since 1.0.0 - * @since 1.0.0-alpha2 Added BC support for PHP 7.4 arrow functions. + * @since 1.0.0-alpha2 Added support for PHP 7.4 arrow functions. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. * @param int $stackPtr The position of `T_OPEN/CLOSE_PARENTHESIS` token. @@ -76,12 +69,8 @@ public static function getOwner(File $phpcsFile, $stackPtr) } /* - * - `T_FN` was only backfilled in PHPCS 3.5.3/4/5. - * - On PHP 7.4 with PHPCS < 3.5.3, T_FN will not yet be a parentheses owner. - * - On PHP < 7.4 with PHPCS < 3.5.3, T_FN will be tokenized as T_STRING and not yet be a parentheses owner. - * - * {@internal As the 'parenthesis_owner' index is only set on parentheses, we didn't need to do any - * input validation before, but now we do.} + * As the 'parenthesis_owner' index is only set on parentheses, we didn't need to do any + * input validation before, but now we do. */ if (isset($tokens[$stackPtr]) === false || ($tokens[$stackPtr]['code'] !== \T_OPEN_PARENTHESIS @@ -94,14 +83,10 @@ public static function getOwner(File $phpcsFile, $stackPtr) $stackPtr = $tokens[$stackPtr]['parenthesis_opener']; } - $skip = Tokens::$emptyTokens; - $skip[\T_BITWISE_AND] = \T_BITWISE_AND; - + $skip = Tokens::$emptyTokens; $prevNonEmpty = $phpcsFile->findPrevious($skip, ($stackPtr - 1), null, true); if ($prevNonEmpty !== false - && (isset(self::$extraParenthesesOwners[$tokens[$prevNonEmpty]['code']]) - // Possibly an arrow function. - || FunctionDeclarations::isArrowFunction($phpcsFile, $prevNonEmpty) === true) + && isset(self::$extraParenthesesOwners[$tokens[$prevNonEmpty]['code']]) === true ) { return $prevNonEmpty; } @@ -114,7 +99,7 @@ public static function getOwner(File $phpcsFile, $stackPtr) * set of valid owners. * * @since 1.0.0 - * @since 1.0.0-alpha2 Added BC support for PHP 7.4 arrow functions. + * @since 1.0.0-alpha2 Added support for PHP 7.4 arrow functions. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. * @param int $stackPtr The position of `T_OPEN/CLOSE_PARENTHESIS` token. @@ -134,23 +119,6 @@ public static function isOwnerIn(File $phpcsFile, $stackPtr, $validOwners) $tokens = $phpcsFile->getTokens(); $validOwners = (array) $validOwners; - /* - * Work around tokenizer bug where anon classes were, in certain circumstances, tokenized - * as `T_CLASS` prior to PHPCS 3.4.0. - * As `T_CLASS` is normally not an parenthesis owner, we can safely add it to the array - * without doing a version check. - */ - if (\in_array(\T_ANON_CLASS, $validOwners, true)) { - $validOwners[] = \T_CLASS; - } - - /* - * Allow for T_FN token being tokenized as T_STRING before PHPCS 3.5.3. - */ - if (TokenHelper::tokenExists('T_FN') && \in_array(\T_FN, $validOwners, true)) { - $validOwners += Collections::arrowFunctionTokensBC(); - } - return \in_array($tokens[$owner]['code'], $validOwners, true); } diff --git a/PHPCSUtils/Utils/PassedParameters.php b/PHPCSUtils/Utils/PassedParameters.php index dee03418..d6d3a612 100644 --- a/PHPCSUtils/Utils/PassedParameters.php +++ b/PHPCSUtils/Utils/PassedParameters.php @@ -24,6 +24,7 @@ * class instantiations, array declarations, isset and unset constructs. * * @since 1.0.0 + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. */ class PassedParameters { @@ -90,7 +91,6 @@ public static function hasParameters(File $phpcsFile, $stackPtr, $isShortArray = ); } - // Reminder: `new parent` only tokenizes as `T_PARENT` since PHPCS 3.7.0. if (isset(Collections::ooHierarchyKeywords()[$tokens[$stackPtr]['code']]) === true) { $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true); if ($tokens[$prev]['code'] !== \T_NEW) { @@ -182,9 +182,7 @@ public static function hasParameters(File $phpcsFile, $stackPtr, $isShortArray = * 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 normally be the colon, but may be different in - * // PHPCS versions prior to the version adding support for - * // named parameters (PHPCS 3.6.0). + * // 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. @@ -276,7 +274,7 @@ public static function getParameters(File $phpcsFile, $stackPtr, $limit = 0, $is && $tokens[$nextComma]['code'] !== $tokens[$closer]['code'] ) { // Just in case. - continue; + continue; // @codeCoverageIgnore } // Ok, we've reached the end of the parameter. @@ -285,37 +283,21 @@ public static function getParameters(File $phpcsFile, $stackPtr, $limit = 0, $is if ($mayHaveNames === true) { $firstNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, $paramStart, ($paramEnd + 1), true); if ($firstNonEmpty !== $paramEnd) { - /* - * BC: Prior to support for named parameters being added to PHPCS in PHPCS 3.6.0, the - * parameter name + the colon would in most cases be tokenized as one token: T_GOTO_LABEL. - */ - if ($tokens[$firstNonEmpty]['code'] === \T_GOTO_LABEL) { - $parameters[$cnt]['name_start'] = $paramStart; - $parameters[$cnt]['name_end'] = $firstNonEmpty; - $parameters[$cnt]['name'] = \substr($tokens[$firstNonEmpty]['content'], 0, -1); - $paramStart = ($firstNonEmpty + 1); - } else { - // PHPCS 3.6.0 and select situations in PHPCS < 3.6.0. - $secondNonEmpty = $phpcsFile->findNext( - Tokens::$emptyTokens, - ($firstNonEmpty + 1), - ($paramEnd + 1), - true - ); - - /* - * BC: Checking the content of the colon token instead of the token type as in PHPCS < 3.6.0 - * the colon _may_ be tokenized as `T_STRING` or even `T_INLINE_ELSE`. - */ - if ($tokens[$secondNonEmpty]['content'] === ':' - && ($tokens[$firstNonEmpty]['type'] === 'T_PARAM_NAME' + $secondNonEmpty = $phpcsFile->findNext( + Tokens::$emptyTokens, + ($firstNonEmpty + 1), + ($paramEnd + 1), + true + ); + + if ($tokens[$secondNonEmpty]['code'] === \T_COLON + && ($tokens[$firstNonEmpty]['type'] === 'T_PARAM_NAME' || NamingConventions::isValidIdentifierName($tokens[$firstNonEmpty]['content']) === true) - ) { - $parameters[$cnt]['name_start'] = $paramStart; - $parameters[$cnt]['name_end'] = $secondNonEmpty; - $parameters[$cnt]['name'] = $tokens[$firstNonEmpty]['content']; - $paramStart = ($secondNonEmpty + 1); - } + ) { + $parameters[$cnt]['name_start'] = $paramStart; + $parameters[$cnt]['name_end'] = $secondNonEmpty; + $parameters[$cnt]['name'] = $tokens[$firstNonEmpty]['content']; + $paramStart = ($secondNonEmpty + 1); } } } diff --git a/PHPCSUtils/Utils/Scopes.php b/PHPCSUtils/Utils/Scopes.php index 9687e7c5..736aab0a 100644 --- a/PHPCSUtils/Utils/Scopes.php +++ b/PHPCSUtils/Utils/Scopes.php @@ -11,7 +11,7 @@ namespace PHPCSUtils\Utils; use PHP_CodeSniffer\Files\File; -use PHPCSUtils\BackCompat\BCTokens; +use PHP_CodeSniffer\Util\Tokens; use PHPCSUtils\Tokens\Collections; use PHPCSUtils\Utils\Conditions; use PHPCSUtils\Utils\Parentheses; @@ -134,7 +134,7 @@ public static function isOOMethod(File $phpcsFile, $stackPtr) return false; } - if (self::validDirectScope($phpcsFile, $stackPtr, BCTokens::ooScopeTokens()) !== false) { + if (self::validDirectScope($phpcsFile, $stackPtr, Tokens::$ooScopeTokens) !== false) { return true; } diff --git a/PHPCSUtils/Utils/TextStrings.php b/PHPCSUtils/Utils/TextStrings.php index 4438dd81..7f6be453 100644 --- a/PHPCSUtils/Utils/TextStrings.php +++ b/PHPCSUtils/Utils/TextStrings.php @@ -22,6 +22,7 @@ * Utility functions for working with text string tokens. * * @since 1.0.0 + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. */ class TextStrings { @@ -102,10 +103,6 @@ public static function getCompleteTextString(File $phpcsFile, $stackPtr, $stripQ /** * Get the stack pointer to the end of a - potentially multi-line - text string. * - * This method also correctly handles a particular type of double quoted string - * with an embedded expression which is incorrectly tokenized in PHPCS itself prior to - * PHPCS version 3.7.0. - * * @see \PHPCSUtils\Utils\TextStrings::getCompleteTextString() Retrieve the contents of a complete - potentially * multi-line - text string. * @@ -169,113 +166,10 @@ public static function getEndOfCompleteTextString(File $phpcsFile, $stackPtr) $lastPtr = ($current - 1); - if ($targetType === \T_DOUBLE_QUOTED_STRING) { - /* - * BC for PHPCS < 3.7.0. - * Prior to PHPCS 3.7.0, when a select group of embedded variables/expressions was encountered - * in a double quoted string, the embed would not be tokenized as part of the T_DOUBLE_QUOTED_STRING, - * but would still have the PHP native tokenization. - */ - $end = self::getEndOfDoubleQuotedString($phpcsFile, $lastPtr); - if ($end !== $lastPtr) { - // Check if the double quoted string continues after the end of the embed. - if ($tokens[$end]['code'] === \T_DOUBLE_QUOTED_STRING) { - // Handles `"Text {embed} Text` followed by new line and additional text. - $end = self::getEndOfCompleteTextString($phpcsFile, $end); - } elseif ($tokens[($end + 1)]['code'] === \T_DOUBLE_QUOTED_STRING) { - // Handles `"Text {multi-line embed}` followed by additional text. - $end = self::getEndOfCompleteTextString($phpcsFile, ($end + 1)); - } - } - - $lastPtr = $end; - } - Cache::set($phpcsFile, __METHOD__, $stackPtr, $lastPtr); return $lastPtr; } - /** - * Get the stack pointer to the end of a (single) double quoted text string. - * - * This method provides a protection layer against a tokenizer bug in PHPCS < 3.7.0. - * When a select group of embedded variables/expressions was encountered in a double quoted string, - * PHPCS would not tokenize the double quoted string as one token per line, but instead the original - * PHP native tokens would be included in the token stream. - * This throws off the scope map (which can't be helped), but also makes examining - * the contents of double quoted strings difficult. - * - * This method can help remedy that. - * - * Note: If the embed is spread over multiple lines, the last token of the mistokenized - * part of the embed will be returned. The double quoted string _may_ still continue after that. - * - * @link https://github.com/squizlabs/PHP_CodeSniffer/pull/3604 PHPCS PR #3604 - * - * @see \PHPCSUtils\Utils\GetTokensAsString Methods to retrieve the contents of the - * combined tokens. - * @see \PHPCSUtils\Utils\TextStrings::getEndOfCompleteTextString() Get the stack pointer to the end of a complete - * - potentially multi-line - text string. - * @see \PHPCSUtils\Utils\TextStrings::getCompleteTextString() Retrieve the contents of a complete - - * - potentially multi-line - text string. - * - * @since 1.0.0-alpha4 - * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. - * @param int $stackPtr Pointer to the first text string token - * of a - potentially multi-token - double - * quoted text string. - * - * @return int Stack pointer to the last token (which may be the original stack pointer). - * - * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the specified position is not a - * T_DOUBLE_QUOTED_STRING token. - */ - public static function getEndOfDoubleQuotedString(File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - - if (isset($tokens[$stackPtr]) === false || $tokens[$stackPtr]['code'] !== \T_DOUBLE_QUOTED_STRING) { - throw new RuntimeException('$stackPtr must be of type T_DOUBLE_QUOTED_STRING'); - } - - $next = ($stackPtr + 1); - if (isset($tokens[$next]) === false || $tokens[$next]['code'] !== \T_DOLLAR_OPEN_CURLY_BRACES) { - // This code is not affected by the tokenizer bug. - return $stackPtr; - } - - /* - * BC for PHPCS < 3.7.0. - */ - $nestedBraces = [$next]; - for ($next = ($next + 1); $next < $phpcsFile->numTokens; $next++) { - if ($tokens[$next]['code'] === \T_DOUBLE_QUOTED_STRING - && empty($nestedBraces) === true - ) { - break; - } - - if (\strpos($tokens[$next]['content'], '{') !== false) { - $nestedBraces[] = $next; - } - - if (\strpos($tokens[$next]['content'], '}') !== false) { - \array_pop($nestedBraces); - } - } - - if ($next === $phpcsFile->numTokens) { - return ($phpcsFile->numTokens - 1); - } - - if ($tokens[$next]['line'] > $tokens[$stackPtr]['line']) { - return ($next - 1); - } - - return self::getEndOfDoubleQuotedString($phpcsFile, $next); - } - /** * Strip text delimiter quotes from an arbitrary text string. * diff --git a/PHPCSUtils/Utils/UseStatements.php b/PHPCSUtils/Utils/UseStatements.php index 12edb5e2..b0b00469 100644 --- a/PHPCSUtils/Utils/UseStatements.php +++ b/PHPCSUtils/Utils/UseStatements.php @@ -13,8 +13,6 @@ use PHP_CodeSniffer\Exceptions\RuntimeException; use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; -use PHPCSUtils\BackCompat\BCTokens; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Internal\Cache; use PHPCSUtils\Utils\Conditions; use PHPCSUtils\Utils\Parentheses; @@ -23,6 +21,7 @@ * Utility functions for examining use statements. * * @since 1.0.0 + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. */ class UseStatements { @@ -75,20 +74,12 @@ public static function getType(File $phpcsFile, $stackPtr) } $lastCondition = Conditions::getLastCondition($phpcsFile, $stackPtr); - if (($tokens[$lastCondition]['code'] === \T_CASE - || $tokens[$lastCondition]['code'] === \T_DEFAULT) - && \version_compare(Helper::getVersion(), '2.99.99', '<') === true - && Conditions::hasCondition($phpcsFile, $stackPtr, [\T_SWITCH]) === false - ) { - $lastCondition = Conditions::getLastCondition($phpcsFile, $lastCondition); - } - if ($lastCondition === false || $tokens[$lastCondition]['code'] === \T_NAMESPACE) { // Global or scoped namespace and not a closure use statement. return 'import'; } - $traitScopes = BCTokens::ooScopeTokens(); + $traitScopes = Tokens::$ooScopeTokens; // Only classes and traits can import traits. unset($traitScopes[\T_INTERFACE]); @@ -242,28 +233,9 @@ public static function splitImportUseStatement(File $phpcsFile, $stackPtr) continue; } - $tokenType = $tokens[$i]['type']; - - /* - * BC: Work round a tokenizer bug related to a parse error. - * - * If `function` or `const` is used as the alias, the semi-colon after it would - * be tokenized as T_STRING. - * For `function` this was fixed in PHPCS 2.8.0. For `const` the issue was fixed - * in PHPCS 3.7.0. - * - * Along the same lines, the `}` T_CLOSE_USE_GROUP would also be tokenized as T_STRING. - */ - if ($tokenType === 'T_STRING') { - if ($tokens[$i]['content'] === ';') { - $tokenType = 'T_SEMICOLON'; - } elseif ($tokens[$i]['content'] === '}') { - $tokenType = 'T_CLOSE_USE_GROUP'; - } - } - - switch ($tokenType) { - case 'T_STRING': + $tokenCode = $tokens[$i]['code']; + switch ($tokenCode) { + case \T_STRING: // Only when either at the start of the statement or at the start of a new sub within a group. if ($start === true && $fixedType === false) { $content = \strtolower($tokens[$i]['content']); @@ -289,23 +261,12 @@ public static function splitImportUseStatement(File $phpcsFile, $stackPtr) } $alias = $tokens[$i]['content']; - - /* - * BC: work around PHPCS tokenizer issue in PHPCS < 3.5.7 where anything directly after - * a `function` or `const` keyword would be retokenized to `T_STRING`, including the - * PHP 8 identifier name tokens. - */ - $hasSlash = \strrpos($tokens[$i]['content'], '\\'); - if ($hasSlash !== false) { - $alias = \substr($tokens[$i]['content'], ($hasSlash + 1)); - } - break; - case 'T_NAME_QUALIFIED': - case 'T_NAME_FULLY_QUALIFIED': // This would be a parse error, but handle it anyway. + case \T_NAME_QUALIFIED: + case \T_NAME_FULLY_QUALIFIED: // This would be a parse error, but handle it anyway. /* - * PHPCS 4.x or PHP > 8.0 with PHPCS < 3.5.7. + * PHPCS 4.x. * * These tokens can only be encountered when either at the start of the statement * or at the start of a new sub within a group. @@ -323,21 +284,21 @@ public static function splitImportUseStatement(File $phpcsFile, $stackPtr) $alias = \substr($tokens[$i]['content'], (\strrpos($tokens[$i]['content'], '\\') + 1)); break; - case 'T_AS': + case \T_AS: $hasAlias = true; break; - case 'T_OPEN_USE_GROUP': + case \T_OPEN_USE_GROUP: $start = true; $useGroup = true; $baseName = $name; $name = ''; break; - case 'T_SEMICOLON': - case 'T_CLOSE_TAG': - case 'T_CLOSE_USE_GROUP': - case 'T_COMMA': + case \T_SEMICOLON: + case \T_CLOSE_TAG: + case \T_CLOSE_USE_GROUP: + case \T_COMMA: if ($name !== '') { if ($useGroup === true) { $statements[$type][$alias] = $baseName . $name; @@ -346,7 +307,7 @@ public static function splitImportUseStatement(File $phpcsFile, $stackPtr) } } - if ($tokenType !== 'T_COMMA') { + if ($tokenCode !== \T_COMMA) { break 2; } @@ -359,46 +320,18 @@ public static function splitImportUseStatement(File $phpcsFile, $stackPtr) } break; - case 'T_NS_SEPARATOR': + case \T_NS_SEPARATOR: $name .= $tokens[$i]['content']; break; - case 'T_FUNCTION': - case 'T_CONST': - /* - * BC: Work around tokenizer bug in PHPCS < 3.4.1. - * - * `function`/`const` in `use function`/`use const` tokenized as T_FUNCTION/T_CONST - * instead of T_STRING when there is a comment between the keywords. - * - * @link https://github.com/squizlabs/PHP_CodeSniffer/issues/2431 - */ - if ($start === true && $fixedType === false) { - $type = \strtolower($tokens[$i]['content']); - $start = false; - if ($useGroup === false) { - $fixedType = true; - } - - break; - } - - $start = false; - - if ($hasAlias === false) { - $name .= $tokens[$i]['content']; - } - - $alias = $tokens[$i]['content']; - break; - /* * Fall back in case reserved keyword is (illegally) used in name. * Parse error, but not our concern. */ default: if ($hasAlias === false) { - $name .= $tokens[$i]['content']; + // Defensive coding, just in case. Should no longer be possible since PHPCS 3.7.0. + $name .= $tokens[$i]['content']; // @codeCoverageIgnore } $alias = $tokens[$i]['content']; diff --git a/PHPCSUtils/Utils/Variables.php b/PHPCSUtils/Utils/Variables.php index c4a8aedc..1e7549d7 100644 --- a/PHPCSUtils/Utils/Variables.php +++ b/PHPCSUtils/Utils/Variables.php @@ -20,9 +20,10 @@ /** * Utility functions for use when examining variables. * - * @since 1.0.0 The `Variables::getMemberProperties()` method is based on and inspired by - * the method of the same name in the PHPCS native `PHP_CodeSniffer\Files\File` class. - * Also see {@see \PHPCSUtils\BackCompat\BCFile}. + * @since 1.0.0 The `Variables::getMemberProperties()` method is based on and inspired by + * the method of the same name in the PHPCS native `PHP_CodeSniffer\Files\File` class. + * Also see {@see \PHPCSUtils\BackCompat\BCFile}. + * @since 1.0.0-alpha4 Dropped support for PHPCS < 3.7.1. */ class Variables { @@ -169,7 +170,7 @@ public static function getMemberProperties(File $phpcsFile, $stackPtr) $typeToken = false; $typeEndToken = false; $nullableType = false; - $propertyTypeTokens = Collections::propertyTypeTokensBC(); + $propertyTypeTokens = Collections::propertyTypeTokens(); if ($i < $stackPtr) { // We've found a type. @@ -179,10 +180,7 @@ public static function getMemberProperties(File $phpcsFile, $stackPtr) break; } - if ($tokens[$i]['type'] === 'T_NULLABLE' - // Handle nullable types in PHPCS < 3.5.0 and for PHP-4 style `var` properties in PHPCS < 3.5.4. - || $tokens[$i]['code'] === \T_INLINE_THEN - ) { + if ($tokens[$i]['code'] === \T_NULLABLE) { $nullableType = true; } diff --git a/README.md b/README.md index d8fd27f7..0e743278 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,7 @@ * [Features](#features) * [Minimum Requirements](#minimum-requirements) * [Integrating PHPCSUtils in your external PHPCS standard](#integrating-phpcsutils-in-your-external-phpcs-standard) - - [Composer-based with a minimum PHPCS requirement of PHPCS 3.1.0](#composer-based-with-a-minimum-phpcs-requirement-of-phpcs-310) - - [Composer-based with a minimum PHPCS requirement of PHPCS 2.6.0](#composer-based-with-a-minimum-phpcs-requirement-of-phpcs-260) + - [Composer-based](#composer-based) - [Non-Composer based integration](#non-composer-based-integration) * [Frequently Asked Questions](#frequently-asked-questions) * [Potential Support Questions from your End-Users](#potential-support-questions-from-your-end-users) @@ -40,37 +39,33 @@ This package offers the following features:
-### Use the latest version of PHP_CodeSniffer native utility functions - -Normally to use the latest version of PHP_CodeSniffer native utility functions, you would have to raise the minimum requirements of your external PHPCS standard. +### An ever-growing number of utility functions for use with PHP_CodeSniffer -Now you won't have to anymore. This package allows you to use the latest version of those utility functions in all PHP_CodeSniffer versions from PHPCS 2.6.0 and up. +Whether you need to split an `array` into the individual items, are trying to determine which variables are being assigned to in a `list()` or are figuring out whether a function has a DocBlock, PHPCSUtils has got you covered! -### Several abstract sniff classes which your sniffs can extend +Includes improved versions of the PHPCS native utility functions and plenty of new utility functions. -These classes take most of the heavy lifting away for some frequently occurring sniff types. +These functions are compatible with PHPCS 3.7.1 up to PHPCS `master`. ### A collection of static properties and methods for often-used token groups Collections of related tokens often-used and needed for sniffs. These are additional "token groups" to compliment the ones available through the PHPCS native `PHP_CodeSniffer\Util\Tokens` class. -### An ever-growing number of utility functions for use with PHP_CodeSniffer - -Whether you need to split an `array` into the individual items, are trying to determine which variables are being assigned to in a `list()` or are figuring out whether a function has a DocBlock, PHPCSUtils has got you covered! - -Includes improved versions of the PHPCS native utility functions and plenty of new utility functions. +### Several abstract sniff classes which your sniffs can extend -These functions are, of course, compatible with PHPCS 2.6.0 up to PHPCS `master`. +These classes take most of the heavy lifting away for some frequently occurring sniff types. ### Test utilities An abstract `UtilityMethodTestCase` class to support testing of your utility methods written for PHP_CodeSniffer. -Compatible with both PHPCS 2.x as well as 3.x. Supports PHPUnit 4.x up to 9.x. +Supports PHPUnit 4.x up to 9.x. -### Backward compatibility layer +### Use the latest version of PHP_CodeSniffer native utility functions + +Normally to use the latest version of PHP_CodeSniffer native utility functions, you would have to raise the minimum requirements of your external PHPCS standard. -A `PHPCS23Utils` standard which allows sniffs to work in both PHPCS 2.x and 3.x, as well as a few helper functions for external standards which still want to support both PHP_CodeSniffer 2.x as well as 3.x. +Now you won't have to anymore. This package allows you to use the latest version of those utility functions in all PHP_CodeSniffer versions from PHPCS 3.7.1 and up. ### Fully documented @@ -82,16 +77,16 @@ To see detailed information about all the available abstract sniffs, utility fun ## Minimum Requirements * PHP 5.4 or higher. -* [PHP_CodeSniffer] 2.6.0+, 3.1.0+ (with the exception of PHPCS 3.5.3). +* [PHP_CodeSniffer] 3.7.1+. * Recommended PHP extensions for optimal functionality: - PCRE with Unicode support (normally enabled by default) ## Integrating PHPCSUtils in your external PHPCS standard -### Composer-based with a minimum PHPCS requirement of PHPCS 3.1.0 +### Composer-based -If your external PHP_CodeSniffer standard only supports Composer-based installs and has a minimum PHPCS requirement of PHP_CodeSniffer 3.1.0, integrating PHPCSUtils is pretty straight forward. +If your external PHP_CodeSniffer standard only supports Composer-based installs, integrating PHPCSUtils is pretty straight forward. Run the following from the root of your external PHPCS standard's project: ```bash @@ -122,25 +117,6 @@ If you have your own unit test suite to test your sniffs, make sure to load the If you intend to use the test utilities provided in the `PHPCSUtils/TestUtils` directory, make sure you also load the `vendor/phpcsstandards/phpcsutils/phpcsutils-autoload.php` file in your PHPUnit bootstrap file. -### Composer-based with a minimum PHPCS requirement of PHPCS 2.6.0 - -Follow the above instructions for use with PHPCS 3.x. - -In addition to that, add the following to the `ruleset.xml` file of your standard(s): -```xml - - -``` - -> :information_source: The `PHPCS23Utils` "standard" does not add any real sniffs, it only makes sure that the Utility functions will work in PHPCS 2.x as well. - -#### Running your unit tests - -If your standard supports both PHPCS 2.x as well as 3.x, you are bound to already have a PHPUnit `bootstrap.php` file in place. - -To allow the unit tests to find the relevant files for PHPCSUtils, make sure that the bootstrap loads both the Composer `vendor/autoload.php` file, as well as the `vendor/phpcsstandards/phpcsutils/phpcsutils-autoload.php` file. - - ### Non-Composer based integration In this case, more than anything, you will need to update the non-Composer installation instructions for your end-users. @@ -194,8 +170,7 @@ if ($phpcsUtilDir === false && file_exists(__DIR__ . '/vendor/autoload.php')) { // Load the Composer autoload file. require_once $vendorDir . '/autoload.php'; - // This snippet is only needed when you use the PHPCSUtils TestUtils - // or if your standard still supports PHPCS 2.x. + // This snippet is only needed when you use the PHPCSUtils TestUtils. if (file_exists($phpcsUtilDir . '/phpcsutils-autoload.php')) { require_once $phpcsUtilDir . '/phpcsutils-autoload.php'; } @@ -236,26 +211,6 @@ Once that's done, you will need to make a small tweak to your own dev environmen A: As PHPCSUtils is registered with PHPCS as an external standard and PHPCSUtils complies with the naming requirements of PHPCS, the PHPCS native autoloader will automatically take care of loading the classes used from PHPCSUtils. -### Q: What does the `PHPCS23Utils` standard do? - -A: All the `PHPCS23Utils` standard does is load the `phpcsutils-autoload.php` file. - -PHPCS 3.x uses namespaces, while PHPCS 2.x does not. The `phpcsutils-autoload.php` file creates `class_alias`-es for the most commonly used PHPCS classes, including all PHPCS classes used by PHPCSUtils. That way, both your external standard as well as PHPCSUtils can refer to the PHPCS 3.x class names and the code will still work in PHPCS 2.x. - -### Q: Why is PHP_CodeSniffer 3.5.3 not supported? - -A: The backfill for PHP 7.4 numeric literals with underscores in PHP_CodeSniffer 3.5.3 is broken and there is no way to reliably provide support for anything to do with numbers or `T_STRING` tokens when using PHP_CodeSniffer 3.5.3 as the tokens returned by the tokenizer are unpredictable and unreliable. - -The backfill was fixed in PHP_CodeSniffer 3.5.4. - -### Q: Any other problematic PHPCS versions? - -A: Well, the arrow function backfill which was added in PHPCS 3.5.3 may still cause problems. In a very limited set of circumstances, it will even hang the Tokenizer. A fix for [one particular such problem](https://github.com/squizlabs/php_codesniffer/issues/2926) was committed upstream and released in PHP_CodeSniffer 3.5.6, but there is no guarantee that all issues have been found. - -As the Tokenizer hanging is a problem unrelated to PHPCSUtils and not something which can be mitigated from within PHPCSUtils in any conceivable way, PHPCSUtils won't block installation in combination with PHPCS 3.5.4 and 3.5.5. - -There are several other issues which can not be worked around, like scope closers being set incorrectly and throwing the scope setting off for the rest of the file, so not withstanding that PHPCSUtils can work around a lot of issues, it is still highly recommended to advise your end-users to always use the latest version of PHPCS for the most reliable results. - ### Q: Does using PHPCSUtils have any effect on the PHPCS native sniffs? A: No. PHPCSUtils will only work for those sniffs which explicitly use the PHPCSUtils functionality. @@ -273,8 +228,7 @@ A: No. The UTF-8 file encoding is the only officially supported encoding. Suppor > **It is recommended to advise your users to save their files as UTF-8 encoded for the best results.** -PHP_CodeSniffer 3.x will default to UTF-8 as the expected file encoding. -If your standard supports PHP_CodeSniffer 2.x, it is recommended to set the expected encoding in the ruleset to `utf-8`, like so: `` or to advise users to use the CLI option `--encoding=utf-8`. +Note: PHP_CodeSniffer 3.x defaults to UTF-8 as the expected file encoding. ## Potential Support Questions from your End-Users diff --git a/Tests/BackCompat/BCFile/FindEndOfStatementTest.inc b/Tests/BackCompat/BCFile/FindEndOfStatementTest.inc index ab5d6fe6..f8b25cb4 100644 --- a/Tests/BackCompat/BCFile/FindEndOfStatementTest.inc +++ b/Tests/BackCompat/BCFile/FindEndOfStatementTest.inc @@ -44,13 +44,13 @@ return 0; /* testArrowFunctionReturnValue */ fn(): array => [a($a, $b)]; +/* testArrowFunctionAsArgument */ $foo = foo( - /* testArrowFunctionAsArgument */ fn() => bar() ); +/* testArrowFunctionWithArrayAsArgument */ $foo = foo( - /* testArrowFunctionWithArrayAsArgument */ fn() => [$row[0], $row[3]] ); diff --git a/Tests/BackCompat/BCFile/FindEndOfStatementTest.php b/Tests/BackCompat/BCFile/FindEndOfStatementTest.php index 8ca4145c..a38b6f89 100644 --- a/Tests/BackCompat/BCFile/FindEndOfStatementTest.php +++ b/Tests/BackCompat/BCFile/FindEndOfStatementTest.php @@ -24,7 +24,6 @@ use PHPCSUtils\BackCompat\BCFile; use PHPCSUtils\TestUtils\UtilityMethodTestCase; -use PHPCSUtils\Tokens\Collections; /** * Tests for the \PHPCSUtils\BackCompat\BCFile::findEndOfStatement method. @@ -175,7 +174,7 @@ public function testUseGroup() */ public function testArrowFunctionArrayValue() { - $start = $this->getTargetToken('/* testArrowFunctionArrayValue */', Collections::arrowFunctionTokensBC()); + $start = $this->getTargetToken('/* testArrowFunctionArrayValue */', T_FN); $found = BCFile::findEndOfStatement(self::$phpcsFile, $start); $this->assertSame(($start + 9), $found); @@ -189,7 +188,7 @@ public function testArrowFunctionArrayValue() public function testStaticArrowFunction() { $static = $this->getTargetToken('/* testStaticArrowFunction */', T_STATIC); - $fn = $this->getTargetToken('/* testStaticArrowFunction */', Collections::arrowFunctionTokensBC()); + $fn = $this->getTargetToken('/* testStaticArrowFunction */', T_FN); $endOfStatementStatic = BCFile::findEndOfStatement(self::$phpcsFile, $static); $endOfStatementFn = BCFile::findEndOfStatement(self::$phpcsFile, $fn); @@ -204,7 +203,7 @@ public function testStaticArrowFunction() */ public function testArrowFunctionReturnValue() { - $start = $this->getTargetToken('/* testArrowFunctionReturnValue */', Collections::arrowFunctionTokensBC()); + $start = $this->getTargetToken('/* testArrowFunctionReturnValue */', T_FN); $found = BCFile::findEndOfStatement(self::$phpcsFile, $start); $this->assertSame(($start + 18), $found); @@ -217,7 +216,7 @@ public function testArrowFunctionReturnValue() */ public function testArrowFunctionAsArgument() { - $start = $this->getTargetToken('/* testArrowFunctionAsArgument */', Collections::arrowFunctionTokensBC()); + $start = $this->getTargetToken('/* testArrowFunctionAsArgument */', T_FN); $found = BCFile::findEndOfStatement(self::$phpcsFile, $start); $this->assertSame(($start + 8), $found); @@ -230,10 +229,7 @@ public function testArrowFunctionAsArgument() */ public function testArrowFunctionWithArrayAsArgument() { - $start = $this->getTargetToken( - '/* testArrowFunctionWithArrayAsArgument */', - Collections::arrowFunctionTokensBC() - ); + $start = $this->getTargetToken('/* testArrowFunctionWithArrayAsArgument */', T_FN); $found = BCFile::findEndOfStatement(self::$phpcsFile, $start); $this->assertSame(($start + 17), $found); diff --git a/Tests/BackCompat/BCFile/GetDeclarationNameJSTest.php b/Tests/BackCompat/BCFile/GetDeclarationNameJSTest.php index 5e5e82e9..c2dbf9d6 100644 --- a/Tests/BackCompat/BCFile/GetDeclarationNameJSTest.php +++ b/Tests/BackCompat/BCFile/GetDeclarationNameJSTest.php @@ -39,7 +39,7 @@ class GetDeclarationNameJSTest extends UtilityMethodTestCase */ public function testInvalidTokenPassed() { - $this->expectPhpcsException('Token type "T_STRING" is not T_FUNCTION, T_CLASS, T_INTERFACE or T_TRAIT'); + $this->expectPhpcsException('Token type "T_STRING" is not T_FUNCTION, T_CLASS, T_INTERFACE, T_TRAIT or T_ENUM'); $target = $this->getTargetToken('/* testInvalidTokenPassed */', \T_STRING); BCFile::getDeclarationName(self::$phpcsFile, $target); @@ -134,10 +134,6 @@ public function dataGetDeclarationName() */ public function testGetDeclarationNameES6Method() { - if (\version_compare(static::$phpcsVersion, '3.0.0', '<') === true) { - $this->markTestSkipped('Support for JS ES6 method has not been backfilled for PHPCS 2.x (yet)'); - } - $target = $this->getTargetToken('/* testMethod */', [\T_CLASS, \T_INTERFACE, \T_TRAIT, \T_FUNCTION]); $result = BCFile::getDeclarationName(self::$phpcsFile, $target); $this->assertSame('methodName', $result); diff --git a/Tests/BackCompat/BCFile/GetDeclarationNameTest.php b/Tests/BackCompat/BCFile/GetDeclarationNameTest.php index 95aa9981..e97b0a45 100644 --- a/Tests/BackCompat/BCFile/GetDeclarationNameTest.php +++ b/Tests/BackCompat/BCFile/GetDeclarationNameTest.php @@ -32,7 +32,7 @@ class GetDeclarationNameTest extends UtilityMethodTestCase */ public function testInvalidTokenPassed() { - $this->expectPhpcsException('Token type "T_STRING" is not T_FUNCTION, T_CLASS, T_INTERFACE or T_TRAIT'); + $this->expectPhpcsException('Token type "T_STRING" is not T_FUNCTION, T_CLASS, T_INTERFACE, T_TRAIT or T_ENUM'); $target = $this->getTargetToken('/* testInvalidTokenPassed */', \T_STRING); BCFile::getDeclarationName(self::$phpcsFile, $target); @@ -85,11 +85,6 @@ public function dataGetDeclarationNameNull() '/* testAnonClassExtendsWithoutParens */', \T_ANON_CLASS, ], - - /* - * Note: this particular test *will* throw tokenizer "undefined offset" notices on PHPCS 2.6.0, - * but the test will pass. - */ 'live-coding' => [ '/* testLiveCoding */', \T_FUNCTION, diff --git a/Tests/BackCompat/BCFile/GetMemberPropertiesTest.php b/Tests/BackCompat/BCFile/GetMemberPropertiesTest.php index a913fbef..5d975a26 100644 --- a/Tests/BackCompat/BCFile/GetMemberPropertiesTest.php +++ b/Tests/BackCompat/BCFile/GetMemberPropertiesTest.php @@ -70,6 +70,9 @@ public function testGetMemberProperties($identifier, $expected) $expected['type_end_token'] += $variable; } + // Temporarily ignore the `is_readonly` key until support for readonly properties has been synced. + unset($result['is_readonly']); + $this->assertSame($expected, $result); } diff --git a/Tests/BackCompat/BCFile/GetMethodParametersParseError1Test.php b/Tests/BackCompat/BCFile/GetMethodParametersParseError1Test.php index cd86d071..0004fef7 100644 --- a/Tests/BackCompat/BCFile/GetMethodParametersParseError1Test.php +++ b/Tests/BackCompat/BCFile/GetMethodParametersParseError1Test.php @@ -12,6 +12,7 @@ use PHPCSUtils\BackCompat\BCFile; use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use PHPCSUtils\Tokens\Collections; /** * Tests for the \PHPCSUtils\BackCompat\BCFile::getMethodParameters method. @@ -32,7 +33,7 @@ class GetMethodParametersParseError1Test extends UtilityMethodTestCase */ public function testParseError() { - $target = $this->getTargetToken('/* testParseError */', [\T_FUNCTION, \T_CLOSURE]); + $target = $this->getTargetToken('/* testParseError */', Collections::functionDeclarationTokens()); $result = BCFile::getMethodParameters(self::$phpcsFile, $target); $this->assertSame([], $result); diff --git a/Tests/BackCompat/BCFile/GetMethodParametersParseError2Test.php b/Tests/BackCompat/BCFile/GetMethodParametersParseError2Test.php index 08da2c2d..bf8b911e 100644 --- a/Tests/BackCompat/BCFile/GetMethodParametersParseError2Test.php +++ b/Tests/BackCompat/BCFile/GetMethodParametersParseError2Test.php @@ -12,6 +12,7 @@ use PHPCSUtils\BackCompat\BCFile; use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use PHPCSUtils\Tokens\Collections; /** * Tests for the \PHPCSUtils\BackCompat\BCFile::getMethodParameters method. @@ -32,7 +33,7 @@ class GetMethodParametersParseError2Test extends UtilityMethodTestCase */ public function testParseError() { - $target = $this->getTargetToken('/* testParseError */', [\T_FUNCTION, \T_CLOSURE]); + $target = $this->getTargetToken('/* testParseError */', Collections::functionDeclarationTokens()); $result = BCFile::getMethodParameters(self::$phpcsFile, $target); $this->assertSame([], $result); diff --git a/Tests/BackCompat/BCFile/GetMethodParametersTest.php b/Tests/BackCompat/BCFile/GetMethodParametersTest.php index 4998e923..802c1794 100644 --- a/Tests/BackCompat/BCFile/GetMethodParametersTest.php +++ b/Tests/BackCompat/BCFile/GetMethodParametersTest.php @@ -25,7 +25,6 @@ use PHPCSUtils\BackCompat\BCFile; use PHPCSUtils\TestUtils\UtilityMethodTestCase; -use PHPCSUtils\Tokens\Collections; /** * Tests for the \PHPCSUtils\BackCompat\BCFile::getMethodParameters method. @@ -73,11 +72,11 @@ public function dataUnexpectedTokenException() ], 'function-call-fn-phpcs-3.5.3-3.5.4' => [ '/* testFunctionCallFnPHPCS353-354 */', - Collections::arrowFunctionTokensBC(), + [T_FN, T_STRING], ], 'fn-live-coding' => [ '/* testArrowFunctionLiveCoding */', - Collections::arrowFunctionTokensBC(), + [T_FN, T_STRING], ], ]; } @@ -123,11 +122,11 @@ public function dataInvalidUse() * * @param string $commentString The comment which preceeds the test. * @param array $targetTokenType Optional. The token type to search for after $commentString. - * Defaults to the function/closure tokens. + * Defaults to the function/closure/arrow tokens. * * @return void */ - public function testNoParams($commentString, $targetTokenType = [T_FUNCTION, T_CLOSURE]) + public function testNoParams($commentString, $targetTokenType = [T_FUNCTION, T_CLOSURE, \T_FN]) { $target = $this->getTargetToken($commentString, $targetTokenType); $result = BCFile::getMethodParameters(self::$phpcsFile, $target); @@ -481,9 +480,7 @@ public function testArrowFunction() 'comma_token' => false, ]; - $arrowTokenTypes = Collections::arrowFunctionTokensBC(); - - $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected, $arrowTokenTypes); + $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); } /** @@ -509,9 +506,7 @@ public function testArrowFunctionReturnByRef() 'comma_token' => false, ]; - $arrowTokenTypes = Collections::arrowFunctionTokensBC(); - - $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected, $arrowTokenTypes); + $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); } /** @@ -1127,9 +1122,7 @@ public function testArrowFunctionWithAllTypes() 'comma_token' => false, ]; - $arrowTokenTypes = Collections::arrowFunctionTokensBC(); - - $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected, $arrowTokenTypes); + $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); } /** @@ -1383,9 +1376,7 @@ public function testPHP8UnionTypesSimpleWithBitwiseOrInDefault() 'comma_token' => false, ]; - $arrowTokenTypes = Collections::arrowFunctionTokensBC(); - - $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected, $arrowTokenTypes); + $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); } /** @@ -1443,7 +1434,7 @@ public function testPHP8UnionTypesAllBaseTypes() } /** - * Verify recognition of PHP8 union type declaration with all pseudo types.. + * Verify recognition of PHP8 union type declaration with all pseudo types. * * Note: "Resource" is not a type, but seen as a class name. * @@ -1979,16 +1970,16 @@ public function testClosureUse() /** * Test helper. * - * @param string $commentString The comment which preceeds the test. - * @param array $expected The expected function output. - * @param array $targetType Optional. The token type to search for after $commentString. - * Defaults to the function/closure tokens. + * @param string $marker The comment which preceeds the test. + * @param array $expected The expected function output. + * @param array $targetType Optional. The token type to search for after $marker. + * Defaults to the function/closure/arrow tokens. * * @return void */ - protected function getMethodParametersTestHelper($commentString, $expected, $targetType = [T_FUNCTION, T_CLOSURE]) + protected function getMethodParametersTestHelper($marker, $expected, $targetType = [T_FUNCTION, T_CLOSURE, T_FN]) { - $target = $this->getTargetToken($commentString, $targetType); + $target = $this->getTargetToken($marker, $targetType); $found = BCFile::getMethodParameters(self::$phpcsFile, $target); foreach ($expected as $key => $param) { diff --git a/Tests/BackCompat/BCFile/GetMethodPropertiesTest.php b/Tests/BackCompat/BCFile/GetMethodPropertiesTest.php index ec24a9dd..4528a86a 100644 --- a/Tests/BackCompat/BCFile/GetMethodPropertiesTest.php +++ b/Tests/BackCompat/BCFile/GetMethodPropertiesTest.php @@ -22,7 +22,6 @@ use PHPCSUtils\BackCompat\BCFile; use PHPCSUtils\TestUtils\UtilityMethodTestCase; -use PHPCSUtils\Tokens\Collections; /** * Tests for the \PHPCSUtils\BackCompat\BCFile::getMethodProperties method. @@ -70,11 +69,11 @@ public function dataNotAFunctionException() ], 'function-call-fn-phpcs-3.5.3-3.5.4' => [ '/* testFunctionCallFnPHPCS353-354 */', - Collections::arrowFunctionTokensBC(), + [T_FN, T_STRING], ], 'fn-live-coding' => [ '/* testArrowFunctionLiveCoding */', - Collections::arrowFunctionTokensBC(), + [T_FN, T_STRING], ], ]; } @@ -496,9 +495,7 @@ public function testArrowFunction() 'has_body' => true, ]; - $arrowTokenTypes = Collections::arrowFunctionTokensBC(); - - $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected, $arrowTokenTypes); + $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); } /** @@ -640,9 +637,7 @@ public function testPHP8UnionTypesTwoClasses() 'has_body' => true, ]; - $arrowTokenTypes = Collections::arrowFunctionTokensBC(); - - $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected, $arrowTokenTypes); + $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); } /** @@ -902,9 +897,7 @@ public function testArrowFunctionArrayReturnValue() 'has_body' => true, ]; - $arrowTokenTypes = Collections::arrowFunctionTokensBC(); - - $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected, $arrowTokenTypes); + $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); } /** @@ -927,9 +920,7 @@ public function testArrowFunctionReturnByRef() 'has_body' => true, ]; - $arrowTokenTypes = Collections::arrowFunctionTokensBC(); - - $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected, $arrowTokenTypes); + $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); } /** @@ -942,8 +933,11 @@ public function testArrowFunctionReturnByRef() * * @return void */ - protected function getMethodPropertiesTestHelper($commentString, $expected, $targetType = [T_FUNCTION, T_CLOSURE]) - { + protected function getMethodPropertiesTestHelper( + $commentString, + $expected, + $targetType = [T_FUNCTION, T_CLOSURE, T_FN] + ) { $function = $this->getTargetToken($commentString, $targetType); $found = BCFile::getMethodProperties(self::$phpcsFile, $function); diff --git a/Tests/BackCompat/BCFile/IsReferenceTest.inc b/Tests/BackCompat/BCFile/IsReferenceTest.inc index e6fde219..93c7acc6 100644 --- a/Tests/BackCompat/BCFile/IsReferenceTest.inc +++ b/Tests/BackCompat/BCFile/IsReferenceTest.inc @@ -1,6 +1,8 @@ 1; + +/* testTokenizerIssue1284PHPCSlt280A */ +if ($foo) {} +[&$a, /* testTokenizerIssue1284PHPCSlt280B */ &$b] = $c; + +/* testTokenizerIssue1284PHPCSlt280C */ +if ($foo) {} +[&$a, $b]; diff --git a/Tests/BackCompat/BCFile/IsReferenceTest.php b/Tests/BackCompat/BCFile/IsReferenceTest.php index c02612fd..2bb169df 100644 --- a/Tests/BackCompat/BCFile/IsReferenceTest.php +++ b/Tests/BackCompat/BCFile/IsReferenceTest.php @@ -88,6 +88,14 @@ public function testIsReference($identifier, $expected) public function dataIsReference() { return [ + 'issue-1971-list-first-in-file' => [ + 'testMarker' => '/* testTokenizerIssue1971PHPCSlt330gt271A */', + 'expected' => true, + ], + 'issue-1971-list-first-in-file-nested' => [ + 'testMarker' => '/* testTokenizerIssue1971PHPCSlt330gt271B */', + 'expected' => true, + ], 'bitwise and: param in function call' => [ '/* testBitwiseAndA */', false, @@ -356,6 +364,18 @@ public function dataIsReference() '/* testBitwiseAndArrowFunctionInDefault */', false, ], + 'issue-1284-short-list-directly-after-close-curly-control-structure' => [ + 'testMarker' => '/* testTokenizerIssue1284PHPCSlt280A */', + 'expected' => true, + ], + 'issue-1284-short-list-directly-after-close-curly-control-structure-second-item' => [ + 'testMarker' => '/* testTokenizerIssue1284PHPCSlt280B */', + 'expected' => true, + ], + 'issue-1284-short-array-directly-after-close-curly-control-structure' => [ + 'testMarker' => '/* testTokenizerIssue1284PHPCSlt280C */', + 'expected' => true, + ], ]; } } diff --git a/Tests/BackCompat/BCTokens/ArithmeticTokensTest.php b/Tests/BackCompat/BCTokens/ArithmeticTokensTest.php deleted file mode 100644 index ba84d961..00000000 --- a/Tests/BackCompat/BCTokens/ArithmeticTokensTest.php +++ /dev/null @@ -1,61 +0,0 @@ - \T_PLUS, - \T_MINUS => \T_MINUS, - \T_MULTIPLY => \T_MULTIPLY, - \T_DIVIDE => \T_DIVIDE, - \T_MODULUS => \T_MODULUS, - \T_POW => \T_POW, - ]; - - $this->assertSame($expected, BCTokens::arithmeticTokens()); - } - - /** - * Test whether the method in BCTokens is still in sync with the latest version of PHPCS. - * - * This group is not run by default and has to be specifically requested to be run. - * - * @group compareWithPHPCS - * - * @return void - */ - public function testPHPCSArithmeticTokens() - { - $this->assertSame(Tokens::$arithmeticTokens, BCTokens::arithmeticTokens()); - } -} diff --git a/Tests/BackCompat/BCTokens/AssignmentTokensTest.php b/Tests/BackCompat/BCTokens/AssignmentTokensTest.php deleted file mode 100644 index 9ac38c8c..00000000 --- a/Tests/BackCompat/BCTokens/AssignmentTokensTest.php +++ /dev/null @@ -1,81 +0,0 @@ - \T_EQUAL, - \T_AND_EQUAL => \T_AND_EQUAL, - \T_OR_EQUAL => \T_OR_EQUAL, - \T_CONCAT_EQUAL => \T_CONCAT_EQUAL, - \T_DIV_EQUAL => \T_DIV_EQUAL, - \T_MINUS_EQUAL => \T_MINUS_EQUAL, - \T_POW_EQUAL => \T_POW_EQUAL, - \T_MOD_EQUAL => \T_MOD_EQUAL, - \T_MUL_EQUAL => \T_MUL_EQUAL, - \T_PLUS_EQUAL => \T_PLUS_EQUAL, - \T_XOR_EQUAL => \T_XOR_EQUAL, - \T_DOUBLE_ARROW => \T_DOUBLE_ARROW, - \T_SL_EQUAL => \T_SL_EQUAL, - \T_SR_EQUAL => \T_SR_EQUAL, - ]; - - if (\version_compare($version, '2.8.1', '>=') === true - || \version_compare(\PHP_VERSION_ID, '70399', '>=') === true - ) { - $expected[\T_COALESCE_EQUAL] = \T_COALESCE_EQUAL; - } - - if (\version_compare($version, '2.8.0', '>=') === true) { - $expected[\T_ZSR_EQUAL] = \T_ZSR_EQUAL; - } - - $this->assertSame($expected, BCTokens::assignmentTokens()); - } - - /** - * Test whether the method in BCTokens is still in sync with the latest version of PHPCS. - * - * This group is not run by default and has to be specifically requested to be run. - * - * @group compareWithPHPCS - * - * @return void - */ - public function testPHPCSAssignmentTokens() - { - $this->assertSame(Tokens::$assignmentTokens, BCTokens::assignmentTokens()); - } -} diff --git a/Tests/BackCompat/BCTokens/ComparisonTokensTest.php b/Tests/BackCompat/BCTokens/ComparisonTokensTest.php deleted file mode 100644 index ad7ee706..00000000 --- a/Tests/BackCompat/BCTokens/ComparisonTokensTest.php +++ /dev/null @@ -1,72 +0,0 @@ - \T_IS_EQUAL, - \T_IS_IDENTICAL => \T_IS_IDENTICAL, - \T_IS_NOT_EQUAL => \T_IS_NOT_EQUAL, - \T_IS_NOT_IDENTICAL => \T_IS_NOT_IDENTICAL, - \T_LESS_THAN => \T_LESS_THAN, - \T_GREATER_THAN => \T_GREATER_THAN, - \T_IS_SMALLER_OR_EQUAL => \T_IS_SMALLER_OR_EQUAL, - \T_IS_GREATER_OR_EQUAL => \T_IS_GREATER_OR_EQUAL, - \T_SPACESHIP => \T_SPACESHIP, - ]; - - if (\version_compare($version, '2.6.1', '>=') === true - || \version_compare(\PHP_VERSION_ID, '60999', '>=') === true - ) { - $expected[\T_COALESCE] = \T_COALESCE; - } - - $this->assertSame($expected, BCTokens::comparisonTokens()); - } - - /** - * Test whether the method in BCTokens is still in sync with the latest version of PHPCS. - * - * This group is not run by default and has to be specifically requested to be run. - * - * @group compareWithPHPCS - * - * @return void - */ - public function testPHPCSComparisonTokens() - { - $this->assertSame(Tokens::$comparisonTokens, BCTokens::comparisonTokens()); - } -} diff --git a/Tests/BackCompat/BCTokens/EmptyTokensTest.php b/Tests/BackCompat/BCTokens/EmptyTokensTest.php deleted file mode 100644 index 3788d3b5..00000000 --- a/Tests/BackCompat/BCTokens/EmptyTokensTest.php +++ /dev/null @@ -1,163 +0,0 @@ - => - */ - protected $commentTokens = [ - \T_COMMENT => \T_COMMENT, - \T_DOC_COMMENT => \T_DOC_COMMENT, - \T_DOC_COMMENT_STAR => \T_DOC_COMMENT_STAR, - \T_DOC_COMMENT_WHITESPACE => \T_DOC_COMMENT_WHITESPACE, - \T_DOC_COMMENT_TAG => \T_DOC_COMMENT_TAG, - \T_DOC_COMMENT_OPEN_TAG => \T_DOC_COMMENT_OPEN_TAG, - \T_DOC_COMMENT_CLOSE_TAG => \T_DOC_COMMENT_CLOSE_TAG, - \T_DOC_COMMENT_STRING => \T_DOC_COMMENT_STRING, - ]; - - /** - * Token types that are comments containing PHPCS instructions. - * - * @var array => - */ - protected $phpcsCommentTokens = [ - 'PHPCS_T_PHPCS_ENABLE' => 'PHPCS_T_PHPCS_ENABLE', - 'PHPCS_T_PHPCS_DISABLE' => 'PHPCS_T_PHPCS_DISABLE', - 'PHPCS_T_PHPCS_SET' => 'PHPCS_T_PHPCS_SET', - 'PHPCS_T_PHPCS_IGNORE' => 'PHPCS_T_PHPCS_IGNORE', - 'PHPCS_T_PHPCS_IGNORE_FILE' => 'PHPCS_T_PHPCS_IGNORE_FILE', - ]; - - /** - * Test the Tokens::emptyTokens() method. - * - * @covers ::__callStatic - * - * @return void - */ - public function testEmptyTokens() - { - $version = Helper::getVersion(); - $expected = [\T_WHITESPACE => \T_WHITESPACE] + $this->commentTokens; - - if (\version_compare($version, '3.2.0', '>=') === true) { - $expected += $this->phpcsCommentTokens; - } - - $this->assertSame($expected, BCTokens::emptyTokens()); - } - - /** - * Test the Tokens::commentTokens() method. - * - * @covers ::__callStatic - * - * @return void - */ - public function testCommentTokens() - { - $version = Helper::getVersion(); - $expected = $this->commentTokens; - - if (\version_compare($version, '3.2.0', '>=') === true) { - $expected += $this->phpcsCommentTokens; - } - - $this->assertSame($expected, BCTokens::commentTokens()); - } - - /** - * Test the Tokens::phpcsCommentTokens() method. - * - * @covers ::phpcsCommentTokens - * - * @return void - */ - public function testPhpcsCommentTokens() - { - $version = Helper::getVersion(); - $expected = []; - - if (\version_compare($version, '3.2.0', '>=') === true) { - $expected = $this->phpcsCommentTokens; - } - - $this->assertSame($expected, BCTokens::phpcsCommentTokens()); - } - - /** - * Test whether the method in BCTokens is still in sync with the latest version of PHPCS. - * - * This group is not run by default and has to be specifically requested to be run. - * - * @group compareWithPHPCS - * - * @covers ::__callStatic - * - * @return void - */ - public function testPHPCSEmptyTokens() - { - $this->assertSame(Tokens::$emptyTokens, BCTokens::emptyTokens()); - } - - /** - * Test whether the method in BCTokens is still in sync with the latest version of PHPCS. - * - * This group is not run by default and has to be specifically requested to be run. - * - * @group compareWithPHPCS - * - * @covers ::__callStatic - * - * @return void - */ - public function testPHPCSUpstreamCommentTokens() - { - $this->assertSame(Tokens::$commentTokens, BCTokens::commentTokens()); - } - - /** - * Test whether the method in BCTokens is still in sync with the latest version of PHPCS. - * - * This group is not run by default and has to be specifically requested to be run. - * - * @group compareWithPHPCS - * - * @covers ::phpcsCommentTokens - * - * @return void - */ - public function testPHPCSPhpcsCommentTokens() - { - $this->assertSame(Tokens::$phpcsCommentTokens, BCTokens::phpcsCommentTokens()); - } -} diff --git a/Tests/BackCompat/BCTokens/FunctionNameTokensTest.php b/Tests/BackCompat/BCTokens/FunctionNameTokensTest.php index 5dbfb895..03a43262 100644 --- a/Tests/BackCompat/BCTokens/FunctionNameTokensTest.php +++ b/Tests/BackCompat/BCTokens/FunctionNameTokensTest.php @@ -34,31 +34,25 @@ class FunctionNameTokensTest extends TestCase */ public function testFunctionNameTokens() { - $version = Helper::getVersion(); $expected = [ - \T_STRING => \T_STRING, - \T_EVAL => \T_EVAL, - \T_EXIT => \T_EXIT, - \T_INCLUDE => \T_INCLUDE, - \T_INCLUDE_ONCE => \T_INCLUDE_ONCE, - \T_REQUIRE => \T_REQUIRE, - \T_REQUIRE_ONCE => \T_REQUIRE_ONCE, - \T_ISSET => \T_ISSET, - \T_UNSET => \T_UNSET, - \T_EMPTY => \T_EMPTY, - \T_SELF => \T_SELF, - \T_STATIC => \T_STATIC, - \T_PARENT => \T_PARENT, + \T_STRING => \T_STRING, + \T_EVAL => \T_EVAL, + \T_EXIT => \T_EXIT, + \T_INCLUDE => \T_INCLUDE, + \T_INCLUDE_ONCE => \T_INCLUDE_ONCE, + \T_REQUIRE => \T_REQUIRE, + \T_REQUIRE_ONCE => \T_REQUIRE_ONCE, + \T_ISSET => \T_ISSET, + \T_UNSET => \T_UNSET, + \T_EMPTY => \T_EMPTY, + \T_SELF => \T_SELF, + \T_STATIC => \T_STATIC, + \T_PARENT => \T_PARENT, + \T_NAME_QUALIFIED => \T_NAME_QUALIFIED, + \T_NAME_FULLY_QUALIFIED => \T_NAME_FULLY_QUALIFIED, + \T_NAME_RELATIVE => \T_NAME_RELATIVE, ]; - if (\version_compare(\PHP_VERSION_ID, '80000', '>=') === true - || \version_compare($version, '3.5.7', '>=') === true - ) { - $expected[\T_NAME_QUALIFIED] = \T_NAME_QUALIFIED; - $expected[\T_NAME_FULLY_QUALIFIED] = \T_NAME_FULLY_QUALIFIED; - $expected[\T_NAME_RELATIVE] = \T_NAME_RELATIVE; - } - \asort($expected); $result = BCTokens::functionNameTokens(); @@ -87,14 +81,10 @@ public function testPHPCSFunctionNameTokens() * Don't fail this test on the difference between PHPCS 4.x and 3.x. * This test is only run against `dev-master` and `dev-master` is still PHPCS 3.x. */ - $expected = Tokens::$functionNameTokens; - if (\version_compare(\PHP_VERSION_ID, '80000', '>=') === true - || \version_compare($version, '3.5.7', '>=') === true - ) { - $expected[\T_NAME_QUALIFIED] = \T_NAME_QUALIFIED; - $expected[\T_NAME_FULLY_QUALIFIED] = \T_NAME_FULLY_QUALIFIED; - $expected[\T_NAME_RELATIVE] = \T_NAME_RELATIVE; - } + $expected = Tokens::$functionNameTokens; + $expected[\T_NAME_QUALIFIED] = \T_NAME_QUALIFIED; + $expected[\T_NAME_FULLY_QUALIFIED] = \T_NAME_FULLY_QUALIFIED; + $expected[\T_NAME_RELATIVE] = \T_NAME_RELATIVE; \asort($expected); diff --git a/Tests/BackCompat/BCTokens/MagicConstantsTest.php b/Tests/BackCompat/BCTokens/MagicConstantsTest.php deleted file mode 100644 index 8730ccf2..00000000 --- a/Tests/BackCompat/BCTokens/MagicConstantsTest.php +++ /dev/null @@ -1,63 +0,0 @@ - \T_CLASS_C, - \T_DIR => \T_DIR, - \T_FILE => \T_FILE, - \T_FUNC_C => \T_FUNC_C, - \T_LINE => \T_LINE, - \T_METHOD_C => \T_METHOD_C, - \T_NS_C => \T_NS_C, - \T_TRAIT_C => \T_TRAIT_C, - ]; - - $this->assertSame($expected, BCTokens::magicConstants()); - } - - /** - * Test whether the method in BCTokens is still in sync with the latest version of PHPCS. - * - * This group is not run by default and has to be specifically requested to be run. - * - * @group compareWithPHPCS - * - * @return void - */ - public function testPHPCSMagicConstants() - { - $this->assertSame(Tokens::$magicConstants, BCTokens::magicConstants()); - } -} diff --git a/Tests/BackCompat/BCTokens/OoScopeTokensTest.php b/Tests/BackCompat/BCTokens/OoScopeTokensTest.php deleted file mode 100644 index 82db8499..00000000 --- a/Tests/BackCompat/BCTokens/OoScopeTokensTest.php +++ /dev/null @@ -1,72 +0,0 @@ - \T_CLASS, - \T_ANON_CLASS => \T_ANON_CLASS, - \T_INTERFACE => \T_INTERFACE, - \T_TRAIT => \T_TRAIT, - ]; - - if (\version_compare($version, '3.7.0', '>=') === true - || \version_compare(\PHP_VERSION_ID, '80099', '>=') === true - ) { - $expected[\T_ENUM] = \T_ENUM; - } - - \asort($expected); - - $result = BCTokens::ooScopeTokens(); - \asort($result); - - $this->assertSame($expected, $result); - } - - /** - * Test whether the method in BCTokens is still in sync with the latest version of PHPCS. - * - * This group is not run by default and has to be specifically requested to be run. - * - * @group compareWithPHPCS - * - * @return void - */ - public function testPHPCSOoScopeTokens() - { - $this->assertSame(Tokens::$ooScopeTokens, BCTokens::ooScopeTokens()); - } -} diff --git a/Tests/BackCompat/BCTokens/OperatorsTest.php b/Tests/BackCompat/BCTokens/OperatorsTest.php deleted file mode 100644 index f020a875..00000000 --- a/Tests/BackCompat/BCTokens/OperatorsTest.php +++ /dev/null @@ -1,80 +0,0 @@ - \T_MINUS, - \T_PLUS => \T_PLUS, - \T_MULTIPLY => \T_MULTIPLY, - \T_DIVIDE => \T_DIVIDE, - \T_MODULUS => \T_MODULUS, - \T_POW => \T_POW, - \T_SPACESHIP => \T_SPACESHIP, - \T_BITWISE_AND => \T_BITWISE_AND, - \T_BITWISE_OR => \T_BITWISE_OR, - \T_BITWISE_XOR => \T_BITWISE_XOR, - \T_SL => \T_SL, - \T_SR => \T_SR, - ]; - - if (\version_compare($version, '2.6.1', '>=') === true - || \version_compare(\PHP_VERSION_ID, '60999', '>=') === true - ) { - $expected[\T_COALESCE] = \T_COALESCE; - } - - \asort($expected); - - $result = BCTokens::operators(); - \asort($result); - - $this->assertSame($expected, $result); - } - - /** - * Test whether the method in BCTokens is still in sync with the latest version of PHPCS. - * - * This group is not run by default and has to be specifically requested to be run. - * - * @group compareWithPHPCS - * - * @return void - */ - public function testPHPCSOperators() - { - $this->assertSame(Tokens::$operators, BCTokens::operators()); - } -} diff --git a/Tests/BackCompat/BCTokens/ParenthesisOpenersTest.php b/Tests/BackCompat/BCTokens/ParenthesisOpenersTest.php index 016d245b..b99584b1 100644 --- a/Tests/BackCompat/BCTokens/ParenthesisOpenersTest.php +++ b/Tests/BackCompat/BCTokens/ParenthesisOpenersTest.php @@ -18,7 +18,7 @@ /** * Test class. * - * @covers \PHPCSUtils\BackCompat\BCTokens::parenthesisOpeners + * @covers \PHPCSUtils\BackCompat\BCTokens::__callStatic * * @group tokens * @@ -49,15 +49,10 @@ public function testParenthesisOpeners() \T_ELSEIF => \T_ELSEIF, \T_CATCH => \T_CATCH, \T_DECLARE => \T_DECLARE, + \T_MATCH => \T_MATCH, ]; - if (\version_compare($version, '3.6.0', '>=') === true - || \version_compare(\PHP_VERSION_ID, '70999', '>=') === true - ) { - $expected[\T_MATCH] = \T_MATCH; - } - - if (\version_compare($version, '4.0.0', '>=') === true) { + if (\version_compare($version, '3.99.99', '>=') === true) { $expected[\T_USE] = \T_USE; } diff --git a/Tests/BackCompat/BCTokens/ScopeOpenersTest.php b/Tests/BackCompat/BCTokens/ScopeOpenersTest.php deleted file mode 100644 index b4ef1f17..00000000 --- a/Tests/BackCompat/BCTokens/ScopeOpenersTest.php +++ /dev/null @@ -1,98 +0,0 @@ - \T_CLASS, - \T_ANON_CLASS => \T_ANON_CLASS, - \T_INTERFACE => \T_INTERFACE, - \T_TRAIT => \T_TRAIT, - \T_NAMESPACE => \T_NAMESPACE, - \T_FUNCTION => \T_FUNCTION, - \T_CLOSURE => \T_CLOSURE, - \T_IF => \T_IF, - \T_SWITCH => \T_SWITCH, - \T_CASE => \T_CASE, - \T_DECLARE => \T_DECLARE, - \T_DEFAULT => \T_DEFAULT, - \T_WHILE => \T_WHILE, - \T_ELSE => \T_ELSE, - \T_ELSEIF => \T_ELSEIF, - \T_FOR => \T_FOR, - \T_FOREACH => \T_FOREACH, - \T_DO => \T_DO, - \T_TRY => \T_TRY, - \T_CATCH => \T_CATCH, - \T_FINALLY => \T_FINALLY, - \T_PROPERTY => \T_PROPERTY, - \T_OBJECT => \T_OBJECT, - \T_USE => \T_USE, - ]; - - if (\version_compare($version, '3.6.0', '>=') === true - || \version_compare(\PHP_VERSION_ID, '70999', '>=') === true - ) { - $expected[\T_MATCH] = \T_MATCH; - } - - if (\version_compare($version, '3.7.0', '>=') === true - || \version_compare(\PHP_VERSION_ID, '80099', '>=') === true - ) { - $expected[\T_ENUM] = \T_ENUM; - } - - \asort($expected); - - $result = BCTokens::scopeOpeners(); - \asort($result); - - $this->assertSame($expected, $result); - } - - /** - * Test whether the method in BCTokens is still in sync with the latest version of PHPCS. - * - * This group is not run by default and has to be specifically requested to be run. - * - * @group compareWithPHPCS - * - * @return void - */ - public function testPHPCSScopeOpeners() - { - $this->assertSame(Tokens::$scopeOpeners, BCTokens::scopeOpeners()); - } -} diff --git a/Tests/BackCompat/BCTokens/TextStringTokensTest.php b/Tests/BackCompat/BCTokens/TextStringTokensTest.php deleted file mode 100644 index 93fb3ac2..00000000 --- a/Tests/BackCompat/BCTokens/TextStringTokensTest.php +++ /dev/null @@ -1,60 +0,0 @@ - \T_CONSTANT_ENCAPSED_STRING, - \T_DOUBLE_QUOTED_STRING => \T_DOUBLE_QUOTED_STRING, - \T_INLINE_HTML => \T_INLINE_HTML, - \T_HEREDOC => \T_HEREDOC, - \T_NOWDOC => \T_NOWDOC, - ]; - - $this->assertSame($expected, BCTokens::textStringTokens()); - } - - /** - * Test whether the method in BCTokens is still in sync with the latest version of PHPCS. - * - * This group is not run by default and has to be specifically requested to be run. - * - * @group compareWithPHPCS - * - * @return void - */ - public function testPHPCSTextStringTokens() - { - $this->assertSame(Tokens::$textStringTokens, BCTokens::textStringTokens()); - } -} diff --git a/Tests/BackCompat/BCTokens/UnchangedTokenArraysTest.php b/Tests/BackCompat/BCTokens/UnchangedTokenArraysTest.php index 656739ef..f2ff52ef 100644 --- a/Tests/BackCompat/BCTokens/UnchangedTokenArraysTest.php +++ b/Tests/BackCompat/BCTokens/UnchangedTokenArraysTest.php @@ -26,6 +26,30 @@ class UnchangedTokenArraysTest extends TestCase { + /** + * Tokens that represent assignments. + * + * @var array + */ + private $assignmentTokens = [ + \T_EQUAL => \T_EQUAL, + \T_AND_EQUAL => \T_AND_EQUAL, + \T_OR_EQUAL => \T_OR_EQUAL, + \T_CONCAT_EQUAL => \T_CONCAT_EQUAL, + \T_DIV_EQUAL => \T_DIV_EQUAL, + \T_MINUS_EQUAL => \T_MINUS_EQUAL, + \T_POW_EQUAL => \T_POW_EQUAL, + \T_MOD_EQUAL => \T_MOD_EQUAL, + \T_MUL_EQUAL => \T_MUL_EQUAL, + \T_PLUS_EQUAL => \T_PLUS_EQUAL, + \T_XOR_EQUAL => \T_XOR_EQUAL, + \T_DOUBLE_ARROW => \T_DOUBLE_ARROW, + \T_SL_EQUAL => \T_SL_EQUAL, + \T_SR_EQUAL => \T_SR_EQUAL, + \T_COALESCE_EQUAL => \T_COALESCE_EQUAL, + \T_ZSR_EQUAL => \T_ZSR_EQUAL, + ]; + /** * Tokens that represent equality comparisons. * @@ -40,6 +64,59 @@ class UnchangedTokenArraysTest extends TestCase \T_IS_GREATER_OR_EQUAL => \T_IS_GREATER_OR_EQUAL, ]; + /** + * Tokens that represent comparison operator. + * + * @var array + */ + private $comparisonTokens = [ + \T_IS_EQUAL => \T_IS_EQUAL, + \T_IS_IDENTICAL => \T_IS_IDENTICAL, + \T_IS_NOT_EQUAL => \T_IS_NOT_EQUAL, + \T_IS_NOT_IDENTICAL => \T_IS_NOT_IDENTICAL, + \T_LESS_THAN => \T_LESS_THAN, + \T_GREATER_THAN => \T_GREATER_THAN, + \T_IS_SMALLER_OR_EQUAL => \T_IS_SMALLER_OR_EQUAL, + \T_IS_GREATER_OR_EQUAL => \T_IS_GREATER_OR_EQUAL, + \T_SPACESHIP => \T_SPACESHIP, + \T_COALESCE => \T_COALESCE, + ]; + + /** + * Tokens that represent arithmetic operators. + * + * @var array + */ + private $arithmeticTokens = [ + \T_PLUS => \T_PLUS, + \T_MINUS => \T_MINUS, + \T_MULTIPLY => \T_MULTIPLY, + \T_DIVIDE => \T_DIVIDE, + \T_MODULUS => \T_MODULUS, + \T_POW => \T_POW, + ]; + + /** + * Tokens that perform operations. + * + * @var array + */ + private $operators = [ + \T_MINUS => \T_MINUS, + \T_PLUS => \T_PLUS, + \T_MULTIPLY => \T_MULTIPLY, + \T_DIVIDE => \T_DIVIDE, + \T_MODULUS => \T_MODULUS, + \T_POW => \T_POW, + \T_SPACESHIP => \T_SPACESHIP, + \T_COALESCE => \T_COALESCE, + \T_BITWISE_AND => \T_BITWISE_AND, + \T_BITWISE_OR => \T_BITWISE_OR, + \T_BITWISE_XOR => \T_BITWISE_XOR, + \T_SL => \T_SL, + \T_SR => \T_SR, + ]; + /** * Tokens that perform boolean operations. * @@ -69,6 +146,40 @@ class UnchangedTokenArraysTest extends TestCase \T_BINARY_CAST => \T_BINARY_CAST, ]; + /** + * Tokens that are allowed to open scopes. + * + * @var array + */ + private $scopeOpeners = [ + \T_CLASS => \T_CLASS, + \T_ANON_CLASS => \T_ANON_CLASS, + \T_INTERFACE => \T_INTERFACE, + \T_TRAIT => \T_TRAIT, + \T_ENUM => \T_ENUM, + \T_NAMESPACE => \T_NAMESPACE, + \T_FUNCTION => \T_FUNCTION, + \T_CLOSURE => \T_CLOSURE, + \T_IF => \T_IF, + \T_SWITCH => \T_SWITCH, + \T_CASE => \T_CASE, + \T_DECLARE => \T_DECLARE, + \T_DEFAULT => \T_DEFAULT, + \T_WHILE => \T_WHILE, + \T_ELSE => \T_ELSE, + \T_ELSEIF => \T_ELSEIF, + \T_FOR => \T_FOR, + \T_FOREACH => \T_FOREACH, + \T_DO => \T_DO, + \T_TRY => \T_TRY, + \T_CATCH => \T_CATCH, + \T_FINALLY => \T_FINALLY, + \T_PROPERTY => \T_PROPERTY, + \T_OBJECT => \T_OBJECT, + \T_USE => \T_USE, + \T_MATCH => \T_MATCH, + ]; + /** * Tokens that represent scope modifiers. * @@ -106,6 +217,62 @@ class UnchangedTokenArraysTest extends TestCase \T_OBJECT => \T_OBJECT, ]; + /** + * Tokens that don't represent code. + * + * @var array + */ + private $emptyTokens = [ + \T_WHITESPACE => \T_WHITESPACE, + \T_COMMENT => \T_COMMENT, + \T_DOC_COMMENT => \T_DOC_COMMENT, + \T_DOC_COMMENT_STAR => \T_DOC_COMMENT_STAR, + \T_DOC_COMMENT_WHITESPACE => \T_DOC_COMMENT_WHITESPACE, + \T_DOC_COMMENT_TAG => \T_DOC_COMMENT_TAG, + \T_DOC_COMMENT_OPEN_TAG => \T_DOC_COMMENT_OPEN_TAG, + \T_DOC_COMMENT_CLOSE_TAG => \T_DOC_COMMENT_CLOSE_TAG, + \T_DOC_COMMENT_STRING => \T_DOC_COMMENT_STRING, + \T_PHPCS_ENABLE => \T_PHPCS_ENABLE, + \T_PHPCS_DISABLE => \T_PHPCS_DISABLE, + \T_PHPCS_SET => \T_PHPCS_SET, + \T_PHPCS_IGNORE => \T_PHPCS_IGNORE, + \T_PHPCS_IGNORE_FILE => \T_PHPCS_IGNORE_FILE, + ]; + + /** + * Tokens that are comments. + * + * @var array + */ + private $commentTokens = [ + \T_COMMENT => \T_COMMENT, + \T_DOC_COMMENT => \T_DOC_COMMENT, + \T_DOC_COMMENT_STAR => \T_DOC_COMMENT_STAR, + \T_DOC_COMMENT_WHITESPACE => \T_DOC_COMMENT_WHITESPACE, + \T_DOC_COMMENT_TAG => \T_DOC_COMMENT_TAG, + \T_DOC_COMMENT_OPEN_TAG => \T_DOC_COMMENT_OPEN_TAG, + \T_DOC_COMMENT_CLOSE_TAG => \T_DOC_COMMENT_CLOSE_TAG, + \T_DOC_COMMENT_STRING => \T_DOC_COMMENT_STRING, + \T_PHPCS_ENABLE => \T_PHPCS_ENABLE, + \T_PHPCS_DISABLE => \T_PHPCS_DISABLE, + \T_PHPCS_SET => \T_PHPCS_SET, + \T_PHPCS_IGNORE => \T_PHPCS_IGNORE, + \T_PHPCS_IGNORE_FILE => \T_PHPCS_IGNORE_FILE, + ]; + + /** + * Tokens that are comments containing PHPCS instructions. + * + * @var array + */ + private $phpcsCommentTokens = [ + \T_PHPCS_ENABLE => \T_PHPCS_ENABLE, + \T_PHPCS_DISABLE => \T_PHPCS_DISABLE, + \T_PHPCS_SET => \T_PHPCS_SET, + \T_PHPCS_IGNORE => \T_PHPCS_IGNORE, + \T_PHPCS_IGNORE_FILE => \T_PHPCS_IGNORE_FILE, + ]; + /** * Tokens that represent strings. * @@ -116,6 +283,19 @@ class UnchangedTokenArraysTest extends TestCase \T_DOUBLE_QUOTED_STRING => \T_DOUBLE_QUOTED_STRING, ]; + /** + * Tokens that represent text strings. + * + * @var array + */ + private $textStringTokens = [ + \T_CONSTANT_ENCAPSED_STRING => \T_CONSTANT_ENCAPSED_STRING, + \T_DOUBLE_QUOTED_STRING => \T_DOUBLE_QUOTED_STRING, + \T_INLINE_HTML => \T_INLINE_HTML, + \T_HEREDOC => \T_HEREDOC, + \T_NOWDOC => \T_NOWDOC, + ]; + /** * Tokens that represent brackets and parenthesis. * @@ -156,6 +336,37 @@ class UnchangedTokenArraysTest extends TestCase \T_NOWDOC => \T_NOWDOC, ]; + /** + * Tokens that open class and object scopes. + * + * @var array + */ + private $ooScopeTokens = [ + \T_CLASS => \T_CLASS, + \T_ANON_CLASS => \T_ANON_CLASS, + \T_INTERFACE => \T_INTERFACE, + \T_TRAIT => \T_TRAIT, + \T_ENUM => \T_ENUM, + ]; + + /** + * Tokens representing PHP magic constants. + * + * @var array => + * + * @link https://www.php.net/language.constants.predefined PHP Manual on magic constants + */ + private $magicConstants = [ + \T_CLASS_C => \T_CLASS_C, + \T_DIR => \T_DIR, + \T_FILE => \T_FILE, + \T_FUNC_C => \T_FUNC_C, + \T_LINE => \T_LINE, + \T_METHOD_C => \T_METHOD_C, + \T_NS_C => \T_NS_C, + \T_TRAIT_C => \T_TRAIT_C, + ]; + /** * Test the method. * diff --git a/Tests/BackCompat/Helper/ConfigDataTest.php b/Tests/BackCompat/Helper/ConfigDataTest.php index 50b4f6d9..0ca8ecf2 100644 --- a/Tests/BackCompat/Helper/ConfigDataTest.php +++ b/Tests/BackCompat/Helper/ConfigDataTest.php @@ -36,10 +36,6 @@ class ConfigDataTest extends TestCase */ public function testConfigData34() { - if (\version_compare(Helper::getVersion(), '2.99.99', '<=') === true) { - $this->markTestSkipped('Test only applicable to PHPCS > 2.x'); - } - $config = new Config(); $original = Helper::getConfigData('arbitrary_name'); $expected = 'expected'; @@ -59,7 +55,7 @@ public function testConfigData34() * * @return void */ - public function testConfigDataPHPCS23() + public function testConfigDataPHPCS3() { if (\version_compare(Helper::getVersion(), '3.99.99', '>') === true) { $this->markTestSkipped('Test only applicable to PHPCS < 4.x'); diff --git a/Tests/BackCompat/Helper/GetCommandLineDataTest.php b/Tests/BackCompat/Helper/GetCommandLineDataTest.php index 3330c1b7..fa04ef61 100644 --- a/Tests/BackCompat/Helper/GetCommandLineDataTest.php +++ b/Tests/BackCompat/Helper/GetCommandLineDataTest.php @@ -47,14 +47,9 @@ public static function setUpTestFile() */ public function testGetCommandLineData() { - // Use the default values which are different across PHPCS versions. $expected = 'utf-8'; - if (\version_compare(static::$phpcsVersion, '2.99.99', '<=') === true) { - // Will effectively come down to `iso-8859-1`. - $expected = null; - } + $result = Helper::getCommandLineData(self::$phpcsFile, 'encoding'); - $result = Helper::getCommandLineData(self::$phpcsFile, 'encoding'); $this->assertSame($expected, $result); } @@ -80,26 +75,19 @@ public function testGetCommandLineDataNull() */ public function testGetTabWidth() { + self::$phpcsFile->config->tabWidth = null; + $result = Helper::getTabWidth(self::$phpcsFile); $this->assertSame(4, $result, 'Failed retrieving the default tab width'); - if (\version_compare(static::$phpcsVersion, '2.99.99', '>') === true) { - // PHPCS 3.x. - self::$phpcsFile->config->tabWidth = 2; - } else { - // PHPCS 2.x. - self::$phpcsFile->phpcs->cli->setCommandLineValues(['--tab-width=2']); - } + self::$phpcsFile->config->tabWidth = 2; $result = Helper::getTabWidth(self::$phpcsFile); - $this->assertSame(2, $result, 'Failed retrieving the custom set tab width'); - // Restore defaults before moving to the next test. - if (\version_compare(static::$phpcsVersion, '2.99.99', '>') === true) { - self::$phpcsFile->config->restoreDefaults(); - } else { - self::$phpcsFile->phpcs->cli->setCommandLineValues(['--tab-width=4']); - } + // Restore default before moving to the next test. + self::$phpcsFile->config->restoreDefaults(); + + $this->assertSame(2, $result, 'Failed retrieving the custom set tab width'); } /** @@ -111,27 +99,20 @@ public function testGetTabWidth() */ public function testGetEncoding() { + self::$phpcsFile->config->encoding = null; + $result = Helper::getEncoding(self::$phpcsFile); - $expected = \version_compare(static::$phpcsVersion, '2.99.99', '>') ? 'utf-8' : 'iso-8859-1'; + $expected = 'utf-8'; $this->assertSame($expected, $result, 'Failed retrieving the default encoding'); - if (\version_compare(static::$phpcsVersion, '2.99.99', '>') === true) { - // PHPCS 3.x. - self::$phpcsFile->config->encoding = 'utf-16'; - } else { - // PHPCS 2.x. - self::$phpcsFile->phpcs->cli->setCommandLineValues(['--encoding=utf-16']); - } + self::$phpcsFile->config->encoding = 'utf-16'; $result = Helper::getEncoding(self::$phpcsFile); - $this->assertSame('utf-16', $result, 'Failed retrieving the custom set encoding'); - // Restore defaults before moving to the next test. - if (\version_compare(static::$phpcsVersion, '2.99.99', '>') === true) { - self::$phpcsFile->config->restoreDefaults(); - } else { - self::$phpcsFile->phpcs->cli->setCommandLineValues(['--encoding=iso-8859-1']); - } + // Restore default before moving to the next test. + self::$phpcsFile->config->restoreDefaults(); + + $this->assertSame('utf-16', $result, 'Failed retrieving the custom set encoding'); } /** @@ -143,42 +124,20 @@ public function testGetEncoding() */ public function testGetEncodingWithoutPHPCSFile() { + self::$phpcsFile->config->encoding = null; + $result = Helper::getEncoding(); - $expected = \version_compare(static::$phpcsVersion, '2.99.99', '>') ? 'utf-8' : 'iso-8859-1'; + $expected = 'utf-8'; $this->assertSame($expected, $result, 'Failed retrieving the default encoding'); - $config = null; - if (isset(self::$phpcsFile->config) === true) { - $config = self::$phpcsFile->config; - } - - Helper::setConfigData('encoding', 'utf-16', true, $config); + Helper::setConfigData('encoding', 'utf-16', true, self::$phpcsFile->config); $result = Helper::getEncoding(); - $this->assertSame('utf-16', $result, 'Failed retrieving the custom set encoding'); // Restore defaults before moving to the next test. - if (\version_compare(static::$phpcsVersion, '2.99.99', '>') === true) { - Helper::setConfigData('encoding', 'utf-8', true, $config); - } else { - Helper::setConfigData('encoding', 'iso-8859-1', true, $config); - } - } - - /** - * Test the ignoreAnnotations() method. - * - * @covers ::ignoreAnnotations - * - * @return void - */ - public function testIgnoreAnnotationsV2() - { - if (\version_compare(static::$phpcsVersion, '2.99.99', '>') === true) { - $this->markTestSkipped('Test only applicable to PHPCS 2.x'); - } + Helper::setConfigData('encoding', 'utf-8', true, self::$phpcsFile->config); - $this->assertFalse(Helper::ignoreAnnotations()); + $this->assertSame('utf-16', $result, 'Failed retrieving the custom set encoding'); } /** @@ -188,20 +147,17 @@ public function testIgnoreAnnotationsV2() * * @return void */ - public function testIgnoreAnnotationsV3Default() + public function testIgnoreAnnotationsDefault() { - if (\version_compare(static::$phpcsVersion, '2.99.99', '<=') === true) { - $this->markTestSkipped('Test only applicable to PHPCS 3.x'); - } - $result = Helper::ignoreAnnotations(); $this->assertFalse($result, 'Failed default ignoreAnnotations test without passing $phpcsFile'); $result = Helper::ignoreAnnotations(self::$phpcsFile); - $this->assertFalse($result, 'Failed default ignoreAnnotations test while passing $phpcsFile'); // Restore defaults before moving to the next test. self::$phpcsFile->config->restoreDefaults(); + + $this->assertFalse($result, 'Failed default ignoreAnnotations test while passing $phpcsFile'); } /** @@ -211,12 +167,8 @@ public function testIgnoreAnnotationsV3Default() * * @return void */ - public function testIgnoreAnnotationsV3SetViaMethod() + public function testIgnoreAnnotationsSetViaMethod() { - if (\version_compare(static::$phpcsVersion, '2.99.99', '<=') === true) { - $this->markTestSkipped('Test only applicable to PHPCS 3.x'); - } - $config = null; if (isset(self::$phpcsFile->config) === true) { $config = self::$phpcsFile->config; @@ -225,10 +177,11 @@ public function testIgnoreAnnotationsV3SetViaMethod() Helper::setConfigData('annotations', false, true, $config); $result = Helper::ignoreAnnotations(); - $this->assertTrue($result); // Restore defaults before moving to the next test. Helper::setConfigData('annotations', true, true, $config); + + $this->assertTrue($result); } /** @@ -238,18 +191,15 @@ public function testIgnoreAnnotationsV3SetViaMethod() * * @return void */ - public function testIgnoreAnnotationsV3SetViaProperty() + public function testIgnoreAnnotationsSetViaProperty() { - if (\version_compare(static::$phpcsVersion, '2.99.99', '<=') === true) { - $this->markTestSkipped('Test only applicable to PHPCS 3.x'); - } - self::$phpcsFile->config->annotations = false; $result = Helper::ignoreAnnotations(self::$phpcsFile); - $this->assertTrue($result); // Restore defaults before moving to the next test. self::$phpcsFile->config->restoreDefaults(); + + $this->assertTrue($result); } } diff --git a/Tests/Fixers/SpacesFixer/SpacesFixerNoSpaceTest.php b/Tests/Fixers/SpacesFixer/SpacesFixerNoSpaceTest.php index 1b180603..246c8d89 100644 --- a/Tests/Fixers/SpacesFixer/SpacesFixerNoSpaceTest.php +++ b/Tests/Fixers/SpacesFixer/SpacesFixerNoSpaceTest.php @@ -221,9 +221,7 @@ public function testCheckAndFix($testMarker, $expected, $type) $expectedMessage = \sprintf(static::MSG, static::MSG_REPLACEMENT_1, $expected['found']); $this->assertSame($expectedMessage, $messages[0]['message'], 'Message comparison failed'); - // PHPCS 2.x places `unknownSniff.` before the actual error code for utility tests with a dummy error code. - $errorCodeResult = \str_replace('unknownSniff.', '', $messages[0]['source']); - $this->assertSame(static::CODE, $errorCodeResult, 'Error code comparison failed'); + $this->assertSame(static::CODE, $messages[0]['source'], 'Error code comparison failed'); $this->assertSame($expected['fixable'], $messages[0]['fixable'], 'Fixability comparison failed'); diff --git a/Tests/Fixers/SpacesFixer/TrailingCommentHandlingTest.php b/Tests/Fixers/SpacesFixer/TrailingCommentHandlingTest.php index 985bbb59..4c3ee115 100644 --- a/Tests/Fixers/SpacesFixer/TrailingCommentHandlingTest.php +++ b/Tests/Fixers/SpacesFixer/TrailingCommentHandlingTest.php @@ -120,9 +120,7 @@ public function testCheckAndFix($testMarker, $expected, $type) $expectedMessage = \sprintf(self::MSG, self::MSG_REPLACEMENT_1, $expected['found']); $this->assertSame($expectedMessage, $messages[0]['message'], 'Message comparison failed'); - // PHPCS 2.x places `unknownSniff.` before the actual error code for utility tests with a dummy error code. - $errorCodeResult = \str_replace('unknownSniff.', '', $messages[0]['source']); - $this->assertSame(self::CODE, $errorCodeResult, 'Error code comparison failed'); + $this->assertSame(self::CODE, $messages[0]['source'], 'Error code comparison failed'); $this->assertSame($expected['fixable'], $messages[0]['fixable'], 'Fixability comparison failed'); diff --git a/Tests/Tokens/Collections/ArrowFunctionTokensBCTest.php b/Tests/Tokens/Collections/ArrowFunctionTokensBCTest.php index 2d45f09c..b7fcf49b 100644 --- a/Tests/Tokens/Collections/ArrowFunctionTokensBCTest.php +++ b/Tests/Tokens/Collections/ArrowFunctionTokensBCTest.php @@ -10,14 +10,14 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; -use PHPUnit\Framework\TestCase; +use Yoast\PHPUnitPolyfills\TestCases\TestCase; /** * Test class. * * @covers \PHPCSUtils\Tokens\Collections::arrowFunctionTokensBC + * @covers \PHPCSUtils\Tokens\Collections::triggerDeprecation * * @group collections * @@ -33,17 +33,16 @@ class ArrowFunctionTokensBCTest extends TestCase */ public function testArrowFunctionTokensBC() { - $version = Helper::getVersion(); + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'Collections::arrowFunctionTokensBC() method is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Use the `T_FN` token instead.' + ); + $expected = [ - \T_STRING => \T_STRING, + \T_FN => \T_FN, ]; - if (\version_compare($version, '3.5.3', '>=') === true - || \version_compare(\PHP_VERSION_ID, '70399', '>=') === true - ) { - $expected[\T_FN] = \T_FN; - } - $this->assertSame($expected, Collections::arrowFunctionTokensBC()); } } diff --git a/Tests/Tokens/Collections/FunctionCallTokensTest.php b/Tests/Tokens/Collections/FunctionCallTokensTest.php index 7bc47a86..ccc499f4 100644 --- a/Tests/Tokens/Collections/FunctionCallTokensTest.php +++ b/Tests/Tokens/Collections/FunctionCallTokensTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPUnit\Framework\TestCase; @@ -33,25 +32,16 @@ class FunctionCallTokensTest extends TestCase */ public function testFunctionCallTokens() { - $version = Helper::getVersion(); $expected = [ - \T_STRING => \T_STRING, - ]; - - if (\version_compare(\PHP_VERSION_ID, '80000', '>=') === true - || \version_compare($version, '3.5.7', '>=') === true - ) { - $expected[\T_NAME_QUALIFIED] = \T_NAME_QUALIFIED; - $expected[\T_NAME_FULLY_QUALIFIED] = \T_NAME_FULLY_QUALIFIED; - $expected[\T_NAME_RELATIVE] = \T_NAME_RELATIVE; - } - - $expected += [ - \T_VARIABLE => \T_VARIABLE, - \T_ANON_CLASS => \T_ANON_CLASS, - \T_PARENT => \T_PARENT, - \T_SELF => \T_SELF, - \T_STATIC => \T_STATIC, + \T_STRING => \T_STRING, + \T_NAME_QUALIFIED => \T_NAME_QUALIFIED, + \T_NAME_FULLY_QUALIFIED => \T_NAME_FULLY_QUALIFIED, + \T_NAME_RELATIVE => \T_NAME_RELATIVE, + \T_VARIABLE => \T_VARIABLE, + \T_ANON_CLASS => \T_ANON_CLASS, + \T_PARENT => \T_PARENT, + \T_SELF => \T_SELF, + \T_STATIC => \T_STATIC, ]; $this->assertSame($expected, Collections::functionCallTokens()); diff --git a/Tests/Tokens/Collections/FunctionDeclarationTokensBCTest.php b/Tests/Tokens/Collections/FunctionDeclarationTokensBCTest.php index 4a40ecfc..954fc2e7 100644 --- a/Tests/Tokens/Collections/FunctionDeclarationTokensBCTest.php +++ b/Tests/Tokens/Collections/FunctionDeclarationTokensBCTest.php @@ -10,14 +10,14 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; -use PHPUnit\Framework\TestCase; +use Yoast\PHPUnitPolyfills\TestCases\TestCase; /** * Test class. * * @covers \PHPCSUtils\Tokens\Collections::functionDeclarationTokensBC + * @covers \PHPCSUtils\Tokens\Collections::triggerDeprecation * * @group collections * @@ -33,19 +33,18 @@ class FunctionDeclarationTokensBCTest extends TestCase */ public function testFunctionDeclarationTokensBC() { - $version = Helper::getVersion(); + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'Collections::functionDeclarationTokensBC() method is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Use the PHPCSUtils\Tokens\Collections::functionDeclarationTokens() method instead.' + ); + $expected = [ \T_FUNCTION => \T_FUNCTION, \T_CLOSURE => \T_CLOSURE, - \T_STRING => \T_STRING, + \T_FN => \T_FN, ]; - if (\version_compare($version, '3.5.3', '>=') === true - || \version_compare(\PHP_VERSION_ID, '70399', '>=') === true - ) { - $expected[\T_FN] = \T_FN; - } - $this->assertSame($expected, Collections::functionDeclarationTokensBC()); } } diff --git a/Tests/Tokens/Collections/FunctionDeclarationTokensTest.php b/Tests/Tokens/Collections/FunctionDeclarationTokensTest.php index e5e2c3cd..27e0d95a 100644 --- a/Tests/Tokens/Collections/FunctionDeclarationTokensTest.php +++ b/Tests/Tokens/Collections/FunctionDeclarationTokensTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPUnit\Framework\TestCase; @@ -33,18 +32,12 @@ class FunctionDeclarationTokensTest extends TestCase */ public function testFunctionDeclarationTokens() { - $version = Helper::getVersion(); $expected = [ \T_FUNCTION => \T_FUNCTION, \T_CLOSURE => \T_CLOSURE, + \T_FN => \T_FN, ]; - if (\version_compare($version, '3.5.3', '>=') === true - || \version_compare(\PHP_VERSION_ID, '70399', '>=') === true - ) { - $expected[\T_FN] = \T_FN; - } - $this->assertSame($expected, Collections::functionDeclarationTokens()); } } diff --git a/Tests/Tokens/Collections/NameTokensTest.php b/Tests/Tokens/Collections/NameTokensTest.php index 9bb2ad3e..56c10a39 100644 --- a/Tests/Tokens/Collections/NameTokensTest.php +++ b/Tests/Tokens/Collections/NameTokensTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPUnit\Framework\TestCase; @@ -33,19 +32,13 @@ class NameTokensTest extends TestCase */ public function testNameTokens() { - $version = Helper::getVersion(); $expected = [ - \T_STRING => \T_STRING, + \T_STRING => \T_STRING, + \T_NAME_QUALIFIED => \T_NAME_QUALIFIED, + \T_NAME_FULLY_QUALIFIED => \T_NAME_FULLY_QUALIFIED, + \T_NAME_RELATIVE => \T_NAME_RELATIVE, ]; - if (\version_compare(\PHP_VERSION_ID, '80000', '>=') === true - || \version_compare($version, '3.5.7', '>=') === true - ) { - $expected[\T_NAME_QUALIFIED] = \T_NAME_QUALIFIED; - $expected[\T_NAME_FULLY_QUALIFIED] = \T_NAME_FULLY_QUALIFIED; - $expected[\T_NAME_RELATIVE] = \T_NAME_RELATIVE; - } - $this->assertSame($expected, Collections::nameTokens()); } } diff --git a/Tests/Tokens/Collections/NamespacedNameTokensTest.php b/Tests/Tokens/Collections/NamespacedNameTokensTest.php index d99be896..fdee9aaf 100644 --- a/Tests/Tokens/Collections/NamespacedNameTokensTest.php +++ b/Tests/Tokens/Collections/NamespacedNameTokensTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPUnit\Framework\TestCase; @@ -33,21 +32,15 @@ class NamespacedNameTokensTest extends TestCase */ public function testNamespacedNameTokens() { - $version = Helper::getVersion(); $expected = [ - \T_NS_SEPARATOR => \T_NS_SEPARATOR, - \T_NAMESPACE => \T_NAMESPACE, - \T_STRING => \T_STRING, + \T_NS_SEPARATOR => \T_NS_SEPARATOR, + \T_NAMESPACE => \T_NAMESPACE, + \T_STRING => \T_STRING, + \T_NAME_QUALIFIED => \T_NAME_QUALIFIED, + \T_NAME_FULLY_QUALIFIED => \T_NAME_FULLY_QUALIFIED, + \T_NAME_RELATIVE => \T_NAME_RELATIVE, ]; - if (\version_compare(\PHP_VERSION_ID, '80000', '>=') === true - || \version_compare($version, '3.5.7', '>=') === true - ) { - $expected[\T_NAME_QUALIFIED] = \T_NAME_QUALIFIED; - $expected[\T_NAME_FULLY_QUALIFIED] = \T_NAME_FULLY_QUALIFIED; - $expected[\T_NAME_RELATIVE] = \T_NAME_RELATIVE; - } - $this->assertSame($expected, Collections::namespacedNameTokens()); } } diff --git a/Tests/Tokens/Collections/NullsafeObjectOperatorTokensBCTest.php b/Tests/Tokens/Collections/NullsafeObjectOperatorTokensBCTest.php deleted file mode 100644 index 057c7620..00000000 --- a/Tests/Tokens/Collections/NullsafeObjectOperatorTokensBCTest.php +++ /dev/null @@ -1,53 +0,0 @@ -=') === true - || \version_compare($version, '3.5.7', '>=') === true - ) { - $expected = [ - \T_NULLSAFE_OBJECT_OPERATOR => \T_NULLSAFE_OBJECT_OPERATOR, - ]; - } else { - $expected = [ - \T_INLINE_THEN => \T_INLINE_THEN, - \T_OBJECT_OPERATOR => \T_OBJECT_OPERATOR, - ]; - } - - $this->assertSame($expected, Collections::nullsafeObjectOperatorBC()); - } -} diff --git a/Tests/Tokens/Collections/ObjectOperatorsBCTest.php b/Tests/Tokens/Collections/ObjectOperatorsBCTest.php deleted file mode 100644 index a9ec6c96..00000000 --- a/Tests/Tokens/Collections/ObjectOperatorsBCTest.php +++ /dev/null @@ -1,52 +0,0 @@ - \T_OBJECT_OPERATOR, - \T_DOUBLE_COLON => \T_DOUBLE_COLON, - ]; - - if (\version_compare(\PHP_VERSION_ID, '80000', '>=') === true - || \version_compare($version, '3.5.7', '>=') === true - ) { - $expected[\T_NULLSAFE_OBJECT_OPERATOR] = \T_NULLSAFE_OBJECT_OPERATOR; - } else { - $expected[\T_INLINE_THEN] = \T_INLINE_THEN; - } - - $this->assertSame($expected, Collections::objectOperatorsBC()); - } -} diff --git a/Tests/Tokens/Collections/ObjectOperatorsTest.php b/Tests/Tokens/Collections/ObjectOperatorsTest.php index da2dfb33..7b18b240 100644 --- a/Tests/Tokens/Collections/ObjectOperatorsTest.php +++ b/Tests/Tokens/Collections/ObjectOperatorsTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPUnit\Framework\TestCase; @@ -33,18 +32,6 @@ class ObjectOperatorsTest extends TestCase */ public function testObjectOperators() { - $version = Helper::getVersion(); - $expected = [ - \T_OBJECT_OPERATOR => \T_OBJECT_OPERATOR, - \T_DOUBLE_COLON => \T_DOUBLE_COLON, - ]; - - if (\version_compare(\PHP_VERSION_ID, '80000', '>=') === true - || \version_compare($version, '3.5.7', '>=') === true - ) { - $expected[\T_NULLSAFE_OBJECT_OPERATOR] = \T_NULLSAFE_OBJECT_OPERATOR; - } - - $this->assertSame($expected, Collections::objectOperators()); + $this->assertSame(Collections::$objectOperators, Collections::objectOperators()); } } diff --git a/Tests/Tokens/Collections/ParameterPassingTokensTest.php b/Tests/Tokens/Collections/ParameterPassingTokensTest.php index f4cf8be8..735060a0 100644 --- a/Tests/Tokens/Collections/ParameterPassingTokensTest.php +++ b/Tests/Tokens/Collections/ParameterPassingTokensTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPUnit\Framework\TestCase; @@ -33,30 +32,21 @@ class ParameterPassingTokensTest extends TestCase */ public function testParameterPassingTokens() { - $version = Helper::getVersion(); $expected = [ - \T_STRING => \T_STRING, - ]; - - if (\version_compare(\PHP_VERSION_ID, '80000', '>=') === true - || \version_compare($version, '3.5.7', '>=') === true - ) { - $expected[\T_NAME_QUALIFIED] = \T_NAME_QUALIFIED; - $expected[\T_NAME_FULLY_QUALIFIED] = \T_NAME_FULLY_QUALIFIED; - $expected[\T_NAME_RELATIVE] = \T_NAME_RELATIVE; - } - - $expected += [ - \T_VARIABLE => \T_VARIABLE, - \T_ANON_CLASS => \T_ANON_CLASS, - \T_PARENT => \T_PARENT, - \T_SELF => \T_SELF, - \T_STATIC => \T_STATIC, - \T_ISSET => \T_ISSET, - \T_UNSET => \T_UNSET, - \T_ARRAY => \T_ARRAY, - \T_OPEN_SHORT_ARRAY => \T_OPEN_SHORT_ARRAY, - \T_OPEN_SQUARE_BRACKET => \T_OPEN_SQUARE_BRACKET, + \T_STRING => \T_STRING, + \T_NAME_QUALIFIED => \T_NAME_QUALIFIED, + \T_NAME_FULLY_QUALIFIED => \T_NAME_FULLY_QUALIFIED, + \T_NAME_RELATIVE => \T_NAME_RELATIVE, + \T_VARIABLE => \T_VARIABLE, + \T_ANON_CLASS => \T_ANON_CLASS, + \T_PARENT => \T_PARENT, + \T_SELF => \T_SELF, + \T_STATIC => \T_STATIC, + \T_ISSET => \T_ISSET, + \T_UNSET => \T_UNSET, + \T_ARRAY => \T_ARRAY, + \T_OPEN_SHORT_ARRAY => \T_OPEN_SHORT_ARRAY, + \T_OPEN_SQUARE_BRACKET => \T_OPEN_SQUARE_BRACKET, ]; $this->assertSame($expected, Collections::parameterPassingTokens()); diff --git a/Tests/Tokens/Collections/ParameterTypeTokensBCTest.php b/Tests/Tokens/Collections/ParameterTypeTokensBCTest.php index f618f28d..c72dd44b 100644 --- a/Tests/Tokens/Collections/ParameterTypeTokensBCTest.php +++ b/Tests/Tokens/Collections/ParameterTypeTokensBCTest.php @@ -10,14 +10,14 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; -use PHPUnit\Framework\TestCase; +use Yoast\PHPUnitPolyfills\TestCases\TestCase; /** * Test class. * * @covers \PHPCSUtils\Tokens\Collections::parameterTypeTokensBC + * @covers \PHPCSUtils\Tokens\Collections::triggerDeprecation * * @group collections * @@ -33,13 +33,12 @@ class ParameterTypeTokensBCTest extends TestCase */ public function testParameterTypeTokensBC() { - $version = Helper::getVersion(); - $expected = Collections::parameterTypeTokens(); + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'Collections::parameterTypeTokensBC() method is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Use the PHPCSUtils\Tokens\Collections::parameterTypeTokens() method instead.' + ); - if (\version_compare($version, '3.99.99', '<=') === true) { - $expected[\T_ARRAY_HINT] = \T_ARRAY_HINT; - } - - $this->assertSame($expected, Collections::parameterTypeTokensBC()); + $this->assertSame(Collections::parameterTypeTokens(), Collections::parameterTypeTokensBC()); } } diff --git a/Tests/Tokens/Collections/ParameterTypeTokensTest.php b/Tests/Tokens/Collections/ParameterTypeTokensTest.php index 70344939..de67dc59 100644 --- a/Tests/Tokens/Collections/ParameterTypeTokensTest.php +++ b/Tests/Tokens/Collections/ParameterTypeTokensTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPUnit\Framework\TestCase; @@ -33,31 +32,21 @@ class ParameterTypeTokensTest extends TestCase */ public function testParameterTypeTokens() { - $version = Helper::getVersion(); $expected = [ - \T_CALLABLE => \T_CALLABLE, - \T_SELF => \T_SELF, - \T_PARENT => \T_PARENT, - \T_FALSE => \T_FALSE, - \T_NULL => \T_NULL, - \T_BITWISE_OR => \T_BITWISE_OR, - \T_NS_SEPARATOR => \T_NS_SEPARATOR, - \T_NAMESPACE => \T_NAMESPACE, - \T_STRING => \T_STRING, + \T_CALLABLE => \T_CALLABLE, + \T_SELF => \T_SELF, + \T_PARENT => \T_PARENT, + \T_FALSE => \T_FALSE, + \T_NULL => \T_NULL, + \T_STRING => \T_STRING, + \T_NS_SEPARATOR => \T_NS_SEPARATOR, + \T_TYPE_UNION => \T_TYPE_UNION, + \T_NAMESPACE => \T_NAMESPACE, + \T_NAME_QUALIFIED => \T_NAME_QUALIFIED, + \T_NAME_FULLY_QUALIFIED => \T_NAME_FULLY_QUALIFIED, + \T_NAME_RELATIVE => \T_NAME_RELATIVE, ]; - if (\version_compare(\PHP_VERSION_ID, '80000', '>=') === true - || \version_compare($version, '3.5.7', '>=') === true - ) { - $expected[\T_NAME_QUALIFIED] = \T_NAME_QUALIFIED; - $expected[\T_NAME_FULLY_QUALIFIED] = \T_NAME_FULLY_QUALIFIED; - $expected[\T_NAME_RELATIVE] = \T_NAME_RELATIVE; - } - - if (\version_compare($version, '3.6.0', '>=') === true) { - $expected[\T_TYPE_UNION] = \T_TYPE_UNION; - } - $this->assertSame($expected, Collections::parameterTypeTokens()); } } diff --git a/Tests/Tokens/Collections/PropertyTypeTokensBCTest.php b/Tests/Tokens/Collections/PropertyTypeTokensBCTest.php index cc9a68c8..c2ee0c13 100644 --- a/Tests/Tokens/Collections/PropertyTypeTokensBCTest.php +++ b/Tests/Tokens/Collections/PropertyTypeTokensBCTest.php @@ -10,14 +10,14 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; -use PHPUnit\Framework\TestCase; +use Yoast\PHPUnitPolyfills\TestCases\TestCase; /** * Test class. * * @covers \PHPCSUtils\Tokens\Collections::propertyTypeTokensBC + * @covers \PHPCSUtils\Tokens\Collections::triggerDeprecation * * @group collections * @@ -33,13 +33,12 @@ class PropertyTypeTokensBCTest extends TestCase */ public function testPropertyTypeTokensBC() { - $version = Helper::getVersion(); - $expected = Collections::propertyTypeTokens(); + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'Collections::propertyTypeTokensBC() method is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Use the PHPCSUtils\Tokens\Collections::propertyTypeTokens() method instead.' + ); - if (\version_compare($version, '3.99.99', '<=') === true) { - $expected[\T_ARRAY_HINT] = \T_ARRAY_HINT; - } - - $this->assertSame($expected, Collections::propertyTypeTokensBC()); + $this->assertSame(Collections::propertyTypeTokens(), Collections::propertyTypeTokensBC()); } } diff --git a/Tests/Tokens/Collections/PropertyTypeTokensTest.php b/Tests/Tokens/Collections/PropertyTypeTokensTest.php index 39833723..dbd03093 100644 --- a/Tests/Tokens/Collections/PropertyTypeTokensTest.php +++ b/Tests/Tokens/Collections/PropertyTypeTokensTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPUnit\Framework\TestCase; @@ -33,31 +32,21 @@ class PropertyTypeTokensTest extends TestCase */ public function testPropertyTypeTokens() { - $version = Helper::getVersion(); $expected = [ - \T_CALLABLE => \T_CALLABLE, - \T_SELF => \T_SELF, - \T_PARENT => \T_PARENT, - \T_FALSE => \T_FALSE, - \T_NULL => \T_NULL, - \T_BITWISE_OR => \T_BITWISE_OR, - \T_NS_SEPARATOR => \T_NS_SEPARATOR, - \T_NAMESPACE => \T_NAMESPACE, - \T_STRING => \T_STRING, + \T_CALLABLE => \T_CALLABLE, + \T_SELF => \T_SELF, + \T_PARENT => \T_PARENT, + \T_FALSE => \T_FALSE, + \T_NULL => \T_NULL, + \T_STRING => \T_STRING, + \T_NS_SEPARATOR => \T_NS_SEPARATOR, + \T_TYPE_UNION => \T_TYPE_UNION, + \T_NAMESPACE => \T_NAMESPACE, + \T_NAME_QUALIFIED => \T_NAME_QUALIFIED, + \T_NAME_FULLY_QUALIFIED => \T_NAME_FULLY_QUALIFIED, + \T_NAME_RELATIVE => \T_NAME_RELATIVE, ]; - if (\version_compare(\PHP_VERSION_ID, '80000', '>=') === true - || \version_compare($version, '3.5.7', '>=') === true - ) { - $expected[\T_NAME_QUALIFIED] = \T_NAME_QUALIFIED; - $expected[\T_NAME_FULLY_QUALIFIED] = \T_NAME_FULLY_QUALIFIED; - $expected[\T_NAME_RELATIVE] = \T_NAME_RELATIVE; - } - - if (\version_compare($version, '3.6.0', '>=') === true) { - $expected[\T_TYPE_UNION] = \T_TYPE_UNION; - } - $this->assertSame($expected, Collections::propertyTypeTokens()); } } diff --git a/Tests/Tokens/Collections/ReturnTypeTokensBCTest.php b/Tests/Tokens/Collections/ReturnTypeTokensBCTest.php index c1955f1b..e737db3a 100644 --- a/Tests/Tokens/Collections/ReturnTypeTokensBCTest.php +++ b/Tests/Tokens/Collections/ReturnTypeTokensBCTest.php @@ -10,14 +10,14 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; -use PHPUnit\Framework\TestCase; +use Yoast\PHPUnitPolyfills\TestCases\TestCase; /** * Test class. * * @covers \PHPCSUtils\Tokens\Collections::returnTypeTokensBC + * @covers \PHPCSUtils\Tokens\Collections::triggerDeprecation * * @group collections * @@ -33,14 +33,12 @@ class ReturnTypeTokensBCTest extends TestCase */ public function testReturnTypeTokensBC() { - $version = Helper::getVersion(); - $expected = Collections::returnTypeTokens(); + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'Collections::returnTypeTokensBC() method is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Use the PHPCSUtils\Tokens\Collections::returnTypeTokens() method instead.' + ); - if (\version_compare($version, '3.99.99', '<=') === true) { - $expected[\T_RETURN_TYPE] = \T_RETURN_TYPE; - $expected[\T_ARRAY_HINT] = \T_ARRAY_HINT; - } - - $this->assertSame($expected, Collections::returnTypeTokensBC()); + $this->assertSame(Collections::returnTypeTokens(), Collections::returnTypeTokensBC()); } } diff --git a/Tests/Tokens/Collections/ReturnTypeTokensTest.php b/Tests/Tokens/Collections/ReturnTypeTokensTest.php index 0c2e3feb..7b258a2b 100644 --- a/Tests/Tokens/Collections/ReturnTypeTokensTest.php +++ b/Tests/Tokens/Collections/ReturnTypeTokensTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPUnit\Framework\TestCase; @@ -33,33 +32,22 @@ class ReturnTypeTokensTest extends TestCase */ public function testReturnTypeTokens() { - $version = Helper::getVersion(); $expected = [ - \T_CALLABLE => \T_CALLABLE, - \T_FALSE => \T_FALSE, - \T_NULL => \T_NULL, - \T_ARRAY => \T_ARRAY, - \T_BITWISE_OR => \T_BITWISE_OR, - \T_PARENT => \T_PARENT, - \T_SELF => \T_SELF, - \T_STATIC => \T_STATIC, - \T_NS_SEPARATOR => \T_NS_SEPARATOR, - \T_NAMESPACE => \T_NAMESPACE, - \T_STRING => \T_STRING, + \T_CALLABLE => \T_CALLABLE, + \T_SELF => \T_SELF, + \T_PARENT => \T_PARENT, + \T_STATIC => \T_STATIC, + \T_FALSE => \T_FALSE, + \T_NULL => \T_NULL, + \T_STRING => \T_STRING, + \T_NS_SEPARATOR => \T_NS_SEPARATOR, + \T_TYPE_UNION => \T_TYPE_UNION, + \T_NAMESPACE => \T_NAMESPACE, + \T_NAME_QUALIFIED => \T_NAME_QUALIFIED, + \T_NAME_FULLY_QUALIFIED => \T_NAME_FULLY_QUALIFIED, + \T_NAME_RELATIVE => \T_NAME_RELATIVE, ]; - if (\version_compare(\PHP_VERSION_ID, '80000', '>=') === true - || \version_compare($version, '3.5.7', '>=') === true - ) { - $expected[\T_NAME_QUALIFIED] = \T_NAME_QUALIFIED; - $expected[\T_NAME_FULLY_QUALIFIED] = \T_NAME_FULLY_QUALIFIED; - $expected[\T_NAME_RELATIVE] = \T_NAME_RELATIVE; - } - - if (\version_compare($version, '3.6.0', '>=') === true) { - $expected[\T_TYPE_UNION] = \T_TYPE_UNION; - } - $this->assertSame($expected, Collections::returnTypeTokens()); } } diff --git a/Tests/Tokens/TokenHelper/TokenExistsTest.php b/Tests/Tokens/TokenHelper/TokenExistsTest.php index 431814fb..3e6babda 100644 --- a/Tests/Tokens/TokenHelper/TokenExistsTest.php +++ b/Tests/Tokens/TokenHelper/TokenExistsTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\TokenHelper; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\TokenHelper; use PHPUnit\Framework\TestCase; @@ -56,12 +55,15 @@ public function testTokenExists($name, $expected) /** * Data provider. * + * {@internal This dataprovider does not currently contain any tests for + * PHP native tokens which may not exist (depending on the PHPCS version). + * These tests are not relevant at this time with the current minimum + * PHPCS version of 3.7.1, but this may change again in the future.} + * * @return array */ public function dataTokenExists() { - $phpcsVersion = Helper::getVersion(); - return [ 'Token which doesn\'t exist either way' => [ 'name' => 'T_DOESNOTEXIST', @@ -75,21 +77,6 @@ public function dataTokenExists() 'name' => 'T_CLOSURE', 'expected' => true, ], - 'PHP native token which may not exist - PHP 7.4 T_FN' => [ - 'name' => 'T_FN', - 'expected' => (\version_compare($phpcsVersion, '3.5.3', '>=') - || \version_compare(\PHP_VERSION_ID, '70399', '>=')), - ], - 'PHP native token which may not exist - PHP 8.0 T_NULLSAFE_OBJECT_OPERATOR' => [ - 'name' => 'T_NULLSAFE_OBJECT_OPERATOR', - 'expected' => (\version_compare($phpcsVersion, '3.5.7', '>=') - || \version_compare(\PHP_VERSION_ID, '79999', '>=')), - ], - 'PHP native token which may not exist - PHP 8.1 T_ENUM' => [ - 'name' => 'T_ENUM', - 'expected' => (\version_compare($phpcsVersion, '3.7.0', '>=') - || \version_compare(\PHP_VERSION_ID, '80099', '>=')), - ], 'Mocked polyfilled token' => [ 'name' => 'T_FAKETOKEN', 'expected' => false, diff --git a/Tests/Utils/Arrays/GetDoubleArrowPtrTest.php b/Tests/Utils/Arrays/GetDoubleArrowPtrTest.php index c868fadf..f8e11344 100644 --- a/Tests/Utils/Arrays/GetDoubleArrowPtrTest.php +++ b/Tests/Utils/Arrays/GetDoubleArrowPtrTest.php @@ -210,6 +210,7 @@ public function dataGetDoubleArrowPtr() 'expected' => 8, ], // Test specifically for PHPCS 3.5.3 and 3.5.4 in which all "fn" tokens were tokenized as T_FN. + // While PHPCS < 3.7.1 is no longer supported, the test remains to safeguard against tokenizer regressions. 'test-arrow-access-to-property-named-fn-as-key-phpcs-3.5.3-3.5.4' => [ 'testMarker' => '/* testKeyPropertyAccessFnPHPCS353-354 */', 'expected' => 12, diff --git a/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseParseError1Test.php b/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseParseError1Test.php index fb299040..57dee387 100644 --- a/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseParseError1Test.php +++ b/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseParseError1Test.php @@ -10,7 +10,7 @@ namespace PHPCSUtils\Tests\Utils\ControlStructures; -use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use PHPCSUtils\Tests\PolyfilledTestCase; use PHPCSUtils\Utils\ControlStructures; /** @@ -22,7 +22,7 @@ * * @since 1.0.0 */ -class GetDeclareScopeOpenCloseParseError1Test extends UtilityMethodTestCase +class GetDeclareScopeOpenCloseParseError1Test extends PolyfilledTestCase { /** @@ -32,6 +32,12 @@ class GetDeclareScopeOpenCloseParseError1Test extends UtilityMethodTestCase */ public function testGetDeclareScopeOpenCloseParseError() { + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'ControlStructures::getDeclareScopeOpenClose() function is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Check for the "scope_opener"/"scope_closer" keys instead.' + ); + $stackPtr = $this->getTargetToken('/* testNoCloseParenthesis */', \T_DECLARE); $result = ControlStructures::getDeclareScopeOpenClose(self::$phpcsFile, $stackPtr); $this->assertFalse($result); diff --git a/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseParseError2Test.php b/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseParseError2Test.php index 791654c1..431e9380 100644 --- a/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseParseError2Test.php +++ b/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseParseError2Test.php @@ -10,7 +10,7 @@ namespace PHPCSUtils\Tests\Utils\ControlStructures; -use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use PHPCSUtils\Tests\PolyfilledTestCase; use PHPCSUtils\Utils\ControlStructures; /** @@ -22,7 +22,7 @@ * * @since 1.0.0 */ -class GetDeclareScopeOpenCloseParseError2Test extends UtilityMethodTestCase +class GetDeclareScopeOpenCloseParseError2Test extends PolyfilledTestCase { /** @@ -32,6 +32,12 @@ class GetDeclareScopeOpenCloseParseError2Test extends UtilityMethodTestCase */ public function testGetDeclareScopeOpenCloseParseError() { + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'ControlStructures::getDeclareScopeOpenClose() function is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Check for the "scope_opener"/"scope_closer" keys instead.' + ); + $stackPtr = $this->getTargetToken('/* testNoScopeOpener */', \T_DECLARE); $result = ControlStructures::getDeclareScopeOpenClose(self::$phpcsFile, $stackPtr); $this->assertFalse($result); diff --git a/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseParseError3Test.php b/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseParseError3Test.php index 9c87aee0..9443fb87 100644 --- a/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseParseError3Test.php +++ b/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseParseError3Test.php @@ -10,7 +10,7 @@ namespace PHPCSUtils\Tests\Utils\ControlStructures; -use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use PHPCSUtils\Tests\PolyfilledTestCase; use PHPCSUtils\Utils\ControlStructures; /** @@ -22,7 +22,7 @@ * * @since 1.0.0 */ -class GetDeclareScopeOpenCloseParseError3Test extends UtilityMethodTestCase +class GetDeclareScopeOpenCloseParseError3Test extends PolyfilledTestCase { /** @@ -32,6 +32,12 @@ class GetDeclareScopeOpenCloseParseError3Test extends UtilityMethodTestCase */ public function testGetDeclareScopeOpenCloseParseError() { + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'ControlStructures::getDeclareScopeOpenClose() function is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Check for the "scope_opener"/"scope_closer" keys instead.' + ); + $stackPtr = $this->getTargetToken('/* testNoScopeCloser */', \T_DECLARE); $result = ControlStructures::getDeclareScopeOpenClose(self::$phpcsFile, $stackPtr); $this->assertFalse($result); diff --git a/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseParseError4Test.php b/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseParseError4Test.php index e72c1b3b..a93d76f4 100644 --- a/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseParseError4Test.php +++ b/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseParseError4Test.php @@ -10,7 +10,7 @@ namespace PHPCSUtils\Tests\Utils\ControlStructures; -use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use PHPCSUtils\Tests\PolyfilledTestCase; use PHPCSUtils\Utils\ControlStructures; /** @@ -22,7 +22,7 @@ * * @since 1.0.0 */ -class GetDeclareScopeOpenCloseParseError4Test extends UtilityMethodTestCase +class GetDeclareScopeOpenCloseParseError4Test extends PolyfilledTestCase { /** @@ -32,6 +32,12 @@ class GetDeclareScopeOpenCloseParseError4Test extends UtilityMethodTestCase */ public function testGetDeclareScopeOpenCloseParseError() { + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'ControlStructures::getDeclareScopeOpenClose() function is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Check for the "scope_opener"/"scope_closer" keys instead.' + ); + $stackPtr = $this->getTargetToken('/* testUnexpectedToken */', \T_DECLARE); $result = ControlStructures::getDeclareScopeOpenClose(self::$phpcsFile, $stackPtr); $this->assertFalse($result); diff --git a/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseTest.php b/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseTest.php index 62e635f7..b3309e4e 100644 --- a/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseTest.php +++ b/Tests/Utils/ControlStructures/GetDeclareScopeOpenCloseTest.php @@ -10,8 +10,7 @@ namespace PHPCSUtils\Tests\Utils\ControlStructures; -use PHPCSUtils\Internal\Cache; -use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use PHPCSUtils\Tests\PolyfilledTestCase; use PHPCSUtils\Utils\ControlStructures; /** @@ -23,7 +22,7 @@ * * @since 1.0.0 */ -class GetDeclareScopeOpenCloseTest extends UtilityMethodTestCase +class GetDeclareScopeOpenCloseTest extends PolyfilledTestCase { /** @@ -33,6 +32,12 @@ class GetDeclareScopeOpenCloseTest extends UtilityMethodTestCase */ public function testNonExistentToken() { + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'ControlStructures::getDeclareScopeOpenClose() function is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Check for the "scope_opener"/"scope_closer" keys instead.' + ); + $this->assertFalse(ControlStructures::getDeclareScopeOpenClose(self::$phpcsFile, 10000)); } @@ -43,6 +48,12 @@ public function testNonExistentToken() */ public function testNotDeclare() { + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'ControlStructures::getDeclareScopeOpenClose() function is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Check for the "scope_opener"/"scope_closer" keys instead.' + ); + $target = $this->getTargetToken('/* testNotDeclare */', \T_ECHO); $this->assertFalse(ControlStructures::getDeclareScopeOpenClose(self::$phpcsFile, $target)); } @@ -59,6 +70,12 @@ public function testNotDeclare() */ public function testGetDeclareScopeOpenClose($testMarker, $expected) { + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'ControlStructures::getDeclareScopeOpenClose() function is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Check for the "scope_opener"/"scope_closer" keys instead.' + ); + $stackPtr = $this->getTargetToken($testMarker, \T_DECLARE); // Translate offsets to absolute token positions. @@ -193,43 +210,4 @@ public function dataGetDeclareScopeOpenClose() ], ]; } - - /** - * Verify that the build-in caching is used when caching is enabled. - * - * @return void - */ - public function testResultIsCached() - { - // The test case used is specifically selected to be one which will always reach the cache check. - $methodName = 'PHPCSUtils\\Utils\\ControlStructures::getDeclareScopeOpenClose'; - $cases = $this->dataGetDeclareScopeOpenClose(); - $testMarker = $cases['mixed-nested-level-4']['testMarker']; - $expected = $cases['mixed-nested-level-4']['expected']; - - $stackPtr = $this->getTargetToken($testMarker, \T_DECLARE); - - // Translate offsets to absolute token positions. - if (isset($expected['opener'], $expected['closer']) === true) { - $expected['opener'] += $stackPtr; - $expected['closer'] += $stackPtr; - } - - // Verify the caching works. - $origStatus = Cache::$enabled; - Cache::$enabled = true; - - $resultFirstRun = ControlStructures::getDeclareScopeOpenClose(self::$phpcsFile, $stackPtr); - $isCached = Cache::isCached(self::$phpcsFile, $methodName, $stackPtr); - $resultSecondRun = ControlStructures::getDeclareScopeOpenClose(self::$phpcsFile, $stackPtr); - - if ($origStatus === false) { - Cache::clear(); - } - Cache::$enabled = $origStatus; - - $this->assertSame($expected, $resultFirstRun, 'First result did not match expectation'); - $this->assertTrue($isCached, 'Cache::isCached() could not find the cached value'); - $this->assertSame($resultFirstRun, $resultSecondRun, 'Second result did not match first'); - } } diff --git a/Tests/Utils/FunctionDeclarations/GetParametersParseError1Test.php b/Tests/Utils/FunctionDeclarations/GetParametersParseError1Test.php index 2efd50cc..1600701f 100644 --- a/Tests/Utils/FunctionDeclarations/GetParametersParseError1Test.php +++ b/Tests/Utils/FunctionDeclarations/GetParametersParseError1Test.php @@ -11,6 +11,7 @@ namespace PHPCSUtils\Tests\Utils\FunctionDeclarations; use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use PHPCSUtils\Tokens\Collections; use PHPCSUtils\Utils\FunctionDeclarations; /** @@ -54,7 +55,7 @@ public static function setUpTestFile() */ public function testParseError() { - $target = $this->getTargetToken('/* testParseError */', [\T_FUNCTION, \T_CLOSURE]); + $target = $this->getTargetToken('/* testParseError */', Collections::functionDeclarationTokens()); $result = FunctionDeclarations::getParameters(self::$phpcsFile, $target); $this->assertSame([], $result); diff --git a/Tests/Utils/FunctionDeclarations/GetParametersParseError2Test.php b/Tests/Utils/FunctionDeclarations/GetParametersParseError2Test.php index ebefed1d..749c00e2 100644 --- a/Tests/Utils/FunctionDeclarations/GetParametersParseError2Test.php +++ b/Tests/Utils/FunctionDeclarations/GetParametersParseError2Test.php @@ -11,6 +11,7 @@ namespace PHPCSUtils\Tests\Utils\FunctionDeclarations; use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use PHPCSUtils\Tokens\Collections; use PHPCSUtils\Utils\FunctionDeclarations; /** @@ -54,7 +55,7 @@ public static function setUpTestFile() */ public function testParseError() { - $target = $this->getTargetToken('/* testParseError */', [\T_FUNCTION, \T_CLOSURE]); + $target = $this->getTargetToken('/* testParseError */', Collections::functionDeclarationTokens()); $result = FunctionDeclarations::getParameters(self::$phpcsFile, $target); $this->assertSame([], $result); diff --git a/Tests/Utils/FunctionDeclarations/GetParametersTest.php b/Tests/Utils/FunctionDeclarations/GetParametersTest.php index 99d9cb94..b6c98683 100644 --- a/Tests/Utils/FunctionDeclarations/GetParametersTest.php +++ b/Tests/Utils/FunctionDeclarations/GetParametersTest.php @@ -89,11 +89,11 @@ public function testInvalidUse($identifier) * * @param string $commentString The comment which preceeds the test. * @param array $targetTokenType Optional. The token type to search for after $commentString. - * Defaults to the function/closure tokens. + * Defaults to the function/closure/arrow tokens. * * @return void */ - public function testNoParams($commentString, $targetTokenType = [\T_FUNCTION, \T_CLOSURE]) + public function testNoParams($commentString, $targetTokenType = [\T_FUNCTION, \T_CLOSURE, \T_FN]) { $target = $this->getTargetToken($commentString, $targetTokenType); $result = FunctionDeclarations::getParameters(self::$phpcsFile, $target); @@ -104,16 +104,16 @@ public function testNoParams($commentString, $targetTokenType = [\T_FUNCTION, \T /** * Test helper. * - * @param string $commentString The comment which preceeds the test. - * @param array $expected The expected function output. - * @param array $targetType Optional. The token type to search for after $commentString. - * Defaults to the function/closure tokens. + * @param string $marker The comment which preceeds the test. + * @param array $expected The expected function output. + * @param array $targetType Optional. The token type to search for after $marker. + * Defaults to the function/closure/arrow tokens. * * @return void */ - protected function getMethodParametersTestHelper($commentString, $expected, $targetType = [\T_FUNCTION, \T_CLOSURE]) + protected function getMethodParametersTestHelper($marker, $expected, $targetType = [\T_FUNCTION, \T_CLOSURE, \T_FN]) { - $target = $this->getTargetToken($commentString, $targetType); + $target = $this->getTargetToken($marker, $targetType); $found = FunctionDeclarations::getParameters(self::$phpcsFile, $target); foreach ($expected as $key => $param) { diff --git a/Tests/Utils/FunctionDeclarations/GetPropertiesDiffTest.php b/Tests/Utils/FunctionDeclarations/GetPropertiesDiffTest.php index 1c635634..9d37d224 100644 --- a/Tests/Utils/FunctionDeclarations/GetPropertiesDiffTest.php +++ b/Tests/Utils/FunctionDeclarations/GetPropertiesDiffTest.php @@ -96,8 +96,11 @@ public function testMessyPhpcsAnnotationsStaticClosure() * * @return void */ - protected function getPropertiesTestHelper($commentString, $expected, $targetType = [\T_FUNCTION, \T_CLOSURE]) - { + protected function getPropertiesTestHelper( + $commentString, + $expected, + $targetType = [\T_FUNCTION, \T_CLOSURE, \T_FN] + ) { $function = $this->getTargetToken($commentString, $targetType); $found = FunctionDeclarations::getProperties(self::$phpcsFile, $function); diff --git a/Tests/Utils/FunctionDeclarations/GetPropertiesTest.php b/Tests/Utils/FunctionDeclarations/GetPropertiesTest.php index b12df8a8..9ee92af0 100644 --- a/Tests/Utils/FunctionDeclarations/GetPropertiesTest.php +++ b/Tests/Utils/FunctionDeclarations/GetPropertiesTest.php @@ -75,8 +75,11 @@ public function testNotAFunctionException($commentString, $targetTokenType) * * @return void */ - protected function getMethodPropertiesTestHelper($commentString, $expected, $targetType = [\T_FUNCTION, \T_CLOSURE]) - { + protected function getMethodPropertiesTestHelper( + $commentString, + $expected, + $targetType = [\T_FUNCTION, \T_CLOSURE, \T_FN] + ) { $function = $this->getTargetToken($commentString, $targetType); $found = FunctionDeclarations::getProperties(self::$phpcsFile, $function); diff --git a/Tests/Utils/FunctionDeclarations/IsArrowFunction2926Test.php b/Tests/Utils/FunctionDeclarations/IsArrowFunction2926Test.php index 897a6481..da8c0908 100644 --- a/Tests/Utils/FunctionDeclarations/IsArrowFunction2926Test.php +++ b/Tests/Utils/FunctionDeclarations/IsArrowFunction2926Test.php @@ -11,8 +11,7 @@ namespace PHPCSUtils\Tests\Utils\FunctionDeclarations; use PHPCSUtils\BackCompat\Helper; -use PHPCSUtils\TestUtils\UtilityMethodTestCase; -use PHPCSUtils\Tokens\Collections; +use PHPCSUtils\Tests\PolyfilledTestCase; use PHPCSUtils\Utils\FunctionDeclarations; /** @@ -31,7 +30,7 @@ * * @since 1.0.0 */ -class IsArrowFunction2926Test extends UtilityMethodTestCase +class IsArrowFunction2926Test extends PolyfilledTestCase { /** @@ -120,7 +119,13 @@ public static function resetProperties() */ public function testIsArrowFunction($testMarker, $expected, $targetContent = null) { - $targets = Collections::arrowFunctionTokensBC(); + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'FunctionDeclarations::isArrowFunction() function is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Use the `T_FN` token instead.' + ); + + $targets = [\T_FN, \T_STRING]; $stackPtr = $this->getTargetToken($testMarker, $targets, $targetContent); $result = FunctionDeclarations::isArrowFunction(self::$phpcsFile, $stackPtr); $this->assertSame($expected['is'], $result); @@ -140,7 +145,13 @@ public function testIsArrowFunction($testMarker, $expected, $targetContent = nul */ public function testGetArrowFunctionOpenClose($testMarker, $expected, $targetContent = 'fn') { - $targets = Collections::arrowFunctionTokensBC(); + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'FunctionDeclarations::getArrowFunctionOpenClose() function is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Use the `T_FN` token instead.' + ); + + $targets = [\T_FN, \T_STRING]; $stackPtr = $this->getTargetToken($testMarker, $targets, $targetContent); // Change from offsets to absolute token positions. diff --git a/Tests/Utils/FunctionDeclarations/IsArrowFunctionTest.php b/Tests/Utils/FunctionDeclarations/IsArrowFunctionTest.php index 7e5be727..7c179fcd 100644 --- a/Tests/Utils/FunctionDeclarations/IsArrowFunctionTest.php +++ b/Tests/Utils/FunctionDeclarations/IsArrowFunctionTest.php @@ -10,9 +10,7 @@ namespace PHPCSUtils\Tests\Utils\FunctionDeclarations; -use PHPCSUtils\Internal\Cache; -use PHPCSUtils\TestUtils\UtilityMethodTestCase; -use PHPCSUtils\Tokens\Collections; +use PHPCSUtils\Tests\PolyfilledTestCase; use PHPCSUtils\Utils\FunctionDeclarations; /** @@ -28,7 +26,7 @@ * * @since 1.0.0 */ -class IsArrowFunctionTest extends UtilityMethodTestCase +class IsArrowFunctionTest extends PolyfilledTestCase { /** @@ -38,6 +36,12 @@ class IsArrowFunctionTest extends UtilityMethodTestCase */ public function testNonExistentToken() { + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'FunctionDeclarations::isArrowFunction() function is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Use the `T_FN` token instead.' + ); + $result = FunctionDeclarations::isArrowFunction(self::$phpcsFile, 10000); $this->assertFalse($result, 'Failed isArrowFunction() test'); @@ -52,6 +56,12 @@ public function testNonExistentToken() */ public function testUnsupportedToken() { + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'FunctionDeclarations::isArrowFunction() function is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Use the `T_FN` token instead.' + ); + $stackPtr = $this->getTargetToken('/* testConstantDeclaration */', \T_CONST); $result = FunctionDeclarations::isArrowFunction(self::$phpcsFile, $stackPtr); @@ -68,6 +78,12 @@ public function testUnsupportedToken() */ public function testTStringNotFn() { + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'FunctionDeclarations::isArrowFunction() function is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Use the `T_FN` token instead.' + ); + $stackPtr = $this->getTargetToken('/* testNotTheRightContent */', \T_STRING); $result = FunctionDeclarations::isArrowFunction(self::$phpcsFile, $stackPtr); @@ -98,7 +114,13 @@ public function testIsArrowFunction($testMarker, $expected, $targetContent = nul $this->markTestSkipped("PHP 8.0 identifier name tokenization used. Target token won't exist."); } - $targets = Collections::arrowFunctionTokensBC(); + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'FunctionDeclarations::isArrowFunction() function is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Use the `T_FN` token instead.' + ); + + $targets = [\T_FN, \T_STRING]; $stackPtr = $this->getTargetToken($testMarker, $targets, $targetContent); $result = FunctionDeclarations::isArrowFunction(self::$phpcsFile, $stackPtr); $this->assertSame($expected['is'], $result); @@ -125,7 +147,13 @@ public function testGetArrowFunctionOpenClose($testMarker, $expected, $targetCon $this->markTestSkipped("PHP 8.0 identifier name tokenization used. Target token won't exist."); } - $targets = Collections::arrowFunctionTokensBC(); + $this->expectDeprecation(); + $this->expectDeprecationMessage( + 'FunctionDeclarations::getArrowFunctionOpenClose() function is deprecated since PHPCSUtils 1.0.0-alpha4.' + . ' Use the `T_FN` token instead.' + ); + + $targets = [\T_FN, \T_STRING]; $stackPtr = $this->getTargetToken($testMarker, $targets, $targetContent); // Change from offsets to absolute token positions. @@ -684,44 +712,4 @@ public function dataArrowFunction() ], ]; } - - /** - * Verify that the build-in caching is used when caching is enabled. - * - * @return void - */ - public function testResultIsCached() - { - // The test case used is specifically selected to be one which will always reach the cache check. - $methodName = 'PHPCSUtils\\Utils\\FunctionDeclarations::getArrowFunctionOpenClose'; - $cases = $this->dataArrowFunction(); - $testMarker = $cases['live-coding']['testMarker']; - $expected = $cases['live-coding']['expected']; - - $stackPtr = $this->getTargetToken($testMarker, Collections::arrowFunctionTokensBC(), 'fn'); - - // Change from offsets to absolute token positions. - if ($expected['get'] !== false) { - foreach ($expected['get'] as $key => $value) { - $expected['get'][$key] += $stackPtr; - } - } - - // Verify the caching works. - $origStatus = Cache::$enabled; - Cache::$enabled = true; - - $resultFirstRun = FunctionDeclarations::getArrowFunctionOpenClose(self::$phpcsFile, $stackPtr); - $isCached = Cache::isCached(self::$phpcsFile, $methodName, $stackPtr); - $resultSecondRun = FunctionDeclarations::getArrowFunctionOpenClose(self::$phpcsFile, $stackPtr); - - if ($origStatus === false) { - Cache::clear(); - } - Cache::$enabled = $origStatus; - - $this->assertSame($expected['get'], $resultFirstRun, 'First result did not match expectation'); - $this->assertTrue($isCached, 'Cache::isCached() could not find the cached value'); - $this->assertSame($resultFirstRun, $resultSecondRun, 'Second result did not match first'); - } } diff --git a/Tests/Utils/Numbers/GetCompleteNumberTest.php b/Tests/Utils/Numbers/GetCompleteNumberTest.php index 1ebdf80b..87987d16 100644 --- a/Tests/Utils/Numbers/GetCompleteNumberTest.php +++ b/Tests/Utils/Numbers/GetCompleteNumberTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Utils\Numbers; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\TestUtils\UtilityMethodTestCase; use PHPCSUtils\Utils\Numbers; @@ -18,7 +17,6 @@ * Tests for the \PHPCSUtils\Utils\Numbers::getCompleteNumber() method. * * @covers \PHPCSUtils\Utils\Numbers::getCompleteNumber - * @covers \PHPCSUtils\Utils\Numbers::updateResult * * @group numbers * @@ -27,59 +25,6 @@ class GetCompleteNumberTest extends UtilityMethodTestCase { - /** - * The PHPCS version being used to run the tests. - * - * @var string - */ - public static $phpcsVersion = '0'; - - /** - * Whether or not the tests are being run on PHP 7.4 or higher. - * - * @var bool - */ - public static $php74OrHigher = false; - - /** - * Whether or not the tests are being run on PHP 8.1 or higher. - * - * @var bool - */ - public static $php81OrHigher = false; - - /** - * Whether the PHPCS version used to run the tests contains support for PHP 7.4 numeric literal separators. - * - * @var string - */ - public static $usableBackfill = false; - - /** - * Whether the PHPCS version used to run the tests contains support for PHP 8.1 explicit octal notation. - * - * @var string - */ - public static $explicitOctalSupport = false; - - /** - * Initialize the static properties, if not done before. - * - * @return void - */ - public static function setUpStaticProperties() - { - if (self::$phpcsVersion !== '0') { - return; - } - - self::$phpcsVersion = Helper::getVersion(); - self::$php74OrHigher = \version_compare(\PHP_VERSION_ID, '70399', '>'); - self::$php81OrHigher = \version_compare(\PHP_VERSION_ID, '80099', '>'); - self::$usableBackfill = \version_compare(self::$phpcsVersion, Numbers::UNSUPPORTED_PHPCS_VERSION, '>'); - self::$explicitOctalSupport = \version_compare(self::$phpcsVersion, '3.7.0', '>='); - } - /** * Test receiving an exception when a non-numeric token is passed to the method. * @@ -93,25 +38,6 @@ public function testNotANumberException() Numbers::getCompleteNumber(self::$phpcsFile, $stackPtr); } - /** - * Test receiving an exception when running PHPCS 3.5.3. - * - * @return void - */ - public function testUnsupportedPhpcsException() - { - if (\version_compare(static::$phpcsVersion, Numbers::UNSUPPORTED_PHPCS_VERSION, '!=') === true) { - $this->markTestSkipped('Test only applicable to PHPCS ' . Numbers::UNSUPPORTED_PHPCS_VERSION); - } - - $this->expectPhpcsException( - 'The PHPCSUtils\Utils\Numbers::getCompleteNumber() method does not support PHPCS ' - ); - - $stackPtr = $this->getTargetToken('/* testPHP74IntDecimalMultiUnderscore */', \T_LNUMBER); - Numbers::getCompleteNumber(self::$phpcsFile, $stackPtr); - } - /** * Test correctly identifying all tokens belonging to a numeric literal. * @@ -124,13 +50,6 @@ public function testUnsupportedPhpcsException() */ public function testGetCompleteNumber($testMarker, $expected) { - // Skip the test(s) on unsupported PHPCS versions. - if (\version_compare(static::$phpcsVersion, Numbers::UNSUPPORTED_PHPCS_VERSION, '==') === true) { - $this->markTestSkipped( - 'PHPCS ' . static::$phpcsVersion . ' is not supported due to buggy numeric string literal backfill.' - ); - } - $stackPtr = $this->getTargetToken($testMarker, [\T_LNUMBER, \T_DNUMBER]); $expected['last_token'] += $stackPtr; @@ -153,17 +72,6 @@ public function testGetCompleteNumber($testMarker, $expected) */ public function dataGetCompleteNumber() { - self::setUpStaticProperties(); - $multiToken = true; - if (self::$php74OrHigher === true || self::$usableBackfill === true) { - $multiToken = false; - } - - $octalMultiToken = true; - if (self::$php81OrHigher === true || self::$explicitOctalSupport === true) { - $octalMultiToken = false; - } - /* * Disabling the hexnumeric string detection for the rest of the file. * These are only strings within the context of PHPCS and need to be tested as such. @@ -273,7 +181,7 @@ public function dataGetCompleteNumber() 'code' => \T_LNUMBER, 'type' => 'T_LNUMBER', 'decimal' => '1000000000', - 'last_token' => $multiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-7.4-integer-larger-than-intmax-is-float' => [ @@ -284,7 +192,7 @@ public function dataGetCompleteNumber() 'code' => \T_DNUMBER, 'type' => 'T_DNUMBER', 'decimal' => '10223372036854775810', - 'last_token' => $multiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-7.4-float' => [ @@ -295,7 +203,7 @@ public function dataGetCompleteNumber() 'code' => \T_DNUMBER, 'type' => 'T_DNUMBER', 'decimal' => '107925284.88', - 'last_token' => $multiToken ? 2 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-7.4-integer-decimal-single-underscore' => [ @@ -306,7 +214,7 @@ public function dataGetCompleteNumber() 'code' => \T_LNUMBER, 'type' => 'T_LNUMBER', 'decimal' => '13500', - 'last_token' => $multiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-7.4-float-exponent-negative' => [ @@ -317,7 +225,7 @@ public function dataGetCompleteNumber() 'code' => \T_DNUMBER, 'type' => 'T_DNUMBER', 'decimal' => '6.674083e-11', - 'last_token' => $multiToken ? 3 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-7.4-float-exponent-positive' => [ @@ -328,7 +236,7 @@ public function dataGetCompleteNumber() 'code' => \T_DNUMBER, 'type' => 'T_DNUMBER', 'decimal' => '6.674083e+11', - 'last_token' => $multiToken ? 3 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-7.4-integer-decimal-multi-underscore-2' => [ @@ -339,7 +247,7 @@ public function dataGetCompleteNumber() 'code' => \T_LNUMBER, 'type' => 'T_LNUMBER', 'decimal' => '299792458', - 'last_token' => $multiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-7.4-integer-hex' => [ @@ -350,7 +258,7 @@ public function dataGetCompleteNumber() 'code' => \T_LNUMBER, 'type' => 'T_LNUMBER', 'decimal' => '3405705229', - 'last_token' => $multiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-7.4-integer-binary' => [ @@ -361,7 +269,7 @@ public function dataGetCompleteNumber() 'code' => \T_LNUMBER, 'type' => 'T_LNUMBER', 'decimal' => '95', - 'last_token' => $multiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-7.4-integer-octal' => [ @@ -372,7 +280,7 @@ public function dataGetCompleteNumber() 'code' => \T_LNUMBER, 'type' => 'T_LNUMBER', 'decimal' => '48673', - 'last_token' => $multiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-7.4-float-exponent-multi-underscore' => [ @@ -383,7 +291,7 @@ public function dataGetCompleteNumber() 'code' => \T_DNUMBER, 'type' => 'T_DNUMBER', 'decimal' => '12.34e123', - 'last_token' => $multiToken ? 3 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], @@ -396,7 +304,7 @@ public function dataGetCompleteNumber() 'code' => \T_LNUMBER, 'type' => 'T_LNUMBER', 'decimal' => '667083', - 'last_token' => $multiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-7.4-integer-calculation-2' => [ @@ -407,7 +315,7 @@ public function dataGetCompleteNumber() 'code' => \T_LNUMBER, 'type' => 'T_LNUMBER', 'decimal' => '74083', - 'last_token' => $multiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-7.4-float-calculation-1' => [ @@ -418,7 +326,7 @@ public function dataGetCompleteNumber() 'code' => \T_DNUMBER, 'type' => 'T_DNUMBER', 'decimal' => '6.67408e3', - 'last_token' => $multiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-7.4-float-calculation-2' => [ @@ -429,7 +337,7 @@ public function dataGetCompleteNumber() 'code' => \T_DNUMBER, 'type' => 'T_DNUMBER', 'decimal' => '6.67408e3', - 'last_token' => $multiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-7.4-integer-whitespace' => [ @@ -440,7 +348,7 @@ public function dataGetCompleteNumber() 'code' => \T_LNUMBER, 'type' => 'T_LNUMBER', 'decimal' => '107925284', - 'last_token' => $multiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-7.4-float-comments' => [ @@ -451,7 +359,7 @@ public function dataGetCompleteNumber() 'code' => \T_LNUMBER, 'type' => 'T_LNUMBER', 'decimal' => '107925284', - 'last_token' => $multiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], @@ -554,7 +462,7 @@ public function dataGetCompleteNumber() 'code' => \T_LNUMBER, 'type' => 'T_LNUMBER', 'decimal' => '48673', - 'last_token' => $octalMultiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-8.1-explicit-octal-uppercase' => [ @@ -565,7 +473,7 @@ public function dataGetCompleteNumber() 'code' => \T_LNUMBER, 'type' => 'T_LNUMBER', 'decimal' => '48673', - 'last_token' => $octalMultiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-8.1-explicit-octal-with-separator' => [ @@ -576,7 +484,7 @@ public function dataGetCompleteNumber() 'code' => \T_LNUMBER, 'type' => 'T_LNUMBER', 'decimal' => '48673', - 'last_token' => $octalMultiToken ? 1 : ($multiToken ? 2 : 0), // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-8.1-invalid-octal-1' => [ @@ -598,7 +506,7 @@ public function dataGetCompleteNumber() 'code' => \T_LNUMBER, 'type' => 'T_LNUMBER', 'decimal' => '2', - 'last_token' => $octalMultiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-8.1-invalid-octal-3' => [ @@ -609,7 +517,7 @@ public function dataGetCompleteNumber() 'code' => \T_LNUMBER, 'type' => 'T_LNUMBER', 'decimal' => '2', - 'last_token' => $octalMultiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-8.1-invalid-octal-4' => [ @@ -620,7 +528,7 @@ public function dataGetCompleteNumber() 'code' => \T_LNUMBER, 'type' => 'T_LNUMBER', 'decimal' => '2', - 'last_token' => $octalMultiToken ? 1 : 0, // Offset from $stackPtr. + 'last_token' => 0, // Offset from $stackPtr. ], ], 'php-7.4-8.1-invalid-explicit-octal' => [ diff --git a/Tests/Utils/ObjectDeclarations/GetNameJSTest.php b/Tests/Utils/ObjectDeclarations/GetNameJSTest.php index c9835127..e1772444 100644 --- a/Tests/Utils/ObjectDeclarations/GetNameJSTest.php +++ b/Tests/Utils/ObjectDeclarations/GetNameJSTest.php @@ -112,10 +112,6 @@ public function testGetDeclarationName($testMarker, $expected, $targetType = nul */ public function testGetDeclarationNameES6Method() { - if (\version_compare(static::$phpcsVersion, '3.0.0', '<') === true) { - $this->markTestSkipped('Support for JS ES6 method has not been backfilled for PHPCS 2.x (yet)'); - } - $target = $this->getTargetToken('/* testMethod */', [\T_CLASS, \T_INTERFACE, \T_TRAIT, \T_FUNCTION]); $result = ObjectDeclarations::getName(self::$phpcsFile, $target); $this->assertSame('methodName', $result); diff --git a/Tests/Utils/Operators/IsNullsafeObjectOperatorTest.inc b/Tests/Utils/Operators/IsNullsafeObjectOperatorTest.inc deleted file mode 100644 index aa7c34ff..00000000 --- a/Tests/Utils/Operators/IsNullsafeObjectOperatorTest.inc +++ /dev/null @@ -1,33 +0,0 @@ -foo; - -/* testNullsafeObjectOperator */ -echo $obj?->foo; - -/* testNullsafeObjectOperatorWriteContext */ -// Intentional parse error, but not the concern of this method. -$foo?->bar->baz = 'baz'; - -/* testTernaryThen */ -echo $obj ? $obj->prop : /* testObjectOperatorInTernary */ $other->prop; - -/* testParseErrorWhitespaceNotAllowed */ -echo $obj ? - -> foo; - -/* testParseErrorCommentNotAllowed */ -echo $obj ?/*comment*/-> foo; - -/* testLiveCoding */ -// Intentional parse error. This has to be the last test in the file. -echo $obj? - diff --git a/Tests/Utils/Operators/IsNullsafeObjectOperatorTest.php b/Tests/Utils/Operators/IsNullsafeObjectOperatorTest.php deleted file mode 100644 index 36ff1eeb..00000000 --- a/Tests/Utils/Operators/IsNullsafeObjectOperatorTest.php +++ /dev/null @@ -1,157 +0,0 @@ -assertFalse(Operators::isNullsafeObjectOperator(self::$phpcsFile, 10000)); - } - - /** - * Test that false is returned when an unsupported token is passed. - * - * @return void - */ - public function testUnsupportedToken() - { - $target = $this->getTargetToken('/* testUnsupportedToken */', \T_DOUBLE_COLON); - $this->assertFalse(Operators::isNullsafeObjectOperator(self::$phpcsFile, $target)); - } - - /** - * Test whether a nullsafe object operator is correctly identified as such. - * - * @dataProvider dataIsNullsafeObjectOperator - * - * @param string $testMarker The comment which prefaces the target token in the test file. - * - * @return void - */ - public function testIsNullsafeObjectOperator($testMarker) - { - $targetTokenTypes = $this->getTargetTokensTypes(); - $stackPtr = $this->getTargetToken($testMarker, $targetTokenTypes); - - $this->assertTrue( - Operators::isNullsafeObjectOperator(self::$phpcsFile, $stackPtr), - 'Failed asserting that (first) token is the nullsafe object operator' - ); - - // Also test the second token of a non-backfilled nullsafe object operator. - $tokens = self::$phpcsFile->getTokens(); - if ($tokens[$stackPtr]['code'] === \T_INLINE_THEN) { - $stackPtr = $this->getTargetToken($testMarker, [\T_OBJECT_OPERATOR]); - - $this->assertTrue( - Operators::isNullsafeObjectOperator(self::$phpcsFile, $stackPtr), - 'Failed asserting that (second) token is the nullsafe object operator' - ); - } - } - - /** - * Data provider. - * - * @see testIsNullsafeObjectOperator() - * - * @return array - */ - public function dataIsNullsafeObjectOperator() - { - return [ - 'nullsafe' => ['/* testNullsafeObjectOperator */'], - 'nullsafe-write-context' => ['/* testNullsafeObjectOperatorWriteContext */'], - ]; - } - - /** - * Test whether tokens which can be confused with a non-nullsafe object operator are - * not misidentified as a nullsafe object operator. - * - * @dataProvider dataNotNullsafeObjectOperator - * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param bool $textNext Whether to also test the next non-empty token. Defaults to false. - * - * @return void - */ - public function testNotNullsafeObjectOperator($testMarker, $textNext = false) - { - $stackPtr = $this->getTargetToken($testMarker, $this->getTargetTokensTypes()); - - $this->assertFalse(Operators::isNullsafeObjectOperator(self::$phpcsFile, $stackPtr)); - - if ($textNext === true) { - $next = self::$phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true); - $this->assertFalse(Operators::isNullsafeObjectOperator(self::$phpcsFile, $next)); - } - } - - /** - * Data provider. - * - * @see testNotNullsafeObjectOperator() - * - * @return array - */ - public function dataNotNullsafeObjectOperator() - { - return [ - 'normal-object-operator' => ['/* testObjectOperator */'], - 'ternary-then' => ['/* testTernaryThen */'], - 'object-operator-in-ternary' => ['/* testObjectOperatorInTernary */'], - 'parse-error-whitespace-not-allowed' => ['/* testParseErrorWhitespaceNotAllowed */', true], - 'parse-error-comment-not-allowed' => ['/* testParseErrorCommentNotAllowed */', true], - 'live-coding' => ['/* testLiveCoding */'], - ]; - } - - /** - * Get the target token types to pass to the getTargetToken() method. - * - * @return array => - */ - private function getTargetTokensTypes() - { - $targets = [ - \T_OBJECT_OPERATOR, - \T_INLINE_THEN, - ]; - - if (TokenHelper::tokenExists('T_NULLSAFE_OBJECT_OPERATOR') === true) { - $targets[] = \T_NULLSAFE_OBJECT_OPERATOR; - } - - return $targets; - } -} diff --git a/Tests/Utils/Operators/IsReferenceDiffTest.inc b/Tests/Utils/Operators/IsReferenceDiffTest.inc deleted file mode 100644 index 2f9f0e04..00000000 --- a/Tests/Utils/Operators/IsReferenceDiffTest.inc +++ /dev/null @@ -1,13 +0,0 @@ -assertFalse(Operators::isReference(self::$phpcsFile, 10000)); - } - - /** - * Test correctly identifying that whether a "bitwise and" token is a reference or not. + * Initialize PHPCS & tokenize the test case file. * - * @dataProvider dataIsReference - * - * @param string $testMarker Comment which precedes the test case. - * @param bool $expected Expected function output. + * @beforeClass * * @return void */ - public function testIsReference($testMarker, $expected) + public static function setUpTestFile() { - $bitwiseAnd = $this->getTargetToken($testMarker, \T_BITWISE_AND); - $result = Operators::isReference(self::$phpcsFile, $bitwiseAnd); - $this->assertSame($expected, $result); + self::$caseFile = \dirname(\dirname(__DIR__)) . '/DummyFile.inc'; + parent::setUpTestFile(); } /** - * Data provider. - * - * @see testIsReference() + * Test passing a non-existent token pointer. * - * @return array + * @return void */ - public function dataIsReference() + public function testNonExistentToken() { - return [ - 'issue-1971-list-first-in-file' => [ - 'testMarker' => '/* testTokenizerIssue1971PHPCSlt330gt271A */', - 'expected' => true, - ], - 'issue-1971-list-first-in-file-nested' => [ - 'testMarker' => '/* testTokenizerIssue1971PHPCSlt330gt271B */', - 'expected' => true, - ], - 'issue-1284-short-list-directly-after-close-curly-control-structure' => [ - 'testMarker' => '/* testTokenizerIssue1284PHPCSlt280A */', - 'expected' => true, - ], - 'issue-1284-short-list-directly-after-close-curly-control-structure-second-item' => [ - 'testMarker' => '/* testTokenizerIssue1284PHPCSlt280B */', - 'expected' => true, - ], - 'issue-1284-short-array-directly-after-close-curly-control-structure' => [ - 'testMarker' => '/* testTokenizerIssue1284PHPCSlt280C */', - 'expected' => true, - ], - ]; + $this->assertFalse(Operators::isReference(self::$phpcsFile, 10000)); } } diff --git a/Tests/Utils/Operators/IsShortTernaryTest.inc b/Tests/Utils/Operators/IsShortTernaryTest.inc index 8561039c..a8b2436e 100644 --- a/Tests/Utils/Operators/IsShortTernaryTest.inc +++ b/Tests/Utils/Operators/IsShortTernaryTest.inc @@ -19,24 +19,6 @@ $foo = $foo ? /* deliberately left empty */ // phpcs:ignore Stnd.Cat.Sniff -- For reasons. : 'bar'; -/* testDontConfuseWithNullCoalesce */ -$foo = $foo ?? 0; - -/* testDontConfuseWithNullCoalesceEquals */ -$foo ??= 0; - -class Foo { - /* testDontConfuseWithNullable1 */ - protected ?int $property = 1; - - public function bar( - /* testDontConfuseWithNullable2 */ - ?bool $param - /* testDontConfuseWithNullable3 */ - ) : ?\My\ClassName { - } -} - /* testParseError */ // Intentional parse error. This has to be the last test in the file. $foo = $foo ? diff --git a/Tests/Utils/Operators/IsShortTernaryTest.php b/Tests/Utils/Operators/IsShortTernaryTest.php index 7e17c232..2567c5e0 100644 --- a/Tests/Utils/Operators/IsShortTernaryTest.php +++ b/Tests/Utils/Operators/IsShortTernaryTest.php @@ -11,7 +11,6 @@ namespace PHPCSUtils\Tests\Utils\Operators; use PHPCSUtils\TestUtils\UtilityMethodTestCase; -use PHPCSUtils\Tokens\TokenHelper; use PHPCSUtils\Utils\Operators; /** @@ -96,75 +95,4 @@ public function dataIsShortTernary() ], ]; } - - /** - * Safeguard that incorrectly tokenized T_INLINE_THEN or T_INLINE_ELSE tokens are correctly - * rejected as not short ternary. - * - * {@internal None of these are really problematic, but better to be safe than sorry.} - * - * @dataProvider dataIsShortTernaryTokenizerIssues - * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string $tokenType The token code to look for. - * - * @return void - */ - public function testIsShortTernaryTokenizerIssues($testMarker, $tokenType = \T_INLINE_THEN) - { - $stackPtr = $this->getTargetToken($testMarker, $tokenType); - $result = Operators::isShortTernary(self::$phpcsFile, $stackPtr); - $this->assertFalse($result); - } - - /** - * Data provider. - * - * @see testIsShortTernaryTokenizerIssues() For the array format. - * - * @return array - */ - public function dataIsShortTernaryTokenizerIssues() - { - $targetCoalesce = [\T_INLINE_THEN]; - if (\defined('T_COALESCE')) { - $targetCoalesce[] = \T_COALESCE; - } - - $targetCoalesceAndEquals = $targetCoalesce; - if (TokenHelper::tokenExists('T_COALESCE_EQUAL')) { - $targetCoalesceAndEquals[] = \T_COALESCE_EQUAL; - } - - $targetNullable = [\T_INLINE_THEN]; - if (\defined('T_NULLABLE')) { - $targetNullable[] = \T_NULLABLE; - } - - return [ - 'null-coalesce' => [ - 'testMarker' => '/* testDontConfuseWithNullCoalesce */', - 'tokenType' => $targetCoalesce, - ], - 'null-coalesce-equals' => [ - 'testMarker' => '/* testDontConfuseWithNullCoalesceEquals */', - 'tokenType' => $targetCoalesceAndEquals, - ], - 'nullable-property' => [ - 'testMarker' => '/* testDontConfuseWithNullable1 */', - 'tokenType' => $targetNullable, - ], - 'nullable-param-type' => [ - 'testMarker' => '/* testDontConfuseWithNullable2 */', - 'tokenType' => $targetNullable, - ], - 'nullable-return-type' => [ - 'testMarker' => '/* testDontConfuseWithNullable3 */', - 'tokenType' => $targetNullable, - ], - 'parse-error' => [ - 'testMarker' => '/* testParseError */', - ], - ]; - } } diff --git a/Tests/Utils/Operators/IsTypeUnionTest.inc b/Tests/Utils/Operators/IsTypeUnionTest.inc deleted file mode 100644 index 94cb51e5..00000000 --- a/Tests/Utils/Operators/IsTypeUnionTest.inc +++ /dev/null @@ -1,131 +0,0 @@ - $param | $int; - -/* testTypeUnionArrowReturnType */ -$arrowWithReturnType = fn ($param) : int|null => $param * 10; - -/* testBitwiseOrInArrayKey */ -$array = array( - A | B => /* testBitwiseOrInArrayValue */ B | C -); - -/* testBitwiseOrInShortArrayKey */ -$array = [ - A | B => /* testBitwiseOrInShortArrayValue */ B | C -]; - -/* testBitwiseOrTryCatch */ -try { -} catch ( ExceptionA | ExceptionB $e ) { -} - -/* testBitwiseOrNonArrowFnFunctionCall */ -$obj->fn($something | $else); - -/* testTypeUnionNonArrowFunctionDeclaration */ -function &fn(int|false $something) {} - -/* testBitwiseOrInNestedTernaryPhpcsLt291 */ -echo $a ? $b : CONST_A ? CONST_A | CONST_B : CONST_C; - -/* testTypeUnionInTernaryNestedArrowFunction1 */ -$fn = fn($a): int|float => $a ? /* testTypeUnionInTernaryNestedArrowFunction2 */ fn() : string|false => 'a' : /* testTypeUnionInTernaryNestedArrowFunction3 */ fn() : ?bool|null => 'b'; - -/* testBitwiseOrInTernaryNestedArrowFunction */ -$fn = fn($a) => $a ? fn( $var = CONST_A | CONST_B ) : ?string => 'a' : fn() : string => 'b'; - -/* testLiveCoding */ -// Intentional parse error. This has to be the last test in the file. -return function( type| diff --git a/Tests/Utils/Operators/IsTypeUnionTest.php b/Tests/Utils/Operators/IsTypeUnionTest.php deleted file mode 100644 index e2cfee6a..00000000 --- a/Tests/Utils/Operators/IsTypeUnionTest.php +++ /dev/null @@ -1,164 +0,0 @@ -assertFalse(Operators::isTypeUnion(self::$phpcsFile, 10000)); - } - - /** - * Test that false is returned when a non-bitwise or token is passed. - * - * @return void - */ - public function testNotBitwiseOrToken() - { - $target = $this->getTargetToken('/* testNotBitwiseOrToken */', \T_ECHO); - $this->assertFalse(Operators::isTypeUnion(self::$phpcsFile, $target)); - } - - /** - * Test whether a type union separator is correctly identified as such. - * - * @dataProvider dataIsTypeUnion - * - * @param string $testMarker The comment which prefaces the target token in the test file. - * - * @return void - */ - public function testIsTypeUnion($testMarker) - { - $targets = [\T_BITWISE_OR]; - if (\defined('T_TYPE_UNION') === true) { - $targets[] = \T_TYPE_UNION; - } - - $stackPtr = $this->getTargetToken($testMarker, $targets); - - $this->assertTrue(Operators::isTypeUnion(self::$phpcsFile, $stackPtr)); - } - - /** - * Data provider. - * - * @see testIsTypeUnion() - * - * @return array - */ - public function dataIsTypeUnion() - { - return [ - 'property' => ['/* testTypeUnionPropertySimple */'], - 'property-reverse-modifier-order' => ['/* testTypeUnionPropertyReverseModifierOrder */'], - 'property-multi-type-1' => ['/* testTypeUnionPropertyMulti1 */'], - 'property-multi-type-2' => ['/* testTypeUnionPropertyMulti2 */'], - 'property-multi-type-3' => ['/* testTypeUnionPropertyMulti3 */'], - 'property-namespace-operator' => ['/* testTypeUnionPropertyNamespaceRelative */'], - 'property-partially-qualified' => ['/* testTypeUnionPropertyPartiallyQualified */'], - 'property-fully-qualified' => ['/* testTypeUnionPropertyFullyQualified */'], - 'parameter-multi-type-1' => ['/* testTypeUnionParam1 */'], - 'parameter-multi-type-2' => ['/* testTypeUnionParam2 */'], - 'parameter-multi-type-3' => ['/* testTypeUnionParam3 */'], - 'parameter-namespace-operator' => ['/* testTypeUnionParamNamespaceRelative */'], - 'parameter-partially-qualified' => ['/* testTypeUnionParamPartiallyQualified */'], - 'parameter-fully-qualified' => ['/* testTypeUnionParamFullyQualified */'], - 'return' => ['/* testTypeUnionReturnType */'], - 'constructor-property-promotion' => ['/* testTypeUnionConstructorPropertyPromotion */'], - 'return-abstract-method-1' => ['/* testTypeUnionAbstractMethodReturnType1 */'], - 'return-abstract-method-2' => ['/* testTypeUnionAbstractMethodReturnType2 */'], - 'return-namespace-operator' => ['/* testTypeUnionReturnTypeNamespaceRelative */'], - 'return-partially-qualified' => ['/* testTypeUnionReturnPartiallyQualified */'], - 'return-fully-qualified' => ['/* testTypeUnionReturnFullyQualified */'], - 'parameter-closure-with-nullable' => ['/* testTypeUnionClosureParamIllegalNullable */'], - 'parameter-with-reference' => ['/* testTypeUnionWithReference */'], - 'parameter-with-spread-operator' => ['/* testTypeUnionWithSpreadOperator */'], - 'return-closure' => ['/* testTypeUnionClosureReturn */'], - 'parameter-arrow' => ['/* testTypeUnionArrowParam */'], - 'return-arrow' => ['/* testTypeUnionArrowReturnType */'], - 'parameter-non-arrow-fn-decl' => ['/* testTypeUnionNonArrowFunctionDeclaration */'], - 'return-ternary-nested-arrow-1' => ['/* testTypeUnionInTernaryNestedArrowFunction1 */'], - 'return-ternary-nested-arrow-2' => ['/* testTypeUnionInTernaryNestedArrowFunction2 */'], - 'return-ternary-nested-arrow-3' => ['/* testTypeUnionInTernaryNestedArrowFunction3 */'], - ]; - } - - /** - * Test whether a real "bitwise or" is correctly identified as such. - * - * @dataProvider dataBitwiseOr - * - * @param string $testMarker The comment which prefaces the target token in the test file. - * - * @return void - */ - public function testBitwiseOr($testMarker) - { - $targets = [\T_BITWISE_OR]; - if (\defined('T_TYPE_UNION') === true) { - $targets[] = \T_TYPE_UNION; - } - - $stackPtr = $this->getTargetToken($testMarker, $targets); - - $this->assertFalse(Operators::isTypeUnion(self::$phpcsFile, $stackPtr)); - } - - /** - * Data provider. - * - * @see testBitwiseOr() - * - * @return array - */ - public function dataBitwiseOr() - { - return [ - 'bitwiseor-1' => ['/* testBitwiseOr1 */'], - 'bitwiseor-2' => ['/* testBitwiseOr2 */'], - 'bitwiseor-property-default' => ['/* testBitwiseOrPropertyDefaultValue */'], - 'bitwiseor-param-default' => ['/* testBitwiseOrParamDefaultValue */'], - 'bitwiseor-3' => ['/* testBitwiseOr3 */'], - 'bitwiseor-closure-param-default' => ['/* testBitwiseOrClosureParamDefault */'], - 'bitwiseor-arrow-param-default' => ['/* testBitwiseOrArrowParamDefault */'], - 'bitwiseor-arrow-expression' => ['/* testBitwiseOrArrowExpression */'], - 'bitwiseor-in-array-key' => ['/* testBitwiseOrInArrayKey */'], - 'bitwiseor-in-array-value' => ['/* testBitwiseOrInArrayValue */'], - 'bitwiseor-in-short-array-key' => ['/* testBitwiseOrInShortArrayKey */'], - 'bitwiseor-in-short-array-value' => ['/* testBitwiseOrInShortArrayValue */'], - 'bitwiseor-in-try-catch' => ['/* testBitwiseOrTryCatch */'], - 'bitwiseor-in-non-arrow-fn-call' => ['/* testBitwiseOrNonArrowFnFunctionCall */'], - 'bitwiseor-in-nested-ternary' => ['/* testBitwiseOrInNestedTernaryPhpcsLt291 */'], - 'bitwiseor-in-ternary-arrow-fn' => ['/* testBitwiseOrInTernaryNestedArrowFunction */'], - 'live-coding' => ['/* testLiveCoding */'], - ]; - } -} diff --git a/Tests/Utils/Operators/IsUnaryPlusMinusTest.inc b/Tests/Utils/Operators/IsUnaryPlusMinusTest.inc index 1ebcda25..0ab78a6b 100644 --- a/Tests/Utils/Operators/IsUnaryPlusMinusTest.inc +++ b/Tests/Utils/Operators/IsUnaryPlusMinusTest.inc @@ -161,12 +161,6 @@ $a = /* testSequenceUnaryEnd */ + /*comment*/ 10; -/* testPHP74NumericLiteralFloatContainingPlus */ -$a = 6.674_083e+11; - -/* testPHP74NumericLiteralFloatContainingMinus */ -$a = 6.674_083e-1_1; - /* testPHP74NumericLiteralIntCalc1 */ $a = 667_083 - 11; diff --git a/Tests/Utils/Operators/IsUnaryPlusMinusTest.php b/Tests/Utils/Operators/IsUnaryPlusMinusTest.php index 581fa52b..c0c01a69 100644 --- a/Tests/Utils/Operators/IsUnaryPlusMinusTest.php +++ b/Tests/Utils/Operators/IsUnaryPlusMinusTest.php @@ -11,7 +11,6 @@ namespace PHPCSUtils\Tests\Utils\Operators; use PHPCSUtils\TestUtils\UtilityMethodTestCase; -use PHPCSUtils\Utils\Numbers; use PHPCSUtils\Utils\Operators; /** @@ -54,30 +53,11 @@ public function testNotPlusMinusToken() * * @param string $testMarker The comment which prefaces the target token in the test file. * @param bool $expected The expected boolean return value. - * @param bool $maybeSkip Whether the "should this test be skipped" check should be executed. - * Defaults to false. * * @return void */ - public function testIsUnaryPlusMinus($testMarker, $expected, $maybeSkip = false) + public function testIsUnaryPlusMinus($testMarker, $expected) { - if ($maybeSkip === true) { - /* - * Skip the test if this is PHP 7.4 or a PHPCS version which backfills the token sequence - * to one token as in that case, the plus/minus token won't exist - */ - if (\version_compare(\PHP_VERSION_ID, '70399', '>') === true) { - $this->markTestSkipped('Test irrelevant as the target token won\'t exist when on PHP >= 7.4'); - } - - if (\version_compare(static::$phpcsVersion, Numbers::UNSUPPORTED_PHPCS_VERSION, '>=') === true) { - $this->markTestSkipped( - 'Test irrelevant as the target token won\'t exist when on PHPCS >= ' - . Numbers::UNSUPPORTED_PHPCS_VERSION - ); - } - } - $stackPtr = $this->getTargetToken($testMarker, [\T_PLUS, \T_MINUS]); $result = Operators::isUnaryPlusMinus(self::$phpcsFile, $stackPtr); @@ -306,16 +286,6 @@ public function dataIsUnaryPlusMinus() 'testMarker' => '/* testSequenceUnaryEnd */', 'expected' => true, ], - 'php-7.4-underscore-float-containing-plus' => [ - 'testMarker' => '/* testPHP74NumericLiteralFloatContainingPlus */', - 'expected' => false, - 'maybeSkip' => true, // Skip for PHP 7.4 & PHPCS 3.5.3+. - ], - 'php-7.4-underscore-float-containing-minus' => [ - 'testMarker' => '/* testPHP74NumericLiteralFloatContainingMinus */', - 'expected' => false, - 'maybeSkip' => true, // Skip for PHP 7.4 & PHPCS 3.5.3+. - ], 'php-7.4-underscore-int-calculation-1' => [ 'testMarker' => '/* testPHP74NumericLiteralIntCalc1 */', 'expected' => false, diff --git a/Tests/Utils/Parentheses/ParenthesesTest.php b/Tests/Utils/Parentheses/ParenthesesTest.php index 7f6d04f8..9b7859ef 100644 --- a/Tests/Utils/Parentheses/ParenthesesTest.php +++ b/Tests/Utils/Parentheses/ParenthesesTest.php @@ -12,8 +12,6 @@ use PHPCSUtils\BackCompat\BCTokens; use PHPCSUtils\TestUtils\UtilityMethodTestCase; -use PHPCSUtils\Tokens\Collections; -use PHPCSUtils\Tokens\TokenHelper; use PHPCSUtils\Utils\Parentheses; /** @@ -414,8 +412,6 @@ public function testPassingParenthesisCloseHandlingInBCLayer() /** * Test that a function named fn sees the T_FUNCTION token as owner, not the T_FN token. * - * This specifically tests the BC-layer for arrow functions. - * * @return void */ public function testFunctionNamedFnKeywordNotParenthesesOwner() @@ -956,11 +952,6 @@ public function testHasOwner($testName, $expectedResults) // Add expected results for all owner types not listed in the data provider. $expectedResults += $this->ownerDefaults; - if (TokenHelper::tokenExists('T_FN') === false) { - $expectedResults['T_STRING'] = $expectedResults['T_FN']; - unset($expectedResults['T_FN']); - } - foreach ($expectedResults as $ownerType => $expected) { $result = Parentheses::hasOwner(self::$phpcsFile, $stackPtr, \constant($ownerType)); $this->assertSame( @@ -1319,8 +1310,6 @@ public function testLastOwnerIn($testName, $validOwners, $expected) */ public function dataLastOwnerIn() { - $arrowFunctionOwners = Collections::arrowFunctionTokensBC(); - return [ 'testElseIfWithClosure-$a-closure' => [ 'testName' => 'testElseIfWithClosure-$a', @@ -1374,7 +1363,7 @@ public function dataLastOwnerIn() ], 'testArrowFunction-$param' => [ 'testName' => 'testArrowFunction-$param', - 'validOwners' => $arrowFunctionOwners, + 'validOwners' => [\T_FN], 'expected' => -2, ], @@ -1385,7 +1374,7 @@ public function dataLastOwnerIn() ], 'testArrowFunctionReturnByRef' => [ 'testName' => 'testArrowFunctionReturnByRef', - 'validOwners' => $arrowFunctionOwners, + 'validOwners' => [\T_FN], 'expected' => -4, ], 'testIfEmpty-$c-unset' => [ diff --git a/Tests/Utils/PassedParameters/GetParameterFromStackTest.php b/Tests/Utils/PassedParameters/GetParameterFromStackTest.php index e28a916e..48040a1d 100644 --- a/Tests/Utils/PassedParameters/GetParameterFromStackTest.php +++ b/Tests/Utils/PassedParameters/GetParameterFromStackTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Utils\PassedParameters; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\TestUtils\UtilityMethodTestCase; use PHPCSUtils\Utils\PassedParameters; @@ -179,21 +178,15 @@ public function testGetParameterFunctionCallWithParamName($testMarker, $expected */ public function dataGetParameterFunctionCallWithParamName() { - /* - * Work around to account for the different token positions due to the old tokenization - * to T_GOTO_LABEL which joins two tokens into one (incorrectly). - */ - $namedParamsInPhpcs = \version_compare(Helper::getVersion(), '3.6.0', '>='); - return [ 'all-named-non-standard-order' => [ 'testMarker' => '/* testAllParamsNamedNonStandardOrder */', 'expected' => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 46 : 42, - 'name_end' => ($namedParamsInPhpcs === true) ? 49 : 44, + 'name_start' => 46, + 'name_end' => 49, 'name' => 'value', - 'start' => ($namedParamsInPhpcs === true) ? 50 : 45, - 'end' => ($namedParamsInPhpcs === true) ? 51 : 46, + 'start' => 50, + 'end' => 51, 'raw' => "'value'", ], ], @@ -298,12 +291,6 @@ public function testGetParameterFromStack($testMarker, $expectedName, $expectedE */ public function dataGetParameterFromStack() { - /* - * Work around to account for the different token positions due to the old tokenization - * to T_GOTO_LABEL which joins two tokens into one (incorrectly). - */ - $namedParamsInPhpcs = \version_compare(Helper::getVersion(), '3.6.0', '>='); - return [ 'all-params-all-positional' => [ 'testMarker' => '/* testAllParamsPositional */', @@ -327,53 +314,53 @@ public function dataGetParameterFromStack() 'testMarker' => '/* testAllParamsNamedStandardOrder */', 'expectedName' => [ 'name_start' => 2, - 'name_end' => ($namedParamsInPhpcs === true) ? 5 : 4, + 'name_end' => 5, 'name' => 'name', - 'start' => ($namedParamsInPhpcs === true) ? 6 : 5, - 'end' => ($namedParamsInPhpcs === true) ? 7 : 6, + 'start' => 6, + 'end' => 7, 'raw' => "'name'", ], 'expectedExpires' => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 16 : 14, - 'name_end' => ($namedParamsInPhpcs === true) ? 19 : 16, + 'name_start' => 16, + 'name_end' => 19, 'name' => 'expires_or_options', - 'start' => ($namedParamsInPhpcs === true) ? 20 : 17, - 'end' => ($namedParamsInPhpcs === true) ? 37 : 34, + 'start' => 20, + 'end' => 37, 'raw' => 'time() + (60 * 60 * 24)', ], 'expectedHttpOnly' => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 60 : 54, - 'name_end' => ($namedParamsInPhpcs === true) ? 63 : 56, + 'name_start' => 60, + 'name_end' => 63, 'name' => 'httponly', - 'start' => ($namedParamsInPhpcs === true) ? 64 : 57, - 'end' => ($namedParamsInPhpcs === true) ? 66 : 59, + 'start' => 64, + 'end' => 66, 'raw' => 'false', ], ], 'all-params-all-named-random-order' => [ 'testMarker' => '/* testAllParamsNamedNonStandardOrder */', 'expectedName' => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 32 : 30, - 'name_end' => ($namedParamsInPhpcs === true) ? 35 : 32, + 'name_start' => 32, + 'name_end' => 35, 'name' => 'name', - 'start' => ($namedParamsInPhpcs === true) ? 36 : 33, - 'end' => ($namedParamsInPhpcs === true) ? 37 : 34, + 'start' => 36, + 'end' => 37, 'raw' => "'name'", ], 'expectedExpires' => [ 'name_start' => 2, - 'name_end' => ($namedParamsInPhpcs === true) ? 5 : 4, + 'name_end' => 5, 'name' => 'expires_or_options', - 'start' => ($namedParamsInPhpcs === true) ? 6 : 5, - 'end' => ($namedParamsInPhpcs === true) ? 23 : 22, + 'start' => 6, + 'end' => 23, 'raw' => 'time() + (60 * 60 * 24)', ], 'expectedHttpOnly' => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 53 : 48, - 'name_end' => ($namedParamsInPhpcs === true) ? 56 : 50, + 'name_start' => 53, + 'name_end' => 56, 'name' => 'httponly', - 'start' => ($namedParamsInPhpcs === true) ? 57 : 51, - 'end' => ($namedParamsInPhpcs === true) ? 58 : 52, + 'start' => 57, + 'end' => 58, 'raw' => 'false', ], ], @@ -390,11 +377,11 @@ public function dataGetParameterFromStack() 'raw' => 'time() + (60 * 60 * 24)', ], 'expectedHttpOnly' => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 44 : 42, - 'name_end' => ($namedParamsInPhpcs === true) ? 47 : 44, + 'name_start' => 44, + 'name_end' => 47, 'name' => 'httponly', - 'start' => ($namedParamsInPhpcs === true) ? 48 : 45, - 'end' => ($namedParamsInPhpcs === true) ? 49 : 46, + 'start' => 48, + 'end' => 49, 'raw' => 'false', ], ], @@ -407,10 +394,10 @@ public function dataGetParameterFromStack() ], 'expectedExpires' => [ 'name_start' => 6, - 'name_end' => ($namedParamsInPhpcs === true) ? 9 : 8, + 'name_end' => 9, 'name' => 'expires_or_options', - 'start' => ($namedParamsInPhpcs === true) ? 10 : 9, - 'end' => ($namedParamsInPhpcs === true) ? 27 : 26, + 'start' => 10, + 'end' => 27, 'raw' => 'time() + (60 * 60 * 24)', ], 'expectedHttpOnly' => false, @@ -424,10 +411,10 @@ public function dataGetParameterFromStack() ], 'expectedExpires' => [ 'name_start' => 6, - 'name_end' => ($namedParamsInPhpcs === true) ? 9 : 8, + 'name_end' => 9, 'name' => 'expires', - 'start' => ($namedParamsInPhpcs === true) ? 10 : 9, - 'end' => ($namedParamsInPhpcs === true) ? 27 : 26, + 'start' => 10, + 'end' => 27, 'raw' => 'time() + (60 * 60 * 24)', ], 'expectedHttpOnly' => false, diff --git a/Tests/Utils/PassedParameters/GetParametersNamedTest.php b/Tests/Utils/PassedParameters/GetParametersNamedTest.php index 03a76d20..31ba87d7 100644 --- a/Tests/Utils/PassedParameters/GetParametersNamedTest.php +++ b/Tests/Utils/PassedParameters/GetParametersNamedTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Utils\PassedParameters; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\TestUtils\UtilityMethodTestCase; use PHPCSUtils\Utils\PassedParameters; @@ -81,17 +80,7 @@ public function testGetParameters($testMarker, $targetType, $expected, $targetCo */ public function dataGetParameters() { - /* - * Work arounds to account for: - * 1. The different tokenization of namespaces names in PHP 8 and different PHPCS versions. - * 2. The different token positions due to the old tokenization to T_GOTO_LABEL - * which joins two tokens into one (incorrectly). - * 3. The new `match` keyword being recognized on PHP 8, but not before, while - * the `match` control structure is not supported in PHPCS yet. - */ - $php8Names = parent::usesPhp8NameTokens(); - $namedParamsInPhpcs = \version_compare(Helper::getVersion(), '3.6.0', '>='); - $matchIsKeyword = \version_compare(\PHP_VERSION_ID, '80000', '>='); + $php8Names = parent::usesPhp8NameTokens(); return [ 'only-positional-args' => [ @@ -121,26 +110,26 @@ public function dataGetParameters() 'expected' => [ 1 => [ 'name_start' => 2, - 'name_end' => ($namedParamsInPhpcs === true) ? 3 : 2, + 'name_end' => 3, 'name' => 'start_index', - 'start' => ($namedParamsInPhpcs === true) ? 4 : 3, - 'end' => ($namedParamsInPhpcs === true) ? 5 : 4, + 'start' => 4, + 'end' => 5, 'raw' => '0', ], 2 => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 7 : 6, - 'name_end' => ($namedParamsInPhpcs === true) ? 9 : 7, + 'name_start' => 7, + 'name_end' => 9, 'name' => 'count', - 'start' => ($namedParamsInPhpcs === true) ? 10 : 8, - 'end' => ($namedParamsInPhpcs === true) ? 11 : 9, + 'start' => 10, + 'end' => 11, 'raw' => '100', ], 3 => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 13 : 11, - 'name_end' => ($namedParamsInPhpcs === true) ? 15 : 12, + 'name_start' => 13, + 'name_end' => 15, 'name' => 'value', - 'start' => ($namedParamsInPhpcs === true) ? 16 : 13, - 'end' => ($namedParamsInPhpcs === true) ? 17 : 14, + 'start' => 16, + 'end' => 17, 'raw' => '50', ], ], @@ -197,10 +186,10 @@ public function dataGetParameters() ], 3 => [ 'name_start' => 21, - 'name_end' => ($namedParamsInPhpcs === true) ? 23 : 22, + 'name_end' => 23, 'name' => 'value', - 'start' => ($namedParamsInPhpcs === true) ? 24 : 23, - 'end' => ($namedParamsInPhpcs === true) ? 25 : 24, + 'start' => 24, + 'end' => 25, 'raw' => '50', ], ], @@ -216,10 +205,10 @@ public function dataGetParameters() ], 2 => [ 'name_start' => 4, - 'name_end' => ($namedParamsInPhpcs === true) ? 6 : 5, + 'name_end' => 6, 'name' => 'double_encode', - 'start' => ($namedParamsInPhpcs === true) ? 7 : 6, - 'end' => ($namedParamsInPhpcs === true) ? 8 : 7, + 'start' => 7, + 'end' => 8, 'raw' => 'false', ], ], @@ -230,26 +219,26 @@ public function dataGetParameters() 'expected' => [ 1 => [ 'name_start' => 2, - 'name_end' => ($namedParamsInPhpcs === true) ? 5 : 4, + 'name_end' => 5, 'name' => 'start_index', - 'start' => ($namedParamsInPhpcs === true) ? 6 : 5, - 'end' => ($namedParamsInPhpcs === true) ? 17 : 15, + 'start' => 6, + 'end' => 17, 'raw' => '/* testNestedFunctionCallInner1 */ $obj->getPos(skip: false)', ], 2 => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 19 : 17, - 'name_end' => ($namedParamsInPhpcs === true) ? 22 : 19, + 'name_start' => 19, + 'name_end' => 22, 'name' => 'count', - 'start' => ($namedParamsInPhpcs === true) ? 23 : 20, - 'end' => ($namedParamsInPhpcs === true) ? 32 : 28, + 'start' => 23, + 'end' => 32, 'raw' => '/* testNestedFunctionCallInner2 */ count(array_or_countable: $array)', ], 3 => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 34 : 30, - 'name_end' => ($namedParamsInPhpcs === true) ? 37 : 32, + 'name_start' => 34, + 'name_end' => 37, 'name' => 'value', - 'start' => ($namedParamsInPhpcs === true) ? 38 : 33, - 'end' => ($namedParamsInPhpcs === true) ? 40 : 35, + 'start' => 38, + 'end' => 40, 'raw' => '50', ], ], @@ -260,10 +249,10 @@ public function dataGetParameters() 'expected' => [ 1 => [ 'name_start' => 2, - 'name_end' => ($namedParamsInPhpcs === true) ? 3 : 2, + 'name_end' => 3, 'name' => 'skip', - 'start' => ($namedParamsInPhpcs === true) ? 4 : 3, - 'end' => ($namedParamsInPhpcs === true) ? 5 : 4, + 'start' => 4, + 'end' => 5, 'raw' => 'false', ], ], @@ -274,10 +263,10 @@ public function dataGetParameters() 'expected' => [ 1 => [ 'name_start' => 2, - 'name_end' => ($namedParamsInPhpcs === true) ? 3 : 2, + 'name_end' => 3, 'name' => 'array_or_countable', - 'start' => ($namedParamsInPhpcs === true) ? 4 : 3, - 'end' => ($namedParamsInPhpcs === true) ? 5 : 4, + 'start' => 4, + 'end' => 5, 'raw' => '$array', ], ], @@ -288,18 +277,18 @@ public function dataGetParameters() 'expected' => [ 1 => [ 'name_start' => 2, - 'name_end' => ($namedParamsInPhpcs === true) ? 3 : 2, + 'name_end' => 3, 'name' => 'label', - 'start' => ($namedParamsInPhpcs === true) ? 4 : 3, - 'end' => ($namedParamsInPhpcs === true) ? 5 : 4, + 'start' => 4, + 'end' => 5, 'raw' => '$string', ], 2 => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 7 : 6, - 'name_end' => ($namedParamsInPhpcs === true) ? 9 : 7, + 'name_start' => 7, + 'name_end' => 9, 'name' => 'more', - 'start' => ($namedParamsInPhpcs === true) ? 10 : 8, - 'end' => ($namedParamsInPhpcs === true) ? 10 : 8, + 'start' => 10, + 'end' => 10, 'raw' => 'false', ], ], @@ -311,18 +300,18 @@ public function dataGetParameters() 'expected' => [ 1 => [ 'name_start' => 2, - 'name_end' => ($namedParamsInPhpcs === true) ? 3 : 2, + 'name_end' => 3, 'name' => 'label', - 'start' => ($namedParamsInPhpcs === true) ? 4 : 3, - 'end' => ($namedParamsInPhpcs === true) ? 5 : 4, + 'start' => 4, + 'end' => 5, 'raw' => '$string', ], 2 => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 7 : 6, - 'name_end' => ($namedParamsInPhpcs === true) ? 9 : 7, + 'name_start' => 7, + 'name_end' => 9, 'name' => 'more', - 'start' => ($namedParamsInPhpcs === true) ? 10 : 8, - 'end' => ($namedParamsInPhpcs === true) ? 10 : 8, + 'start' => 10, + 'end' => 10, 'raw' => 'false', ], ], @@ -333,18 +322,18 @@ public function dataGetParameters() 'expected' => [ 1 => [ 'name_start' => 2, - 'name_end' => ($namedParamsInPhpcs === true) ? 3 : 2, + 'name_end' => 3, 'name' => 'label', - 'start' => ($namedParamsInPhpcs === true) ? 4 : 3, - 'end' => ($namedParamsInPhpcs === true) ? 5 : 4, + 'start' => 4, + 'end' => 5, 'raw' => '$string', ], 2 => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 7 : 6, - 'name_end' => ($namedParamsInPhpcs === true) ? 9 : 7, + 'name_start' => 7, + 'name_end' => 9, 'name' => 'more', - 'start' => ($namedParamsInPhpcs === true) ? 10 : 8, - 'end' => ($namedParamsInPhpcs === true) ? 10 : 8, + 'start' => 10, + 'end' => 10, 'raw' => 'false', ], ], @@ -355,18 +344,18 @@ public function dataGetParameters() 'expected' => [ 1 => [ 'name_start' => 2, - 'name_end' => ($namedParamsInPhpcs === true) ? 3 : 2, + 'name_end' => 3, 'name' => 'label', - 'start' => ($namedParamsInPhpcs === true) ? 4 : 3, - 'end' => ($namedParamsInPhpcs === true) ? 5 : 4, + 'start' => 4, + 'end' => 5, 'raw' => '$string', ], 2 => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 7 : 6, - 'name_end' => ($namedParamsInPhpcs === true) ? 9 : 7, + 'name_start' => 7, + 'name_end' => 9, 'name' => 'more', - 'start' => ($namedParamsInPhpcs === true) ? 10 : 8, - 'end' => ($namedParamsInPhpcs === true) ? 11 : 9, + 'start' => 10, + 'end' => 11, 'raw' => 'false', ], ], @@ -377,26 +366,26 @@ public function dataGetParameters() 'expected' => [ 1 => [ 'name_start' => 2, - 'name_end' => ($namedParamsInPhpcs === true) ? 3 : 2, + 'name_end' => 3, 'name' => '💩💩💩', - 'start' => ($namedParamsInPhpcs === true) ? 4 : 3, - 'end' => ($namedParamsInPhpcs === true) ? 6 : 5, + 'start' => 4, + 'end' => 6, 'raw' => '[]', ], 2 => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 8 : 7, - 'name_end' => ($namedParamsInPhpcs === true) ? 10 : 8, + 'name_start' => 8, + 'name_end' => 10, 'name' => 'Пасха', - 'start' => ($namedParamsInPhpcs === true) ? 11 : 9, - 'end' => ($namedParamsInPhpcs === true) ? 12 : 10, + 'start' => 11, + 'end' => 12, 'raw' => "'text'", ], 3 => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 14 : 12, - 'name_end' => ($namedParamsInPhpcs === true) ? 16 : 13, + 'name_start' => 14, + 'name_end' => 16, 'name' => '_valid', - 'start' => ($namedParamsInPhpcs === true) ? 17 : 14, - 'end' => ($namedParamsInPhpcs === true) ? 18 : 15, + 'start' => 17, + 'end' => 18, 'raw' => '123', ], ], @@ -426,18 +415,18 @@ public function dataGetParameters() 'expected' => [ 1 => [ 'name_start' => 2, - 'name_end' => ($namedParamsInPhpcs === true) ? 4 : 3, + 'name_end' => 4, 'name' => 'label', - 'start' => ($namedParamsInPhpcs === true) ? 5 : 4, - 'end' => ($namedParamsInPhpcs === true) ? 14 : 13, + 'start' => 5, + 'end' => 14, 'raw' => '$cond ? true : false', ], 2 => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 16 : 15, - 'name_end' => ($namedParamsInPhpcs === true) ? 18 : 17, + 'name_start' => 16, + 'name_end' => 18, 'name' => 'more', - 'start' => ($namedParamsInPhpcs === true) ? 19 : 18, - 'end' => ($namedParamsInPhpcs === true) ? 29 : 28, + 'start' => 19, + 'end' => 29, 'raw' => '$cond ? CONSTANT_A : CONSTANT_B', ], ], @@ -476,15 +465,15 @@ public function dataGetParameters() 'expected' => [ 1 => [ 'name_start' => 2, - 'name_end' => ($namedParamsInPhpcs === true) ? 3 : 2, + 'name_end' => 3, 'name' => 'param', - 'start' => ($namedParamsInPhpcs === true) ? 4 : 3, - 'end' => ($namedParamsInPhpcs === true) ? 5 : 4, + 'start' => 4, + 'end' => 5, 'raw' => '$bar', ], 2 => [ - 'start' => ($namedParamsInPhpcs === true) ? 7 : 6, - 'end' => ($namedParamsInPhpcs === true) ? 8 : 7, + 'start' => 7, + 'end' => 8, 'raw' => '$foo', ], ], @@ -495,18 +484,18 @@ public function dataGetParameters() 'expected' => [ 1 => [ 'name_start' => 2, - 'name_end' => ($namedParamsInPhpcs === true) ? 3 : 2, + 'name_end' => 3, 'name' => 'param', - 'start' => ($namedParamsInPhpcs === true) ? 4 : 3, - 'end' => ($namedParamsInPhpcs === true) ? 5 : 4, + 'start' => 4, + 'end' => 5, 'raw' => '1', ], 2 => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 7 : 6, - 'name_end' => ($namedParamsInPhpcs === true) ? 9 : 7, + 'name_start' => 7, + 'name_end' => 9, 'name' => 'param', - 'start' => ($namedParamsInPhpcs === true) ? 10 : 8, - 'end' => ($namedParamsInPhpcs === true) ? 11 : 9, + 'start' => 10, + 'end' => 11, 'raw' => '2', ], ], @@ -517,15 +506,15 @@ public function dataGetParameters() 'expected' => [ 1 => [ 'name_start' => 2, - 'name_end' => ($namedParamsInPhpcs === true) ? 3 : 2, + 'name_end' => 3, 'name' => 'start_index', - 'start' => ($namedParamsInPhpcs === true) ? 4 : 3, - 'end' => ($namedParamsInPhpcs === true) ? 5 : 4, + 'start' => 4, + 'end' => 5, 'raw' => '0', ], 2 => [ - 'start' => ($namedParamsInPhpcs === true) ? 7 : 6, - 'end' => ($namedParamsInPhpcs === true) ? 14 : 13, + 'start' => 7, + 'end' => 14, 'raw' => '...[100, 50]', ], ], @@ -541,10 +530,10 @@ public function dataGetParameters() ], 2 => [ 'name_start' => 5, - 'name_end' => ($namedParamsInPhpcs === true) ? 7 : 6, + 'name_end' => 7, 'name' => 'param', - 'start' => ($namedParamsInPhpcs === true) ? 8 : 7, - 'end' => ($namedParamsInPhpcs === true) ? 9 : 8, + 'start' => 8, + 'end' => 9, 'raw' => '$value', ], ], @@ -598,42 +587,42 @@ public function dataGetParameters() ], 5 => [ 'name_start' => 30, - 'name_end' => ($namedParamsInPhpcs === true) ? 33 : 32, + 'name_end' => 33, 'name' => 'iterable', - 'start' => ($namedParamsInPhpcs === true) ? 34 : 33, - 'end' => ($namedParamsInPhpcs === true) ? 35 : 34, + 'start' => 34, + 'end' => 35, 'raw' => '$value', ], 6 => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 37 : 36, - 'name_end' => ($namedParamsInPhpcs === true) ? 40 : (($matchIsKeyword === true) ? 39 : 38), + 'name_start' => 37, + 'name_end' => 40, 'name' => 'match', - 'start' => ($namedParamsInPhpcs === true) ? 41 : (($matchIsKeyword === true) ? 40 : 39), - 'end' => ($namedParamsInPhpcs === true) ? 42 : (($matchIsKeyword === true) ? 41 : 40), + 'start' => 41, + 'end' => 42, 'raw' => '$value', ], 7 => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 44 : (($matchIsKeyword === true) ? 43 : 42), - 'name_end' => ($namedParamsInPhpcs === true) ? 47 : (($matchIsKeyword === true) ? 46 : 45), + 'name_start' => 44, + 'name_end' => 47, 'name' => 'protected', - 'start' => ($namedParamsInPhpcs === true) ? 48 : (($matchIsKeyword === true) ? 47 : 46), - 'end' => ($namedParamsInPhpcs === true) ? 49 : (($matchIsKeyword === true) ? 48 : 47), + 'start' => 48, + 'end' => 49, 'raw' => '$value', ], 8 => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 51 : (($matchIsKeyword === true) ? 50 : 49), - 'name_end' => ($namedParamsInPhpcs === true) ? 54 : (($matchIsKeyword === true) ? 52 : 51), + 'name_start' => 51, + 'name_end' => 54, 'name' => 'object', - 'start' => ($namedParamsInPhpcs === true) ? 55 : (($matchIsKeyword === true) ? 53 : 52), - 'end' => ($namedParamsInPhpcs === true) ? 56 : (($matchIsKeyword === true) ? 54 : 53), + 'start' => 55, + 'end' => 56, 'raw' => '$value', ], 9 => [ - 'name_start' => ($namedParamsInPhpcs === true) ? 58 : (($matchIsKeyword === true) ? 56 : 55), - 'name_end' => ($namedParamsInPhpcs === true) ? 61 : (($matchIsKeyword === true) ? 58 : 57), + 'name_start' => 58, + 'name_end' => 61, 'name' => 'parent', - 'start' => ($namedParamsInPhpcs === true) ? 62 : (($matchIsKeyword === true) ? 59 : 58), - 'end' => ($namedParamsInPhpcs === true) ? 63 : (($matchIsKeyword === true) ? 60 : 59), + 'start' => 62, + 'end' => 63, 'raw' => '$value', ], ], diff --git a/Tests/Utils/PassedParameters/GetParametersTest.php b/Tests/Utils/PassedParameters/GetParametersTest.php index 8f0bab0e..876ae1df 100644 --- a/Tests/Utils/PassedParameters/GetParametersTest.php +++ b/Tests/Utils/PassedParameters/GetParametersTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Utils\PassedParameters; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Internal\Cache; use PHPCSUtils\TestUtils\UtilityMethodTestCase; use PHPCSUtils\Utils\PassedParameters; @@ -321,10 +320,7 @@ public function dataGetParameters() ], 3 => [ 'start' => 31, - // Account for null coalesce tokenization difference. - 'end' => (Helper::getVersion() === '2.6.0' && \PHP_VERSION_ID < 59999) - ? 53 - : 51, + 'end' => 51, 'raw' => '\'hey\' => $baz ?? [\'one\'] ?? [\'two\']', diff --git a/Tests/Utils/PassedParameters/HasParametersTest.php b/Tests/Utils/PassedParameters/HasParametersTest.php index 7cdbe629..cff91827 100644 --- a/Tests/Utils/PassedParameters/HasParametersTest.php +++ b/Tests/Utils/PassedParameters/HasParametersTest.php @@ -173,8 +173,7 @@ public function dataHasParameters() ], 'no-params-function-call-5-new-self' => [ 'testMarker' => '/* testNoParamsFunctionCall5 */', - // In PHPCS < 2.8.0, self in "new self" is tokenized as T_STRING. - 'targetType' => [\T_SELF, \T_STRING], + 'targetType' => \T_SELF, 'expected' => false, ], 'no-params-function-call-6-new-static' => [ @@ -184,8 +183,7 @@ public function dataHasParameters() ], 'no-params-function-call-7-new-parent' => [ 'testMarker' => '/* testNoParamsFunctionCall7 */', - // In PHPCS < 3.7.0, parent in "new parent" is tokenized as T_STRING. - 'targetType' => [\T_PARENT, \T_STRING], + 'targetType' => \T_PARENT, 'expected' => false, ], @@ -201,8 +199,7 @@ public function dataHasParameters() ], 'has-params-function-call-3-new-self' => [ 'testMarker' => '/* testHasParamsFunctionCall3 */', - // In PHPCS < 2.8.0, self in "new self" is tokenized as T_STRING. - 'targetType' => [\T_SELF, \T_STRING], + 'targetType' => \T_SELF, 'expected' => true, ], 'has-params-function-call-4-new-static' => [ @@ -212,8 +209,7 @@ public function dataHasParameters() ], 'has-params-function-call-5-new-parent' => [ 'testMarker' => '/* testHasParamsFunctionCall5 */', - // In PHPCS < 3.7.0, parent in "new parent" is tokenized as T_STRING. - 'targetType' => [\T_PARENT, \T_STRING], + 'targetType' => \T_PARENT, 'expected' => true, ], 'has-params-function-call-6-self-as-method-name' => [ diff --git a/Tests/Utils/TextStrings/GetEndOfDoubleQuotedStringTest.inc b/Tests/Utils/TextStrings/GetEndOfCompleteTextStringTest.inc similarity index 96% rename from Tests/Utils/TextStrings/GetEndOfDoubleQuotedStringTest.inc rename to Tests/Utils/TextStrings/GetEndOfCompleteTextStringTest.inc index 7a5d20f5..b9890ed8 100644 --- a/Tests/Utils/TextStrings/GetEndOfDoubleQuotedStringTest.inc +++ b/Tests/Utils/TextStrings/GetEndOfCompleteTextStringTest.inc @@ -3,9 +3,6 @@ // These tests mirror the upstream Core\Tokenizer\DoubleQuotedStringsTest. // Test source: https://gist.github.com/iluuu1994/72e2154fc4150f2258316b0255b698f2#file-test-php -/* testNotDoubleQuotedString */ -$var = 'test'; - /* testSimple1 */ "$foo"; /* testSimple2 */ diff --git a/Tests/Utils/TextStrings/GetEndOfDoubleQuotedStringTest.php b/Tests/Utils/TextStrings/GetEndOfCompleteTextStringTest.php similarity index 81% rename from Tests/Utils/TextStrings/GetEndOfDoubleQuotedStringTest.php rename to Tests/Utils/TextStrings/GetEndOfCompleteTextStringTest.php index 39e527f5..1d40907f 100644 --- a/Tests/Utils/TextStrings/GetEndOfDoubleQuotedStringTest.php +++ b/Tests/Utils/TextStrings/GetEndOfCompleteTextStringTest.php @@ -10,49 +10,25 @@ namespace PHPCSUtils\Tests\Utils\TextStrings; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\TestUtils\UtilityMethodTestCase; use PHPCSUtils\Utils\GetTokensAsString; use PHPCSUtils\Utils\TextStrings; /** - * Tests for the \PHPCSUtils\Utils\TextStrings::getDoubleQuotedString() method covering a specific tokenizer + * Tests for the \PHPCSUtils\Utils\TextStrings::getEndOfCompleteTextString() method covering a specific tokenizer * issue as reported upstream in {@link https://github.com/squizlabs/PHP_CodeSniffer/pull/3604 PHPCS 3604}. * - * @covers \PHPCSUtils\Utils\TextStrings::getEndOfDoubleQuotedString + * {@internal The exceptions thrown by the method are tested in the `GetCompleteTextStringTest` class.} + * + * @covers \PHPCSUtils\Utils\TextStrings::getEndOfCompleteTextString * * @group textstrings * * @since 1.0.0 */ -class GetEndOfDoubleQuotedStringTest extends UtilityMethodTestCase +class GetEndOfCompleteTextStringTest extends UtilityMethodTestCase { - /** - * Test passing a non-existent token pointer. - * - * @return void - */ - public function testNonExistentToken() - { - $this->expectPhpcsException('$stackPtr must be of type T_DOUBLE_QUOTED_STRING'); - - TextStrings::getEndOfDoubleQuotedString(self::$phpcsFile, 100000); - } - - /** - * Test receiving an expected exception when a non text string is passed. - * - * @return void - */ - public function testNotATextStringException() - { - $this->expectPhpcsException('$stackPtr must be of type T_DOUBLE_QUOTED_STRING'); - - $next = $this->getTargetToken('/* testNotDoubleQuotedString */', \T_CONSTANT_ENCAPSED_STRING); - TextStrings::getEndOfDoubleQuotedString(self::$phpcsFile, $next); - } - /** * Test correctly retrieving the contents of a double quoted text string with potentially problematic * embedded variables/expressions. @@ -67,7 +43,7 @@ public function testNotATextStringException() public function testGetEndOfDoubleQuotedString($testMarker, $expectedContent) { $stackPtr = $this->getTargetToken($testMarker, \T_DOUBLE_QUOTED_STRING); - $result = TextStrings::getEndOfDoubleQuotedString(self::$phpcsFile, $stackPtr); + $result = TextStrings::getEndOfCompleteTextString(self::$phpcsFile, $stackPtr); $this->assertSame($expectedContent, GetTokensAsString::normal(self::$phpcsFile, $stackPtr, $result)); } @@ -81,7 +57,7 @@ public function testGetEndOfDoubleQuotedString($testMarker, $expectedContent) */ public function dataGetEndOfDoubleQuotedString() { - $data = [ + return [ 'Simple embedded variable 1' => [ 'testMarker' => '/* testSimple1 */', 'expectedContent' => '"$foo"', @@ -169,13 +145,13 @@ public function dataGetEndOfDoubleQuotedString() 'Problem embed at end of line in multi-line text string' => [ 'testMarker' => '/* testProblemEmbedAtEndOfLineInMultiLineString */', 'expectedContent' => '"Testing ${foo["${bar[\'baz\']}"]} -', +and more testing"', ], 'Multi-line problem embed in multi-line text string' => [ 'testMarker' => '/* testMultilineProblemEmbedInMultiLineString */', 'expectedContent' => '"Testing ${foo["${bar [\'baz\'] -}', +}"]} and more testing"', ], 'Parse error at end of file' => [ @@ -184,13 +160,5 @@ public function dataGetEndOfDoubleQuotedString() ', ], ]; - - $version = Helper::getVersion(); - if (\version_compare($version, '3.7.0', '>=') === true) { - $data['Multi-line problem embed in multi-line text string']['expectedContent'] = '"Testing ${foo["${bar -'; - } - - return $data; } } diff --git a/Tests/Utils/UseStatements/SplitImportUseStatementTest.inc b/Tests/Utils/UseStatements/SplitImportUseStatementTest.inc index d930e345..ad23ddcf 100644 --- a/Tests/Utils/UseStatements/SplitImportUseStatementTest.inc +++ b/Tests/Utils/UseStatements/SplitImportUseStatementTest.inc @@ -69,6 +69,10 @@ use Some\NS\ { AnotherLevel, }; +/* testUsePlainReservedKeyword */ +// Intentional parse error - use of reserved keyword in namespace. +use Vendor\break\ClassName; + /* testUseFunctionPlainReservedKeyword */ // Intentional parse error - use of reserved keyword in namespace. use function Vendor\YourNamespace\switch\yourFunction; diff --git a/Tests/Utils/UseStatements/SplitImportUseStatementTest.php b/Tests/Utils/UseStatements/SplitImportUseStatementTest.php index 8518fc8e..d5baf09d 100644 --- a/Tests/Utils/UseStatements/SplitImportUseStatementTest.php +++ b/Tests/Utils/UseStatements/SplitImportUseStatementTest.php @@ -242,6 +242,15 @@ public function dataSplitImportUseStatement() 'const' => ['SOME_CONSTANT' => 'Some\NS\Constants\CONSTANT_NAME'], ], ], + + 'parse-error-plain-reserved-keyword' => [ + 'testMarker' => '/* testUsePlainReservedKeyword */', + 'expected' => [ + 'name' => ['ClassName' => 'Vendor\break\ClassName'], + 'function' => [], + 'const' => [], + ], + ], 'parse-error-function-plain-reserved-keyword' => [ 'testMarker' => '/* testUseFunctionPlainReservedKeyword */', 'expected' => [ diff --git a/Tests/Utils/MessageHelper/HasNewLineSupportTest.inc b/Tests/Xtra/Messages/HasNewLineSupportTest.inc similarity index 100% rename from Tests/Utils/MessageHelper/HasNewLineSupportTest.inc rename to Tests/Xtra/Messages/HasNewLineSupportTest.inc diff --git a/Tests/Utils/MessageHelper/HasNewLineSupportTest.php b/Tests/Xtra/Messages/HasNewLineSupportTest.php similarity index 84% rename from Tests/Utils/MessageHelper/HasNewLineSupportTest.php rename to Tests/Xtra/Messages/HasNewLineSupportTest.php index 24482dda..5fd31147 100644 --- a/Tests/Utils/MessageHelper/HasNewLineSupportTest.php +++ b/Tests/Xtra/Messages/HasNewLineSupportTest.php @@ -8,22 +8,21 @@ * @link https://github.com/PHPCSStandards/PHPCSUtils */ -namespace PHPCSUtils\Tests\Utils\MessageHelper; +namespace PHPCSUtils\Tests\Xtra\Messages; use PHP_CodeSniffer\Reporter; use PHP_CodeSniffer\Reports\Full; use PHPCSUtils\Tests\PolyfilledTestCase; -use PHPCSUtils\Utils\MessageHelper; /** - * Tests for the \PHPCSUtils\Utils\MessageHelper::hasNewLineSupport() method. + * Tests for new line handling in PHPCS error/warning messages. * - * {@internal Note: this is largely testing PHPCS native functionality, but as PHPCS doesn't + * {@internal Note: this is testing PHPCS native functionality, but as PHPCS doesn't * have any unit tests in place for this functionality, that's not a bad thing.} * - * @covers \PHPCSUtils\Utils\MessageHelper::hasNewLineSupport + * @coversNothing * - * @group messagehelper + * @group xtra * * @since 1.0.0 */ @@ -37,33 +36,22 @@ class HasNewLineSupportTest extends PolyfilledTestCase * * @var string */ - const CODE = 'PHPCSUtils.MessageHelper.HasNewLineSupportTest.Found'; + const CODE = 'PHPCSUtils.Xtra.HasNewLineSupportTest.Found'; /** * Set the name of a sniff to pass to PHPCS to limit the run (and force it to record errors). * * @var array */ - protected static $selectedSniff = ['PHPCSUtils.MessageHelper.HasNewLineSupportTest']; + protected static $selectedSniff = ['PHPCSUtils.Xtra.HasNewLineSupportTest']; /** - * Test the hasNewLineSupport() detection. + * Test that PHPCS properly supports new lines in error messages. * * @return void */ public function testHasNewLineSupport() { - $result = MessageHelper::hasNewLineSupport(); - $this->assertIsBool($result); - - if ($result === false) { - return; - } - - /* - * Test the actual message returned for PHPCS versions which have proper new line support. - */ - /* * Set up the expected output. * phpcs:disable Generic.Files.LineLength.TooLong diff --git a/Tests/Xtra/README.md b/Tests/Xtra/README.md new file mode 100644 index 00000000..2cf66264 --- /dev/null +++ b/Tests/Xtra/README.md @@ -0,0 +1,8 @@ +# Xtra Tests + +This is a directory for tests not directly related to functionality within PHPCSUtils. + +These tests safeguard functionality from PHP_CodeSniffer for which PHPCS itself does not have suffiencient test coverage. + +In most cases, these type of tests should be pulled to PHP_CodeSniffer itself, but if testing this within the PHPCS native test framework would be difficult, tests can be placed here. +Tests can also be added here for functionality for which PHPCS just doesn't have enough tests or temporarily, while waiting for a test PR to be merged in PHPCS itself. diff --git a/Tests/bootstrap.php b/Tests/bootstrap.php index 789e756d..8e660fb9 100644 --- a/Tests/bootstrap.php +++ b/Tests/bootstrap.php @@ -51,17 +51,10 @@ // Try and load the PHPCS autoloader. if ($phpcsDir !== false && \file_exists($phpcsDir . '/autoload.php')) { - // PHPCS 3.x. require_once $phpcsDir . '/autoload.php'; // Pre-load the token back-fills to prevent undefined constant notices. require_once $phpcsDir . '/src/Util/Tokens.php'; -} elseif ($phpcsDir !== false && \file_exists($phpcsDir . '/CodeSniffer.php')) { - // PHPCS 2.x. - require_once $phpcsDir . '/CodeSniffer.php'; - - // Pre-load the token back-fills to prevent undefined constant notices. - require_once $phpcsDir . '/CodeSniffer/Tokens.php'; } else { echo 'Uh oh... can\'t find PHPCS. diff --git a/composer.json b/composer.json index 313235e1..d634265d 100644 --- a/composer.json +++ b/composer.json @@ -23,19 +23,17 @@ }, "require" : { "php" : ">=5.4", - "squizlabs/php_codesniffer" : "^2.6.0 || ^3.1.0 || 4.0.x-dev@dev", + "squizlabs/php_codesniffer" : "^3.7.1 || 4.0.x-dev@dev", "dealerdirect/phpcodesniffer-composer-installer" : "^0.4.1 || ^0.5 || ^0.6.2 || ^0.7" }, "require-dev" : { "ext-filter": "*", + "phpcsstandards/phpcsdevcs": "^1.1.3", "php-parallel-lint/php-parallel-lint": "^1.3.2", "php-parallel-lint/php-console-highlighter": "^1.0", "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.3", "yoast/phpunit-polyfills": "^1.0.1" }, - "conflict": { - "squizlabs/php_codesniffer": "3.5.3" - }, "minimum-stability": "dev", "prefer-stable": true, "autoload": { @@ -56,21 +54,11 @@ "lint": [ "@php ./vendor/php-parallel-lint/php-parallel-lint/parallel-lint . -e php --exclude vendor --exclude .git" ], - "install-devcs": [ - "composer require phpcsstandards/phpcsdevcs:\"^1.1.3\" --no-suggest" - ], - "remove-devcs": [ - "composer remove phpcsstandards/phpcsdevcs" - ], "checkcs": [ - "@install-devcs", - "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs", - "@remove-devcs" + "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs" ], "fixcs": [ - "@install-devcs", - "@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf", - "@remove-devcs" + "@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf" ], "test": [ "@php ./vendor/phpunit/phpunit/phpunit --no-coverage" diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 14d42f00..022e9368 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -33,9 +33,7 @@ to be recorded properly, while still allowing the tests to run on all supported PHP/PHPUnit/PHPCS combinations. --> - ./Tests/BackCompat/BCTokens/EmptyTokensTest.php ./Tests/Utils/Namespaces/NamespaceTypeTest.php - ./Tests/Utils/Numbers/GetCompleteNumberTest.php ./Tests/ @@ -45,9 +43,7 @@ Tests/Internal/NoFileCache/GetClearTest.php Tests/Internal/NoFileCache/SetTest.php - Tests/BackCompat/BCTokens/EmptyTokensTest.php Tests/Utils/Namespaces/NamespaceTypeTest.php - Tests/Utils/Numbers/GetCompleteNumberTest.php