detectBlockType() public static method

Detect type of block.
public static detectBlockType ( PhpCsFixer\Tokenizer\Token $token ) : null | array
$token PhpCsFixer\Tokenizer\Token token
return null | array array with 'type' and 'isStart' keys or null if not found
Esempio n. 1
0
 /**
  * @param Tokens $tokens
  * @param int    $index
  *
  * @return int
  */
 private function findStart(Tokens $tokens, $index)
 {
     do {
         $index = $tokens->getPrevMeaningfulToken($index);
         $token = $tokens[$index];
         $blockType = $tokens->detectBlockType($token);
         if (null !== $blockType && !$blockType['isStart']) {
             $index = $tokens->findBlockEnd($blockType['type'], $index, false);
             $token = $tokens[$index];
         }
     } while (!$token->equalsAny(array('$', array(T_VARIABLE))));
     $prevIndex = $tokens->getPrevMeaningfulToken($index);
     $prevToken = $tokens[$prevIndex];
     if ($prevToken->equals('$')) {
         $index = $prevIndex;
         $prevIndex = $tokens->getPrevMeaningfulToken($index);
         $prevToken = $tokens[$prevIndex];
     }
     if ($prevToken->isGivenKind(T_OBJECT_OPERATOR)) {
         return $this->findStart($tokens, $prevIndex);
     }
     if ($prevToken->isGivenKind(T_PAAMAYIM_NEKUDOTAYIM)) {
         $prevPrevIndex = $tokens->getPrevMeaningfulToken($prevIndex);
         if (!$tokens[$prevPrevIndex]->isGivenKind(T_STRING)) {
             return $this->findStart($tokens, $prevIndex);
         }
         $index = $tokens->getTokenNotOfKindSibling($prevIndex, -1, array(array(T_NS_SEPARATOR), array(T_STRING)));
         $index = $tokens->getNextMeaningfulToken($index);
     }
     return $index;
 }
Esempio n. 2
0
 /**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     foreach ($tokens as $index => $token) {
         if (!$token->isGivenKind(T_ECHO)) {
             continue;
         }
         $nextTokenIndex = $tokens->getNextMeaningfulToken($index);
         $endTokenIndex = $tokens->getNextTokenOfKind($index, array(';', array(T_CLOSE_TAG)));
         $canBeConverted = true;
         for ($i = $nextTokenIndex; $i < $endTokenIndex; ++$i) {
             if ($tokens[$i]->equalsAny(array('(', array(CT_ARRAY_SQUARE_BRACE_OPEN)))) {
                 $blockType = $tokens->detectBlockType($tokens[$i]);
                 $i = $tokens->findBlockEnd($blockType['type'], $i);
             }
             if ($tokens[$i]->equals(',')) {
                 $canBeConverted = false;
                 break;
             }
         }
         if (false === $canBeConverted) {
             continue;
         }
         $tokens->overrideAt($index, array(T_PRINT, 'print'));
     }
 }
 /**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     foreach ($tokens as $index => $token) {
         if (!$token->isGivenKind(T_ECHO)) {
             continue;
         }
         /*
          * HHVM parses '<?=' as T_ECHO instead of T_OPEN_TAG_WITH_ECHO
          *
          * @see https://github.com/facebook/hhvm/issues/4809
          * @see https://github.com/facebook/hhvm/issues/7161
          */
         if (defined('HHVM_VERSION') && 0 === strpos($token->getContent(), '<?=')) {
             continue;
         }
         $nextTokenIndex = $tokens->getNextMeaningfulToken($index);
         $endTokenIndex = $tokens->getNextTokenOfKind($index, array(';', array(T_CLOSE_TAG)));
         $canBeConverted = true;
         for ($i = $nextTokenIndex; $i < $endTokenIndex; ++$i) {
             if ($tokens[$i]->equalsAny(array('(', array(CT_ARRAY_SQUARE_BRACE_OPEN)))) {
                 $blockType = Tokens::detectBlockType($tokens[$i]);
                 $i = $tokens->findBlockEnd($blockType['type'], $i);
             }
             if ($tokens[$i]->equals(',')) {
                 $canBeConverted = false;
                 break;
             }
         }
         if (false === $canBeConverted) {
             continue;
         }
         $tokens->overrideAt($index, array(T_PRINT, 'print'));
     }
 }
 /**
  * Remove white line(s) after the index of a block type,
  * but only if the block is not on one line.
  *
  * @param int $index body start
  */
 private function fixStructureOpenCloseIfMultiLine($index)
 {
     $blockTypeInfo = $this->tokens->detectBlockType($this->tokens[$index]);
     $bodyEnd = $this->tokens->findBlockEnd($blockTypeInfo['type'], $index);
     for ($i = $bodyEnd - 1; $i >= $index; --$i) {
         if (false !== strpos($this->tokens[$i]->getContent(), "\n")) {
             $this->removeEmptyLinesAfterLineWithTokenAt($i);
             $this->removeEmptyLinesAfterLineWithTokenAt($index);
             break;
         }
     }
 }
