Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
tipuloidea
/
back
/
vendor
/
friendsofphp
/
php-cs-fixer
/
src
/
Fixer
/
LanguageConstruct
:
CombineConsecutiveIssetsFixer.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php declare(strict_types=1); /* * This file is part of PHP CS Fixer. * * (c) Fabien Potencier <fabien@symfony.com> * Dariusz RumiĆski <dariusz.ruminski@gmail.com> * * This source file is subject to the MIT license that is bundled * with this source code in the file LICENSE. */ namespace PhpCsFixer\Fixer\LanguageConstruct; use PhpCsFixer\AbstractFixer; use PhpCsFixer\FixerDefinition\CodeSample; use PhpCsFixer\FixerDefinition\FixerDefinition; use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; use PhpCsFixer\Tokenizer\Token; use PhpCsFixer\Tokenizer\Tokens; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise. */ final class CombineConsecutiveIssetsFixer extends AbstractFixer { public function getDefinition(): FixerDefinitionInterface { return new FixerDefinition( 'Using `isset($var) &&` multiple times should be done in one call.', [new CodeSample("<?php\n\$a = isset(\$a) && isset(\$b);\n")], ); } /** * {@inheritdoc} * * Must run before MultilineWhitespaceBeforeSemicolonsFixer, NoSinglelineWhitespaceBeforeSemicolonsFixer, NoSpacesInsideParenthesisFixer, NoTrailingWhitespaceFixer, NoWhitespaceInBlankLineFixer, SpacesInsideParenthesesFixer. */ public function getPriority(): int { return 4; } public function isCandidate(Tokens $tokens): bool { return $tokens->isAllTokenKindsFound([\T_ISSET, \T_BOOLEAN_AND]); } protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { $tokenCount = $tokens->count(); for ($index = 1; $index < $tokenCount; ++$index) { if (!$tokens[$index]->isGivenKind(\T_ISSET) || !$tokens[$tokens->getPrevMeaningfulToken($index)]->equalsAny(['(', '{', ';', '=', [\T_OPEN_TAG], [\T_BOOLEAN_AND], [\T_BOOLEAN_OR]])) { continue; } $issetInfo = $this->getIssetInfo($tokens, $index); $issetCloseBraceIndex = end($issetInfo); // ')' token $insertLocation = (int) prev($issetInfo) + 1; // one index after the previous meaningful of ')' $booleanAndTokenIndex = $tokens->getNextMeaningfulToken($issetCloseBraceIndex); while ($tokens[$booleanAndTokenIndex]->isGivenKind(\T_BOOLEAN_AND)) { $issetIndex = $tokens->getNextMeaningfulToken($booleanAndTokenIndex); if (!$tokens[$issetIndex]->isGivenKind(\T_ISSET)) { $index = $issetIndex; break; } // fetch info about the 'isset' statement that we're merging $nextIssetInfo = $this->getIssetInfo($tokens, $issetIndex); $nextMeaningfulTokenIndex = $tokens->getNextMeaningfulToken(end($nextIssetInfo)); $nextMeaningfulToken = $tokens[$nextMeaningfulTokenIndex]; if (!$nextMeaningfulToken->equalsAny([')', '}', ';', [\T_CLOSE_TAG], [\T_BOOLEAN_AND], [\T_BOOLEAN_OR]])) { $index = $nextMeaningfulTokenIndex; break; } // clone what we want to move, do not clone '(' and ')' of the 'isset' statement we're merging $clones = $this->getTokenClones($tokens, \array_slice($nextIssetInfo, 1, -1)); // clean up now the tokens of the 'isset' statement we're merging $this->clearTokens($tokens, array_merge($nextIssetInfo, [$issetIndex, $booleanAndTokenIndex])); // insert the tokens to create the new statement array_unshift($clones, new Token(','), new Token([\T_WHITESPACE, ' '])); $tokens->insertAt($insertLocation, $clones); // correct some counts and offset based on # of tokens inserted $numberOfTokensInserted = \count($clones); $tokenCount += $numberOfTokensInserted; $issetCloseBraceIndex += $numberOfTokensInserted; $insertLocation += $numberOfTokensInserted; $booleanAndTokenIndex = $tokens->getNextMeaningfulToken($issetCloseBraceIndex); } } } /** * @param list<int> $indices */ private function clearTokens(Tokens $tokens, array $indices): void { foreach ($indices as $index) { $tokens->clearTokenAndMergeSurroundingWhitespace($index); } } /** * @param int $index of T_ISSET * * @return non-empty-list<int> indices of meaningful tokens belonging to the isset statement */ private function getIssetInfo(Tokens $tokens, int $index): array { $openIndex = $tokens->getNextMeaningfulToken($index); $braceOpenCount = 1; $meaningfulTokenIndices = [$openIndex]; for ($i = $openIndex + 1;; ++$i) { if ($tokens[$i]->isWhitespace() || $tokens[$i]->isComment()) { continue; } $meaningfulTokenIndices[] = $i; if ($tokens[$i]->equals(')')) { --$braceOpenCount; if (0 === $braceOpenCount) { break; } } elseif ($tokens[$i]->equals('(')) { ++$braceOpenCount; } } return $meaningfulTokenIndices; } /** * @param list<int> $indices * * @return list<Token> */ private function getTokenClones(Tokens $tokens, array $indices): array { $clones = []; foreach ($indices as $i) { $clones[] = clone $tokens[$i]; } return $clones; } }