/**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     $tokensAnalyzer = new TokensAnalyzer($tokens);
     foreach ($tokensAnalyzer->getImportUseIndexes() as $index) {
         $indent = '';
         // if previous line ends with comment and current line starts with whitespace, use current indent
         if ($tokens[$index - 1]->isWhitespace(" \t") && $tokens[$index - 2]->isGivenKind(T_COMMENT)) {
             $indent = $tokens[$index - 1]->getContent();
         } elseif ($tokens[$index - 1]->isWhitespace()) {
             $indent = Utils::calculateTrailingWhitespaceIndent($tokens[$index - 1]);
         }
         $newline = "\n";
         // Handle insert index for inline T_COMMENT with whitespace after semicolon
         $semicolonIndex = $tokens->getNextTokenOfKind($index, array(';', '{'));
         $insertIndex = $semicolonIndex + 1;
         if ($tokens[$insertIndex]->isWhitespace(" \t") && $tokens[$insertIndex + 1]->isComment()) {
             ++$insertIndex;
         }
         // Increment insert index for inline T_COMMENT or T_DOC_COMMENT
         if ($tokens[$insertIndex]->isComment()) {
             ++$insertIndex;
         }
         $afterSemicolon = $tokens->getNextMeaningfulToken($semicolonIndex);
         if (!$tokens[$afterSemicolon]->isGivenKind(T_USE)) {
             $newline .= "\n";
         }
         if ($tokens[$insertIndex]->isWhitespace()) {
             $nextToken = $tokens[$insertIndex];
             $nextToken->setContent($newline . $indent . ltrim($nextToken->getContent()));
         } elseif ($newline && $indent) {
             $tokens->insertAt($insertIndex, new Token(array(T_WHITESPACE, $newline . $indent)));
         }
     }
 }
 /**
  * Constructor. Register built in Transformers.
  */
 private function __construct()
 {
     $this->registerBuiltInTransformers();
     usort($this->items, function (TransformerInterface $a, TransformerInterface $b) {
         return Utils::cmpInt($b->getPriority(), $a->getPriority());
     });
 }
 /**
  * Cleanup a whitespace token.
  *
  * @param Token $token
  */
 private function fixWhitespace(Token $token)
 {
     $content = $token->getContent();
     // if there is more than one new line in the whitespace, then we need to fix it
     if (substr_count($content, "\n") > 1) {
         // the final bit of the whitespace must be the next statement's indentation
         $lines = Utils::splitLines($content);
         $token->setContent("\n" . end($lines));
     }
 }
 /**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     $ending = $this->whitespacesConfig->getLineEnding();
     $tokensAnalyzer = new TokensAnalyzer($tokens);
     foreach ($tokensAnalyzer->getImportUseIndexes() as $index) {
         $indent = '';
         // if previous line ends with comment and current line starts with whitespace, use current indent
         if ($tokens[$index - 1]->isWhitespace(" \t") && $tokens[$index - 2]->isGivenKind(T_COMMENT)) {
             $indent = $tokens[$index - 1]->getContent();
         } elseif ($tokens[$index - 1]->isWhitespace()) {
             $indent = Utils::calculateTrailingWhitespaceIndent($tokens[$index - 1]);
         }
         $semicolonIndex = $tokens->getNextTokenOfKind($index, array(';', array(T_CLOSE_TAG)));
         // Handle insert index for inline T_COMMENT with whitespace after semicolon
         $insertIndex = $semicolonIndex;
         if ($tokens[$semicolonIndex]->isGivenKind(T_CLOSE_TAG)) {
             if ($tokens[$insertIndex - 1]->isWhitespace()) {
                 --$insertIndex;
             }
             $tokens->insertAt($insertIndex, new Token(';'));
         }
         if ($semicolonIndex === count($tokens) - 1) {
             $tokens->insertAt($insertIndex + 1, new Token(array(T_WHITESPACE, $ending . $ending . $indent)));
         } else {
             $newline = $ending;
             $tokens[$semicolonIndex]->isGivenKind(T_CLOSE_TAG) ? --$insertIndex : ++$insertIndex;
             if ($tokens[$insertIndex]->isWhitespace(" \t") && $tokens[$insertIndex + 1]->isComment()) {
                 ++$insertIndex;
             }
             // Increment insert index for inline T_COMMENT or T_DOC_COMMENT
             if ($tokens[$insertIndex]->isComment()) {
                 ++$insertIndex;
             }
             $afterSemicolon = $tokens->getNextMeaningfulToken($semicolonIndex);
             if (null === $afterSemicolon || !$tokens[$afterSemicolon]->isGivenKind(T_USE)) {
                 $newline .= $ending;
             }
             if ($tokens[$insertIndex]->isWhitespace()) {
                 $nextToken = $tokens[$insertIndex];
                 $nextMeaningfulAfterUseIndex = $tokens->getNextMeaningfulToken($insertIndex);
                 if (null !== $nextMeaningfulAfterUseIndex && $tokens[$nextMeaningfulAfterUseIndex]->isGivenKind(T_USE)) {
                     if (substr_count($nextToken->getContent(), "\n") < 2) {
                         $nextToken->setContent($newline . $indent . ltrim($nextToken->getContent()));
                     }
                 } else {
                     $nextToken->setContent($newline . $indent . ltrim($nextToken->getContent()));
                 }
             } else {
                 $tokens->insertAt($insertIndex, new Token(array(T_WHITESPACE, $newline . $indent)));
             }
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 public function fix(\SplFileInfo $file, Tokens $tokens)
 {
     foreach ($tokens as $index => $token) {
         if (!$token->isGivenKind(T_DOC_COMMENT)) {
             continue;
         }
         $nextIndex = $tokens->getNextMeaningfulToken($index);
         // skip if there is no next token or if next token is block end `}`
         if (null === $nextIndex || $tokens[$nextIndex]->equals('}')) {
             continue;
         }
         $prevToken = $tokens[$index - 1];
         // ignore inline docblocks
         if ($prevToken->isGivenKind(T_OPEN_TAG) || $prevToken->isWhitespace(" \t") && !$tokens[$index - 2]->isGivenKind(T_OPEN_TAG) || $prevToken->equalsAny(array(';', '{'))) {
             continue;
         }
         $indent = '';
         if ($tokens[$nextIndex - 1]->isWhitespace()) {
             $indent = Utils::calculateTrailingWhitespaceIndent($tokens[$nextIndex - 1]);
         }
         $prevToken->setContent($this->fixWhitespaceBefore($prevToken->getContent(), $indent));
         $token->setContent($this->fixDocBlock($token->getContent(), $indent));
     }
 }
 /**
  * Create a new docblock instance.
  *
  * @param string $content
  */
 public function __construct($content)
 {
     foreach (Utils::splitLines($content) as $line) {
         $this->lines[] = new Line($line);
     }
 }
 /**
  * Fix a given docblock.
  *
  * @param string $content
  *
  * @return string
  */
 private function fixDocBlock($content)
 {
     $lines = Utils::splitLines($content);
     $l = count($lines);
     for ($i = 0; $i < $l; ++$i) {
         $items = array();
         $matches = $this->getMatches($lines[$i]);
         if (null === $matches) {
             continue;
         }
         $current = $i;
         $items[] = $matches;
         while ($matches = $this->getMatches($lines[++$i], true)) {
             $items[] = $matches;
         }
         // compute the max length of the tag, hint and variables
         $tagMax = 0;
         $hintMax = 0;
         $varMax = 0;
         foreach ($items as $item) {
             if (null === $item['tag']) {
                 continue;
             }
             $tagMax = max($tagMax, strlen($item['tag']));
             $hintMax = max($hintMax, strlen($item['hint']));
             $varMax = max($varMax, strlen($item['var']));
         }
         $currTag = null;
         // update
         foreach ($items as $j => $item) {
             if (null === $item['tag']) {
                 if ($item['desc'][0] === '@') {
                     $lines[$current + $j] = $item['indent'] . ' * ' . $item['desc'] . "\n";
                     continue;
                 }
                 $line = $item['indent'] . ' *  ' . str_repeat(' ', $tagMax + $hintMax + $varMax + ('param' === $currTag ? 3 : 2)) . $item['desc'] . "\n";
                 $lines[$current + $j] = $line;
                 continue;
             }
             $currTag = $item['tag'];
             $line = $item['indent'] . ' * @' . $item['tag'] . str_repeat(' ', $tagMax - strlen($item['tag']) + 1) . $item['hint'];
             if (!empty($item['var'])) {
                 $line .= str_repeat(' ', $hintMax - strlen($item['hint']) + 1) . $item['var'] . (!empty($item['desc']) ? str_repeat(' ', $varMax - strlen($item['var']) + 1) . $item['desc'] . "\n" : "\n");
             } elseif (!empty($item['desc'])) {
                 $line .= str_repeat(' ', $hintMax - strlen($item['hint']) + 1) . $item['desc'] . "\n";
             } else {
                 $line .= "\n";
             }
             $lines[$current + $j] = $line;
         }
     }
     return implode($lines);
 }