Esempio n. 5
0
 /**
  * @param int    $expectedIndex
  * @param string $source
  * @param int    $type
  * @param int    $searchIndex
  *
  * @dataProvider provideFindBlockEndCases
  */
 public function testFindBlockEnd($expectedIndex, $source, $type, $searchIndex)
 {
     Tokens::clearCache();
     $tokens = Tokens::fromCode($source);
     $this->assertSame($expectedIndex, $tokens->findBlockEnd($type, $searchIndex, true));
     $this->assertSame($searchIndex, $tokens->findBlockEnd($type, $expectedIndex, false));
     $detectedType = Tokens::detectBlockType($tokens[$searchIndex]);
     $this->assertInternalType('array', $detectedType);
     $this->assertArrayHasKey('type', $detectedType);
     $this->assertArrayHasKey('isStart', $detectedType);
     $this->assertSame($type, $detectedType['type']);
     $this->assertTrue($detectedType['isStart']);
     $detectedType = Tokens::detectBlockType($tokens[$expectedIndex]);
     $this->assertInternalType('array', $detectedType);
     $this->assertArrayHasKey('type', $detectedType);
     $this->assertArrayHasKey('isStart', $detectedType);
     $this->assertSame($type, $detectedType['type']);
     $this->assertFalse($detectedType['isStart']);
 }
 /**
  * Returns start and end token indexes of arguments.
  *
  * Return an array which each index being the first token af an
  * argument and the value the last. Including non-function tokens
  * such as comments and white space tokens, but without the separation
  * tokens like '(', ',' and ')'.
  *
  * @param Tokens $tokens
  * @param int    $openParenthesis
  * @param int    $closeParenthesis
  *
  * @return array<int, int>
  */
 protected function getArguments(Tokens $tokens, $openParenthesis, $closeParenthesis)
 {
     $arguments = array();
     $firstSensibleToken = $tokens->getNextMeaningfulToken($openParenthesis);
     if ($tokens[$firstSensibleToken]->equals(')')) {
         return $arguments;
     }
     $paramContentIndex = $openParenthesis + 1;
     $argumentsStart = $paramContentIndex;
     for (; $paramContentIndex < $closeParenthesis; ++$paramContentIndex) {
         $token = $tokens[$paramContentIndex];
         // skip nested (), [], {} constructs
         $blockDefinitionProbe = Tokens::detectBlockType($token);
         if (null !== $blockDefinitionProbe && true === $blockDefinitionProbe['isStart']) {
             $paramContentIndex = $tokens->findBlockEnd($blockDefinitionProbe['type'], $paramContentIndex);
             continue;
         }
         // if comma matched, increase arguments counter
         if ($token->equals(',')) {
             $arguments[$argumentsStart] = $paramContentIndex - 1;
             $argumentsStart = $paramContentIndex + 1;
         }
     }
     $arguments[$argumentsStart] = $paramContentIndex - 1;
     return $arguments;
 }
 /**
  * Inject into the text placeholders of candidates of vertical alignment.
  *
  * @param Tokens $tokens
  * @param int    $startAt
  * @param int    $endAt
  *
  * @return array($code, $context_counter)
  */
 private function injectAlignmentPlaceholders(Tokens $tokens, $startAt, $endAt)
 {
     for ($index = $startAt; $index < $endAt; ++$index) {
         $token = $tokens[$index];
         if ($token->isGivenKind(array(T_FOREACH, T_FOR, T_WHILE, T_IF, T_SWITCH))) {
             $index = $tokens->getNextMeaningfulToken($index);
             $index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $index);
             continue;
         }
         if ($token->isGivenKind(T_ARRAY)) {
             // don't use "$tokens->isArray()" here, short arrays are handled in the next case
             $from = $tokens->getNextMeaningfulToken($index);
             $until = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $from);
             $index = $until;
             $this->injectArrayAlignmentPlaceholders($tokens, $from, $until);
             continue;
         }
         if ($token->isGivenKind(CT_ARRAY_SQUARE_BRACE_OPEN)) {
             $prevToken = $tokens[$tokens->getPrevMeaningfulToken($index)];
             if ($prevToken->isGivenKind(array(T_STRING, T_VARIABLE))) {
                 continue;
             }
             $from = $index;
             $until = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, $from);
             $index = $until;
             $this->injectArrayAlignmentPlaceholders($tokens, $from + 1, $until - 1);
             continue;
         }
         if ($token->isGivenKind(T_DOUBLE_ARROW)) {
             $tokenContent = sprintf(self::ALIGNABLE_PLACEHOLDER, $this->currentLevel) . $token->getContent();
             $nextToken = $tokens[$index + 1];
             if (!$nextToken->isWhitespace()) {
                 $tokenContent .= ' ';
             } elseif ($nextToken->isWhitespace(" \t")) {
                 $nextToken->setContent(' ');
             }
             $token->setContent($tokenContent);
             continue;
         }
         if ($token->equals(';')) {
             ++$this->deepestLevel;
             ++$this->currentLevel;
             continue;
         }
         if ($token->equals(',')) {
             for ($i = $index; $i < $endAt - 1; ++$i) {
                 if (false !== strpos($tokens[$i - 1]->getContent(), "\n")) {
                     break;
                 }
                 if ($tokens[$i + 1]->isGivenKind(array(T_ARRAY, CT_ARRAY_SQUARE_BRACE_OPEN))) {
                     $arrayStartIndex = $tokens[$i + 1]->isGivenKind(T_ARRAY) ? $tokens->getNextMeaningfulToken($i + 1) : $i + 1;
                     $blockType = Tokens::detectBlockType($tokens[$arrayStartIndex]);
                     $arrayEndIndex = $tokens->findBlockEnd($blockType['type'], $arrayStartIndex);
                     if ($tokens->isPartialCodeMultiline($arrayStartIndex, $arrayEndIndex)) {
                         break;
                     }
                 }
                 ++$index;
             }
         }
     }
 }
 /**
  * @param Tokens $tokens
  * @param int    $argumentStartIndex
  * @param int    $argumentEndIndex
  *
  * @return bool
  */
 private function isParenthesisNeeded(Tokens $tokens, $argumentStartIndex, $argumentEndIndex)
 {
     static $allowedKinds = array(T_DNUMBER, T_LNUMBER, T_VARIABLE, T_STRING, T_OBJECT_OPERATOR, T_CONSTANT_ENCAPSED_STRING, T_DOUBLE_CAST, T_INT_CAST, T_INC, T_DEC, T_NS_SEPARATOR, T_WHITESPACE, T_DOUBLE_COLON, T_LINE, T_COMMENT, T_DOC_COMMENT, CT::T_NAMESPACE_OPERATOR);
     for ($i = $argumentStartIndex; $i <= $argumentEndIndex; ++$i) {
         if ($tokens[$i]->isGivenKind($allowedKinds) || $tokens[$i]->isEmpty()) {
             continue;
         }
         if (null !== ($blockType = Tokens::detectBlockType($tokens[$i]))) {
             $i = $tokens->findBlockEnd($blockType['type'], $i);
             continue;
         }
         if ($tokens[$i]->equals('$')) {
             $i = $tokens->getNextMeaningfulToken($i);
             if ($tokens[$i]->isGivenKind(CT::T_DYNAMIC_VAR_BRACE_OPEN)) {
                 $i = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_DYNAMIC_VAR_BRACE, $i);
                 continue;
             }
         }
         if ($tokens[$i]->equals('+') && $tokens->getPrevMeaningfulToken($i) < $argumentStartIndex) {
             continue;
         }
         return true;
     }
     return false;
 }