Beispiel #8
0
 /**
  * @expectedException \InvalidArgumentException
  * @expectedExceptionMessage The given token must be whitespace, got "T_STRING".
  */
 public function testCalculateTrailingWhitespaceIndentFail()
 {
     $token = new Token(array(T_STRING, 'foo'));
     Utils::calculateTrailingWhitespaceIndent($token);
 }
Beispiel #9
0
 /**
  * Sort fixers by their priorities.
  *
  * @return $this
  */
 private function sortFixers()
 {
     // Schwartzian transform is used to improve the efficiency and avoid
     // `usort(): Array was modified by the user comparison function` warning for mocked objects.
     $data = array_map(function (FixerInterface $fixer) {
         return array($fixer, $fixer->getPriority());
     }, $this->fixers);
     usort($data, function (array $a, array $b) {
         return Utils::cmpInt($b[1], $a[1]);
     });
     $this->fixers = array_map(function (array $item) {
         return $item[0];
     }, $data);
     return $this;
 }
 /**
  * @return string
  */
 protected function getFixerName()
 {
     $reflection = new \ReflectionClass($this);
     $name = preg_replace('/FixerTest$/', '', $reflection->getShortName());
     return Utils::camelCaseToUnderscore($name);
 }
 /**
  * Get the delimiter that would require the least escaping in a regular expression.
  *
  * @param string $pattern the regular expression
  *
  * @return string the preg delimiter
  */
 private function getBestDelimiter($pattern)
 {
     // try do find something that's not used
     $delimiters = array();
     foreach (self::$delimiters as $k => $d) {
         if (false === strpos($pattern, $d)) {
             return $d;
         }
         $delimiters[$d] = array(substr_count($pattern, $d), $k);
     }
     // return the least used delimiter, using the position in the list as a tie breaker
     uasort($delimiters, function ($a, $b) {
         if ($a[0] === $b[0]) {
             return Utils::cmpInt($a, $b);
         }
         return $a[0] < $b[0] ? -1 : 1;
     });
     return key($delimiters);
 }
Beispiel #12
0
 /**
  * @param string[]|null $options JSON encode option
  *
  * @return string
  */
 public function toJson(array $options = null)
 {
     static $defaultOptions = null;
     if (null === $options) {
         if (null === $defaultOptions) {
             $defaultOptions = Utils::calculateBitmask(array('JSON_PRETTY_PRINT', 'JSON_NUMERIC_CHECK'));
         }
         $options = $defaultOptions;
     } else {
         $options = Utils::calculateBitmask($options);
     }
     return json_encode($this->toArray(), $options);
 }
Beispiel #13
0
 /**
  * {@inheritdoc}
  */
 public function getName()
 {
     $nameParts = explode('\\', get_called_class());
     $name = substr(end($nameParts), 0, -strlen('Fixer'));
     return Utils::camelCaseToUnderscore($name);
 }
Beispiel #14
0
 public function toJson()
 {
     static $options = null;
     if (null === $options) {
         $options = Utils::calculateBitmask(array('JSON_PRETTY_PRINT', 'JSON_NUMERIC_CHECK'));
     }
     $output = new \SplFixedArray(count($this));
     foreach ($this as $index => $token) {
         $output[$index] = $token->toArray();
     }
     $this->rewind();
     return json_encode($output, $options);
 }