<?php

/*
 * 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\Casing;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;

/**
 * @author SpacePossum
 */
final class MagicMethodCasingFixer extends AbstractFixer
{
    private static $magicNames = [
        '__call' => '__call',
        '__callstatic' => '__callStatic',
        '__clone' => '__clone',
        '__construct' => '__construct',
        '__debuginfo' => '__debugInfo',
        '__destruct' => '__destruct',
        '__get' => '__get',
        '__invoke' => '__invoke',
        '__isset' => '__isset',
        '__serialize' => '__serialize',
        '__set' => '__set',
        '__set_state' => '__set_state',
        '__sleep' => '__sleep',
        '__tostring' => '__toString',
        '__unserialize' => '__unserialize',
        '__unset' => '__unset',
        '__wakeup' => '__wakeup',
    ];

    /**
     * {@inheritdoc}
     */
    public function getDefinition()
    {
        return new FixerDefinition(
            'Magic method definitions and calls must be using the correct casing.',
            [
                new CodeSample(
                    '<?php
class Foo
{
    public function __Sleep()
    {
    }
}
'
                ),
                new CodeSample(
                    '<?php
$foo->__INVOKE(1);
'
                ),
            ]
        );
    }

    /**
     * {@inheritdoc}
     */
    public function isCandidate(Tokens $tokens)
    {
        return $tokens->isTokenKindFound(T_STRING) && $tokens->isAnyTokenKindsFound([T_FUNCTION, T_OBJECT_OPERATOR, T_DOUBLE_COLON]);
    }

    /**
     * {@inheritdoc}
     */
    protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        $inClass = 0;
        $tokenCount = \count($tokens);

        for ($index = 1; $index < $tokenCount - 2; ++$index) {
            if (0 === $inClass && $tokens[$index]->isClassy()) {
                $inClass = 1;
                $index = $tokens->getNextTokenOfKind($index, ['{']);

                continue;
            }

            if (0 !== $inClass) {
                if ($tokens[$index]->equals('{')) {
                    ++$inClass;

                    continue;
                }

                if ($tokens[$index]->equals('}')) {
                    --$inClass;

                    continue;
                }
            }

            if (!$tokens[$index]->isGivenKind(T_STRING)) {
                continue; // wrong type
            }

            $content = $tokens[$index]->getContent();
            if ('__' !== substr($content, 0, 2)) {
                continue; // cheap look ahead
            }

            $name = strtolower($content);

            if (!$this->isMagicMethodName($name)) {
                continue; // method name is not one of the magic ones we can fix
            }

            $nameInCorrectCasing = $this->getMagicMethodNameInCorrectCasing($name);
            if ($nameInCorrectCasing === $content) {
                continue; // method name is already in the correct casing, no fix needed
            }

            if ($this->isFunctionSignature($tokens, $index)) {
                if (0 !== $inClass) {
                    // this is a method definition we want to fix
                    $this->setTokenToCorrectCasing($tokens, $index, $nameInCorrectCasing);
                }

                continue;
            }

            if ($this->isMethodCall($tokens, $index)) {
                $this->setTokenToCorrectCasing($tokens, $index, $nameInCorrectCasing);

                continue;
            }

            if (
                ('__callstatic' === $name || '__set_state' === $name)
                && $this->isStaticMethodCall($tokens, $index)
            ) {
                $this->setTokenToCorrectCasing($tokens, $index, $nameInCorrectCasing);
            }
        }
    }

    /**
     * @param Tokens $tokens
     * @param int    $index
     *
     * @return bool
     */
    private function isFunctionSignature(Tokens $tokens, $index)
    {
        $prevIndex = $tokens->getPrevMeaningfulToken($index);
        if (!$tokens[$prevIndex]->isGivenKind(T_FUNCTION)) {
            return false; // not a method signature
        }

        return $tokens[$tokens->getNextMeaningfulToken($index)]->equals('(');
    }

    /**
     * @param Tokens $tokens
     * @param int    $index
     *
     * @return bool
     */
    private function isMethodCall(Tokens $tokens, $index)
    {
        $prevIndex = $tokens->getPrevMeaningfulToken($index);
        if (!$tokens[$prevIndex]->equals([T_OBJECT_OPERATOR, '->'])) {
            return false; // not a "simple" method call
        }

        return $tokens[$tokens->getNextMeaningfulToken($index)]->equals('(');
    }

    /**
     * @param Tokens $tokens
     * @param int    $index
     *
     * @return bool
     */
    private function isStaticMethodCall(Tokens $tokens, $index)
    {
        $prevIndex = $tokens->getPrevMeaningfulToken($index);
        if (!$tokens[$prevIndex]->isGivenKind(T_DOUBLE_COLON)) {
            return false; // not a "simple" static method call
        }

        return $tokens[$tokens->getNextMeaningfulToken($index)]->equals('(');
    }

    /**
     * @param string $name
     *
     * @return bool
     */
    private function isMagicMethodName($name)
    {
        return isset(self::$magicNames[$name]);
    }

    /**
     * @param string $name name of a magic method
     *
     * @return string
     */
    private function getMagicMethodNameInCorrectCasing($name)
    {
        return self::$magicNames[$name];
    }

    /**
     * @param Tokens $tokens
     * @param int    $index
     * @param string $nameInCorrectCasing
     */
    private function setTokenToCorrectCasing(Tokens $tokens, $index, $nameInCorrectCasing)
    {
        $tokens[$index] = new Token([T_STRING, $nameInCorrectCasing]);
    }
}


<?php

/*
 * 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\ControlStructure;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\Fixer\ConfigurationDefinitionFixerInterface;
use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface;
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver;
use PhpCsFixer\FixerConfiguration\FixerOptionBuilder;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Preg;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
use Symfony\Component\OptionsResolver\Options;

/**
 * Fixer for rule defined in PSR2 ¶5.2.
 */
final class NoBreakCommentFixer extends AbstractFixer implements ConfigurationDefinitionFixerInterface, WhitespacesAwareFixerInterface
{
    /**
     * {@inheritdoc}
     */
    public function getDefinition()
    {
        return new FixerDefinition(
            'There must be a comment when fall-through is intentional in a non-empty case body.',
            [
                new CodeSample(
                    '<?php
switch ($foo) {
    case 1:
        foo();
    case 2:
        bar();
        // no break
        break;
    case 3:
        baz();
}
'
                ),
            ],
            'Adds a "no break" comment before fall-through cases, and removes it if there is no fall-through.'
        );
    }

    /**
     * {@inheritdoc}
     */
    public function isCandidate(Tokens $tokens)
    {
        return $tokens->isAnyTokenKindsFound([T_CASE, T_DEFAULT]);
    }

    /**
     * {@inheritdoc}
     */
    protected function createConfigurationDefinition()
    {
        return new FixerConfigurationResolver([
            (new FixerOptionBuilder('comment_text', 'The text to use in the added comment and to detect it.'))
                ->setAllowedTypes(['string'])
                ->setAllowedValues([
                    function ($value) {
                        if (\is_string($value) && Preg::match('/\R/', $value)) {
                            throw new InvalidOptionsException('The comment text must not contain new lines.');
                        }

                        return true;
                    },
                ])
                ->setNormalizer(function (Options $options, $value) {
                    return rtrim($value);
                })
                ->setDefault('no break')
                ->getOption(),
        ]);
    }

    /**
     * {@inheritdoc}
     */
    protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        for ($position = \count($tokens) - 1; $position >= 0; --$position) {
            if ($tokens[$position]->isGivenKind([T_CASE, T_DEFAULT])) {
                $this->fixCase($tokens, $position);
            }
        }
    }

    /**
     * @param Tokens $tokens
     * @param int    $casePosition
     */
    private function fixCase(Tokens $tokens, $casePosition)
    {
        $empty = true;
        $fallThrough = true;
        $commentPosition = null;
        for ($i = $tokens->getNextTokenOfKind($casePosition, [':', ';']) + 1, $max = \count($tokens); $i < $max; ++$i) {
            if ($tokens[$i]->isGivenKind([T_SWITCH, T_IF, T_ELSE, T_ELSEIF, T_FOR, T_FOREACH, T_WHILE, T_DO, T_FUNCTION, T_CLASS])) {
                $empty = false;
                $i = $this->getStructureEnd($tokens, $i);

                continue;
            }

            if ($tokens[$i]->isGivenKind([T_BREAK, T_CONTINUE, T_RETURN, T_EXIT, T_THROW, T_GOTO])) {
                $fallThrough = false;

                continue;
            }

            if ($tokens[$i]->equals('}') || $tokens[$i]->isGivenKind(T_ENDSWITCH)) {
                if (null !== $commentPosition) {
                    $this->removeComment($tokens, $commentPosition);
                }

                break;
            }

            if ($this->isNoBreakComment($tokens[$i])) {
                $commentPosition = $i;

                continue;
            }

            if ($tokens[$i]->isGivenKind([T_CASE, T_DEFAULT])) {
                if (!$empty && $fallThrough) {
                    if (null !== $commentPosition && $tokens->getPrevNonWhitespace($i) !== $commentPosition) {
                        $this->removeComment($tokens, $commentPosition);
                        $commentPosition = null;
                    }

                    if (null === $commentPosition) {
                        $this->insertCommentAt($tokens, $i);
                    } else {
                        $text = $this->configuration['comment_text'];

                        $tokens[$commentPosition] = new Token([
                            $tokens[$commentPosition]->getId(),
                            str_ireplace($text, $text, $tokens[$commentPosition]->getContent()),
                        ]);

                        $this->ensureNewLineAt($tokens, $commentPosition);
                    }
                } elseif (null !== $commentPosition) {
                    $this->removeComment($tokens, $commentPosition);
                }

                break;
            }

            if (!$tokens[$i]->isGivenKind([T_COMMENT, T_WHITESPACE])) {
                $empty = false;
            }
        }
    }

    /**
     * @param Token $token
     *
     * @return bool
     */
    private function isNoBreakComment(Token $token)
    {
        if (!$token->isComment()) {
            return false;
        }

        $text = preg_quote($this->configuration['comment_text'], '~');

        return 1 === Preg::match("~^((//|#)\\s*{$text}\\s*)|(/\\*\\*?\\s*{$text}\\s*\\*/)$~i", $token->getContent());
    }

    /**
     * @param Tokens $tokens
     * @param int    $casePosition
     */
    private function insertCommentAt(Tokens $tokens, $casePosition)
    {
        $lineEnding = $this->whitespacesConfig->getLineEnding();

        $newlinePosition = $this->ensureNewLineAt($tokens, $casePosition);

        $newlineToken = $tokens[$newlinePosition];

        $nbNewlines = substr_count($newlineToken->getContent(), $lineEnding);
        if ($newlineToken->isGivenKind(T_OPEN_TAG) && Preg::match('/\R/', $newlineToken->getContent())) {
            ++$nbNewlines;
        } elseif ($tokens[$newlinePosition - 1]->isGivenKind(T_OPEN_TAG) && Preg::match('/\R/', $tokens[$newlinePosition - 1]->getContent())) {
            ++$nbNewlines;

            if (!Preg::match('/\R/', $newlineToken->getContent())) {
                $tokens[$newlinePosition] = new Token([$newlineToken->getId(), $lineEnding.$newlineToken->getContent()]);
            }
        }

        if ($nbNewlines > 1) {
            Preg::match('/^(.*?)(\R[ \t]*)$/s', $newlineToken->getContent(), $matches);

            $indent = $this->getIndentAt($tokens, $newlinePosition - 1);
            $tokens[$newlinePosition] = new Token([$newlineToken->getId(), $matches[1].$lineEnding.$indent]);
            $tokens->insertAt(++$newlinePosition, new Token([T_WHITESPACE, $matches[2]]));
        }

        $tokens->insertAt($newlinePosition, new Token([T_COMMENT, '// '.$this->configuration['comment_text']]));

        $this->ensureNewLineAt($tokens, $newlinePosition);
    }

    /**
     * @param Tokens $tokens
     * @param int    $position
     *
     * @return int The newline token position
     */
    private function ensureNewLineAt(Tokens $tokens, $position)
    {
        $lineEnding = $this->whitespacesConfig->getLineEnding();
        $content = $lineEnding.$this->getIndentAt($tokens, $position);

        $whitespaceToken = $tokens[$position - 1];
        if (!$whitespaceToken->isGivenKind(T_WHITESPACE)) {
            if ($whitespaceToken->isGivenKind(T_OPEN_TAG)) {
                $content = Preg::replace('/\R/', '', $content);
                if (!Preg::match('/\R/', $whitespaceToken->getContent())) {
                    $tokens[$position - 1] = new Token([T_OPEN_TAG, Preg::replace('/\s+$/', $lineEnding, $whitespaceToken->getContent())]);
                }
            }

            if ('' !== $content) {
                $tokens->insertAt($position, new Token([T_WHITESPACE, $content]));

                return $position;
            }

            return $position - 1;
        }

        if ($tokens[$position - 2]->isGivenKind(T_OPEN_TAG) && Preg::match('/\R/', $tokens[$position - 2]->getContent())) {
            $content = Preg::replace('/^\R/', '', $content);
        }

        if (!Preg::match('/\R/', $whitespaceToken->getContent())) {
            $tokens[$position - 1] = new Token([T_WHITESPACE, $content]);
        }

        return $position - 1;
    }

    /**
     * @param Tokens $tokens
     * @param int    $commentPosition
     */
    private function removeComment(Tokens $tokens, $commentPosition)
    {
        if ($tokens[$tokens->getPrevNonWhitespace($commentPosition)]->isGivenKind(T_OPEN_TAG)) {
            $whitespacePosition = $commentPosition + 1;
            $regex = '/^\R[ \t]*/';
        } else {
            $whitespacePosition = $commentPosition - 1;
            $regex = '/\R[ \t]*$/';
        }

        $whitespaceToken = $tokens[$whitespacePosition];
        if ($whitespaceToken->isGivenKind(T_WHITESPACE)) {
            $content = Preg::replace($regex, '', $whitespaceToken->getContent());
            if ('' !== $content) {
                $tokens[$whitespacePosition] = new Token([T_WHITESPACE, $content]);
            } else {
                $tokens->clearAt($whitespacePosition);
            }
        }

        $tokens->clearTokenAndMergeSurroundingWhitespace($commentPosition);
    }

    /**
     * @param Tokens $tokens
     * @param int    $position
     *
     * @return string
     */
    private function getIndentAt(Tokens $tokens, $position)
    {
        while (true) {
            $position = $tokens->getPrevTokenOfKind($position, [[T_WHITESPACE]]);

            if (null === $position) {
                break;
            }

            $content = $tokens[$position]->getContent();

            $prevToken = $tokens[$position - 1];
            if ($prevToken->isGivenKind(T_OPEN_TAG) && Preg::match('/\R$/', $prevToken->getContent())) {
                $content = $this->whitespacesConfig->getLineEnding().$content;
            }

            if (Preg::match('/\R([ \t]*)$/', $content, $matches)) {
                return $matches[1];
            }
        }

        return '';
    }

    /**
     * @param Tokens $tokens
     * @param int    $position
     *
     * @return int
     */
    private function getStructureEnd(Tokens $tokens, $position)
    {
        $initialToken = $tokens[$position];

        if ($initialToken->isGivenKind([T_FOR, T_FOREACH, T_WHILE, T_IF, T_ELSEIF, T_SWITCH, T_FUNCTION])) {
            $position = $tokens->findBlockEnd(
                Tokens::BLOCK_TYPE_PARENTHESIS_BRACE,
                $tokens->getNextTokenOfKind($position, ['('])
            );
        } elseif ($initialToken->isGivenKind(T_CLASS)) {
            $openParenthesisPosition = $tokens->getNextMeaningfulToken($position);
            if ('(' === $tokens[$openParenthesisPosition]->getContent()) {
                $position = $tokens->findBlockEnd(
                    Tokens::BLOCK_TYPE_PARENTHESIS_BRACE,
                    $openParenthesisPosition
                );
            }
        }

        $position = $tokens->getNextMeaningfulToken($position);
        if ('{' !== $tokens[$position]->getContent()) {
            return $tokens->getNextTokenOfKind($position, [';']);
        }

        $position = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $position);

        if ($initialToken->isGivenKind(T_DO)) {
            $position = $tokens->findBlockEnd(
                Tokens::BLOCK_TYPE_PARENTHESIS_BRACE,
                $tokens->getNextTokenOfKind($position, ['('])
            );

            return $tokens->getNextTokenOfKind($position, [';']);
        }

        return $position;
    }
}


<?php

/*
 * 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;

/**
 * This class replaces preg_* functions to better handling UTF8 strings,
 * ensuring no matter "u" modifier is present or absent subject will be handled correctly.
 *
 * @author Kuba Werłos <werlos@gmail.com>
 *
 * @internal
 */
final class Preg
{
    /**
     * @param string        $pattern
     * @param string        $subject
     * @param null|string[] $matches
     * @param int           $flags
     * @param int           $offset
     *
     * @throws PregException
     *
     * @return int
     */
    public static function match($pattern, $subject, &$matches = null, $flags = 0, $offset = 0)
    {
        $result = @preg_match(self::addUtf8Modifier($pattern), $subject, $matches, $flags, $offset);
        if (false !== $result && PREG_NO_ERROR === preg_last_error()) {
            return $result;
        }

        $result = @preg_match(self::removeUtf8Modifier($pattern), $subject, $matches, $flags, $offset);
        if (false !== $result && PREG_NO_ERROR === preg_last_error()) {
            return $result;
        }

        throw new PregException('Error occurred when calling preg_match.', preg_last_error());
    }

    /**
     * @param string        $pattern
     * @param string        $subject
     * @param null|string[] $matches
     * @param int           $flags
     * @param int           $offset
     *
     * @throws PregException
     *
     * @return int
     */
    public static function matchAll($pattern, $subject, &$matches = null, $flags = PREG_PATTERN_ORDER, $offset = 0)
    {
        $result = @preg_match_all(self::addUtf8Modifier($pattern), $subject, $matches, $flags, $offset);
        if (false !== $result && PREG_NO_ERROR === preg_last_error()) {
            return $result;
        }

        $result = @preg_match_all(self::removeUtf8Modifier($pattern), $subject, $matches, $flags, $offset);
        if (false !== $result && PREG_NO_ERROR === preg_last_error()) {
            return $result;
        }

        throw new PregException('Error occurred when calling preg_match_all.', preg_last_error());
    }

    /**
     * @param string|string[] $pattern
     * @param string|string[] $replacement
     * @param string|string[] $subject
     * @param int             $limit
     * @param null|int        $count
     *
     * @throws PregException
     *
     * @return string|string[]
     */
    public static function replace($pattern, $replacement, $subject, $limit = -1, &$count = null)
    {
        $result = @preg_replace(self::addUtf8Modifier($pattern), $replacement, $subject, $limit, $count);
        if (null !== $result && PREG_NO_ERROR === preg_last_error()) {
            return $result;
        }

        $result = @preg_replace(self::removeUtf8Modifier($pattern), $replacement, $subject, $limit, $count);
        if (null !== $result && PREG_NO_ERROR === preg_last_error()) {
            return $result;
        }

        throw new PregException('Error occurred when calling preg_replace.', preg_last_error());
    }

    /**
     * @param string|string[] $pattern
     * @param callable        $callback
     * @param string|string[] $subject
     * @param int             $limit
     * @param null|int        $count
     *
     * @throws PregException
     *
     * @return string|string[]
     */
    public static function replaceCallback($pattern, $callback, $subject, $limit = -1, &$count = null)
    {
        $result = @preg_replace_callback(self::addUtf8Modifier($pattern), $callback, $subject, $limit, $count);
        if (null !== $result && PREG_NO_ERROR === preg_last_error()) {
            return $result;
        }

        $result = @preg_replace_callback(self::removeUtf8Modifier($pattern), $callback, $subject, $limit, $count);
        if (null !== $result && PREG_NO_ERROR === preg_last_error()) {
            return $result;
        }

        throw new PregException('Error occurred when calling preg_replace_callback.', preg_last_error());
    }

    /**
     * @param string $pattern
     * @param string $subject
     * @param int    $limit
     * @param int    $flags
     *
     * @throws PregException
     *
     * @return string[]
     */
    public static function split($pattern, $subject, $limit = -1, $flags = 0)
    {
        $result = @preg_split(self::addUtf8Modifier($pattern), $subject, $limit, $flags);
        if (false !== $result && PREG_NO_ERROR === preg_last_error()) {
            return $result;
        }

        $result = @preg_split(self::removeUtf8Modifier($pattern), $subject, $limit, $flags);
        if (false !== $result && PREG_NO_ERROR === preg_last_error()) {
            return $result;
        }

        throw new PregException('Error occurred when calling preg_split.', preg_last_error());
    }

    /**
     * @param string|string[] $pattern
     *
     * @return string|string[]
     */
    private static function addUtf8Modifier($pattern)
    {
        if (\is_array($pattern)) {
            return array_map(__METHOD__, $pattern);
        }

        return $pattern.'u';
    }

    /**
     * @param string|string[] $pattern
     *
     * @return string|string[]
     */
    private static function removeUtf8Modifier($pattern)
    {
        if (\is_array($pattern)) {
            return array_map(__METHOD__, $pattern);
        }

        if ('' === $pattern) {
            return '';
        }

        $delimiter = substr($pattern, 0, 1);

        $endDelimiterPosition = strrpos($pattern, $delimiter);

        return substr($pattern, 0, $endDelimiterPosition).str_replace('u', '', substr($pattern, $endDelimiterPosition));
    }
}


<?php

/*
 * 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\Phpdoc;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Tokenizer\Analyzer\CommentsAnalyzer;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;

/**
 * @author Ceeram <ceeram@cakephp.org>
 * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
 */
final class PhpdocToCommentFixer extends AbstractFixer
{
    /**
     * {@inheritdoc}
     */
    public function isCandidate(Tokens $tokens)
    {
        return $tokens->isTokenKindFound(T_DOC_COMMENT);
    }

    /**
     * {@inheritdoc}
     */
    public function getPriority()
    {
        /*
         * Should be run before all other docblock fixers so that these fixers
         * don't touch doc comments which are meant to be converted to regular
         * comments.
         */
        return 25;
    }

    /**
     * {@inheritdoc}
     */
    public function getDefinition()
    {
        return new FixerDefinition(
            'Docblocks should only be used on structural elements.',
            [
                new CodeSample(
                    '<?php
$first = true;// needed because by default first docblock is never fixed.

/** This should not be a docblock */
foreach($connections as $key => $sqlite) {
    $sqlite->open($path);
}
'
                ),
            ]
        );
    }

    /**
     * {@inheritdoc}
     */
    protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        $commentsAnalyzer = new CommentsAnalyzer();

        foreach ($tokens as $index => $token) {
            if (!$token->isGivenKind(T_DOC_COMMENT)) {
                continue;
            }

            if ($commentsAnalyzer->isHeaderComment($tokens, $index)) {
                continue;
            }

            if ($commentsAnalyzer->isBeforeStructuralElement($tokens, $index)) {
                continue;
            }

            $tokens[$index] = new Token([T_COMMENT, '/*'.ltrim($token->getContent(), '/*')]);
        }
    }
}


<?php

/*
 * 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;

/**
 * File reader that unify access to regular file and stdin-alike file.
 *
 * Regular file could be read multiple times with `file_get_contents`, but file provided on stdin can not.
 * Consecutive try will provide empty content for stdin-alike file.
 * This reader unifies access to them.
 *
 * @internal
 */
final class FileReader
{
    /**
     * @var null|self
     */
    private static $instance;

    /**
     * @var null|string
     */
    private $stdinContent;

    /**
     * @return self
     */
    public static function createSingleton()
    {
        if (null === self::$instance) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    /**
     * @param string $filePath
     *
     * @return string
     */
    public function read($filePath)
    {
        if ('php://stdin' === $filePath) {
            if (null === $this->stdinContent) {
                $this->stdinContent = $this->readRaw($filePath);
            }

            return $this->stdinContent;
        }

        return $this->readRaw($filePath);
    }

    /**
     * @param string $realPath
     *
     * @return string
     */
    private function readRaw($realPath)
    {
        $content = @file_get_contents($realPath);

        if (false === $content) {
            $error = error_get_last();

            throw new \RuntimeException(sprintf(
                'Failed to read content from "%s".%s',
                $realPath,
                $error ? ' '.$error['message'] : ''
            ));
        }

        return $content;
    }
}


<?php

/*
 * 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\Operator;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Tokenizer\CT;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;

/**
 * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
 */
final class NewWithBracesFixer extends AbstractFixer
{
    /**
     * {@inheritdoc}
     */
    public function getDefinition()
    {
        return new FixerDefinition(
            'All instances created with new keyword must be followed by braces.',
            [new CodeSample("<?php \$x = new X;\n")]
        );
    }

    /**
     * {@inheritdoc}
     */
    public function isCandidate(Tokens $tokens)
    {
        return $tokens->isTokenKindFound(T_NEW);
    }

    /**
     * {@inheritdoc}
     */
    protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        static $nextTokenKinds = null;

        if (null === $nextTokenKinds) {
            $nextTokenKinds = [
                '?',
                ';',
                ',',
                '(',
                ')',
                '[',
                ']',
                ':',
                '<',
                '>',
                '+',
                '-',
                '*',
                '/',
                '%',
                '&',
                '^',
                '|',
                [T_CLASS],
                [T_IS_SMALLER_OR_EQUAL],
                [T_IS_GREATER_OR_EQUAL],
                [T_IS_EQUAL],
                [T_IS_NOT_EQUAL],
                [T_IS_IDENTICAL],
                [T_IS_NOT_IDENTICAL],
                [T_CLOSE_TAG],
                [T_LOGICAL_AND],
                [T_LOGICAL_OR],
                [T_LOGICAL_XOR],
                [T_BOOLEAN_AND],
                [T_BOOLEAN_OR],
                [T_SL],
                [T_SR],
                [T_INSTANCEOF],
                [T_AS],
                [T_DOUBLE_ARROW],
                [T_POW],
                [CT::T_ARRAY_SQUARE_BRACE_OPEN],
                [CT::T_ARRAY_SQUARE_BRACE_CLOSE],
                [CT::T_BRACE_CLASS_INSTANTIATION_OPEN],
                [CT::T_BRACE_CLASS_INSTANTIATION_CLOSE],
            ];

            if (\defined('T_SPACESHIP')) {
                $nextTokenKinds[] = [T_SPACESHIP];
            }
        }

        for ($index = $tokens->count() - 3; $index > 0; --$index) {
            $token = $tokens[$index];

            if (!$token->isGivenKind(T_NEW)) {
                continue;
            }

            $nextIndex = $tokens->getNextTokenOfKind($index, $nextTokenKinds);
            $nextToken = $tokens[$nextIndex];

            // new anonymous class definition
            if ($nextToken->isGivenKind(T_CLASS)) {
                if (!$tokens[$tokens->getNextMeaningfulToken($nextIndex)]->equals('(')) {
                    $this->insertBracesAfter($tokens, $nextIndex);
                }

                continue;
            }

            // entrance into array index syntax - need to look for exit
            while ($nextToken->equals('[')) {
                $nextIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_INDEX_SQUARE_BRACE, $nextIndex) + 1;
                $nextToken = $tokens[$nextIndex];
            }

            // new statement has a gap in it - advance to the next token
            if ($nextToken->isWhitespace()) {
                $nextIndex = $tokens->getNextNonWhitespace($nextIndex);
                $nextToken = $tokens[$nextIndex];
            }

            // new statement with () - nothing to do
            if ($nextToken->equals('(')) {
                continue;
            }

            $this->insertBracesAfter($tokens, $tokens->getPrevMeaningfulToken($nextIndex));
        }
    }

    /**
     * @param Tokens $tokens
     * @param int    $index
     */
    private function insertBracesAfter(Tokens $tokens, $index)
    {
        $tokens->insertAt(++$index, [new Token('('), new Token(')')]);
    }
}


<?php

/*
 * 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\Phpdoc;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Preg;
use PhpCsFixer\Tokenizer\CT;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;

/**
 * Remove inheritdoc tags from classy that does not inherit.
 *
 * @author SpacePossum
 */
final class PhpdocNoUselessInheritdocFixer extends AbstractFixer
{
    /**
     * {@inheritdoc}
     */
    public function getDefinition()
    {
        return new FixerDefinition(
            'Classy that does not inherit must not have `@inheritdoc` tags.',
            [
                new CodeSample("<?php\n/** {@inheritdoc} */\nclass Sample\n{\n}\n"),
                new CodeSample("<?php\nclass Sample\n{\n    /**\n     * @inheritdoc\n     */\n    public function Test()\n    {\n    }\n}\n"),
            ]
        );
    }

    /**
     * {@inheritdoc}
     */
    public function getPriority()
    {
        // Should run before NoEmptyPhpdocFixer, NoTrailingWhitespaceInCommentFixer
        // and after PhpdocToCommentFixer.
        return 6;
    }

    /**
     * {@inheritdoc}
     */
    public function isCandidate(Tokens $tokens)
    {
        return $tokens->isTokenKindFound(T_DOC_COMMENT) && $tokens->isAnyTokenKindsFound([T_CLASS, T_INTERFACE]);
    }

    /**
     * {@inheritdoc}
     */
    protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        // min. offset 4 as minimal candidate is @: <?php\n/** @inheritdoc */class min{}
        for ($index = 1, $count = \count($tokens) - 4; $index < $count; ++$index) {
            if ($tokens[$index]->isGivenKind([T_CLASS, T_INTERFACE])) {
                $index = $this->fixClassy($tokens, $index);
            }
        }
    }

    /**
     * @param Tokens $tokens
     * @param int    $index
     *
     * @return int
     */
    private function fixClassy(Tokens $tokens, $index)
    {
        // figure out where the classy starts
        $classOpenIndex = $tokens->getNextTokenOfKind($index, ['{']);

        // figure out where the classy ends
        $classEndIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $classOpenIndex);

        // is classy extending or implementing some interface
        $extendingOrImplementing = $this->isExtendingOrImplementing($tokens, $index, $classOpenIndex);

        if (!$extendingOrImplementing) {
            // PHPDoc of classy should not have inherit tag even when using traits as Traits cannot provide this information
            $this->fixClassyOutside($tokens, $index);
        }

        // figure out if the classy uses a trait
        if (!$extendingOrImplementing && $this->isUsingTrait($tokens, $index, $classOpenIndex, $classEndIndex)) {
            $extendingOrImplementing = true;
        }

        $this->fixClassyInside($tokens, $classOpenIndex, $classEndIndex, !$extendingOrImplementing);

        return $classEndIndex;
    }

    /**
     * @param Tokens $tokens
     * @param int    $classOpenIndex
     * @param int    $classEndIndex
     * @param bool   $fixThisLevel
     */
    private function fixClassyInside(Tokens $tokens, $classOpenIndex, $classEndIndex, $fixThisLevel)
    {
        for ($i = $classOpenIndex; $i < $classEndIndex; ++$i) {
            if ($tokens[$i]->isGivenKind(T_CLASS)) {
                $i = $this->fixClassy($tokens, $i);
            } elseif ($fixThisLevel && $tokens[$i]->isGivenKind(T_DOC_COMMENT)) {
                $this->fixToken($tokens, $i);
            }
        }
    }

    /**
     * @param Tokens $tokens
     * @param int    $classIndex
     */
    private function fixClassyOutside(Tokens $tokens, $classIndex)
    {
        $previousIndex = $tokens->getPrevNonWhitespace($classIndex);
        if ($tokens[$previousIndex]->isGivenKind(T_DOC_COMMENT)) {
            $this->fixToken($tokens, $previousIndex);
        }
    }

    /**
     * @param Tokens $tokens
     * @param int    $tokenIndex
     */
    private function fixToken(Tokens $tokens, $tokenIndex)
    {
        $count = 0;
        $content = Preg::replaceCallback(
            '#(\h*(?:@{*|{*\h*@)\h*inheritdoc\h*)([^}]*)((?:}*)\h*)#i',
            static function ($matches) {
                return ' '.$matches[2];
            },
            $tokens[$tokenIndex]->getContent(),
            -1,
            $count
        );

        if ($count) {
            $tokens[$tokenIndex] = new Token([T_DOC_COMMENT, $content]);
        }
    }

    /**
     * @param Tokens $tokens
     * @param int    $classIndex
     * @param int    $classOpenIndex
     *
     * @return bool
     */
    private function isExtendingOrImplementing(Tokens $tokens, $classIndex, $classOpenIndex)
    {
        for ($index = $classIndex; $index < $classOpenIndex; ++$index) {
            if ($tokens[$index]->isGivenKind([T_EXTENDS, T_IMPLEMENTS])) {
                return true;
            }
        }

        return false;
    }

    /**
     * @param Tokens $tokens
     * @param int    $classIndex
     * @param int    $classOpenIndex
     * @param int    $classCloseIndex
     *
     * @return bool
     */
    private function isUsingTrait(Tokens $tokens, $classIndex, $classOpenIndex, $classCloseIndex)
    {
        if ($tokens[$classIndex]->isGivenKind(T_INTERFACE)) {
            // cannot use Trait inside an interface
            return false;
        }

        $useIndex = $tokens->getNextTokenOfKind($classOpenIndex, [[CT::T_USE_TRAIT]]);

        return null !== $useIndex && $useIndex < $classCloseIndex;
    }
}


<?php

/*
 * 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\PhpUnit;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Indicator\PhpUnitTestCaseIndicator;
use PhpCsFixer\Preg;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;

/**
 * @author Roland Franssen <franssen.roland@gmail.com>
 */
final class PhpUnitFqcnAnnotationFixer extends AbstractFixer
{
    /**
     * {@inheritdoc}
     */
    public function getDefinition()
    {
        return new FixerDefinition(
            'PHPUnit annotations should be a FQCNs including a root namespace.',
            [new CodeSample(
                '<?php
final class MyTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @expectedException InvalidArgumentException
     * @covers Project\NameSpace\Something
     * @coversDefaultClass Project\Default
     * @uses Project\Test\Util
     */
    public function testSomeTest()
    {
    }
}
'
            )]
        );
    }

    /**
     * {@inheritdoc}
     */
    public function getPriority()
    {
        // should be run before NoUnusedImportsFixer
        return -9;
    }

    /**
     * {@inheritdoc}
     */
    public function isCandidate(Tokens $tokens)
    {
        return $tokens->isAllTokenKindsFound([T_CLASS, T_DOC_COMMENT]);
    }

    /**
     * {@inheritdoc}
     */
    protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        $phpUnitTestCaseIndicator = new PhpUnitTestCaseIndicator();
        foreach ($phpUnitTestCaseIndicator->findPhpUnitClasses($tokens) as $indexes) {
            $startIndex = $indexes[0];
            $prevDocCommentIndex = $tokens->getPrevTokenOfKind($startIndex, [[T_DOC_COMMENT]]);
            if (null !== $prevDocCommentIndex) {
                $startIndex = $prevDocCommentIndex;
            }
            $this->fixPhpUnitClass($tokens, $startIndex, $indexes[1]);
        }
    }

    /**
     * @param Tokens $tokens
     * @param int    $startIndex
     * @param int    $endIndex
     */
    private function fixPhpUnitClass(Tokens $tokens, $startIndex, $endIndex)
    {
        for ($index = $startIndex; $index < $endIndex; ++$index) {
            if ($tokens[$index]->isGivenKind(T_DOC_COMMENT)) {
                $tokens[$index] = new Token([T_DOC_COMMENT, Preg::replace(
                    '~^(\s*\*\s*@(?:expectedException|covers|coversDefaultClass|uses)\h+)(?!(?:self|static)::)(\w.*)$~m',
                    '$1\\\\$2',
                    $tokens[$index]->getContent()
                )]);
            }
        }
    }
}


<?php

/*
 * 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\Alias;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\Fixer\ConfigurationDefinitionFixerInterface;
use PhpCsFixer\FixerConfiguration\AllowedValueSubset;
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver;
use PhpCsFixer\FixerConfiguration\FixerOptionBuilder;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Tokenizer\Analyzer\FunctionsAnalyzer;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;

/**
 * @author Vladimir Reznichenko <kalessil@gmail.com>
 * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
 */
final class NoAliasFunctionsFixer extends AbstractFixer implements ConfigurationDefinitionFixerInterface
{
    /** @var array<string, string> stores alias (key) - master (value) functions mapping */
    private $aliases = [];

    /** @var array<string, string> stores alias (key) - master (value) functions mapping */
    private static $internalSet = [
        'chop' => 'rtrim',
        'close' => 'closedir',
        'doubleval' => 'floatval',
        'fputs' => 'fwrite',
        'get_required_files' => 'get_included_files',
        'ini_alter' => 'ini_set',
        'is_double' => 'is_float',
        'is_integer' => 'is_int',
        'is_long' => 'is_int',
        'is_real' => 'is_float',
        'is_writeable' => 'is_writable',
        'join' => 'implode',
        'key_exists' => 'array_key_exists',
        'magic_quotes_runtime' => 'set_magic_quotes_runtime',
        'pos' => 'current',
        'show_source' => 'highlight_file',
        'sizeof' => 'count',
        'strchr' => 'strstr',
        'user_error' => 'trigger_error',
    ];

    /** @var array<string, string> stores alias (key) - master (value) functions mapping */
    private static $imapSet = [
        'imap_create' => 'imap_createmailbox',
        'imap_fetchtext' => 'imap_body',
        'imap_header' => 'imap_headerinfo',
        'imap_listmailbox' => 'imap_list',
        'imap_listsubscribed' => 'imap_lsub',
        'imap_rename' => 'imap_renamemailbox',
        'imap_scan' => 'imap_listscan',
        'imap_scanmailbox' => 'imap_listscan',
    ];

    /** @var array<string, string> stores alias (key) - master (value) functions mapping */
    private static $mbregSet = [
        'mbereg' => 'mb_ereg',
        'mbereg_match' => 'mb_ereg_match',
        'mbereg_replace' => 'mb_ereg_replace',
        'mbereg_search' => 'mb_ereg_search',
        'mbereg_search_getpos' => 'mb_ereg_search_getpos',
        'mbereg_search_getregs' => 'mb_ereg_search_getregs',
        'mbereg_search_init' => 'mb_ereg_search_init',
        'mbereg_search_pos' => 'mb_ereg_search_pos',
        'mbereg_search_regs' => 'mb_ereg_search_regs',
        'mbereg_search_setpos' => 'mb_ereg_search_setpos',
        'mberegi' => 'mb_eregi',
        'mberegi_replace' => 'mb_eregi_replace',
        'mbregex_encoding' => 'mb_regex_encoding',
        'mbsplit' => 'mb_split',
    ];

    public function configure(array $configuration = null)
    {
        parent::configure($configuration);

        $this->aliases = [];
        foreach ($this->configuration['sets'] as $set) {
            if ('@all' === $set) {
                $this->aliases = self::$internalSet;
                $this->aliases = array_merge($this->aliases, self::$imapSet);
                $this->aliases = array_merge($this->aliases, self::$mbregSet);

                break;
            }
            if ('@internal' === $set) {
                $this->aliases = array_merge($this->aliases, self::$internalSet);
            } elseif ('@IMAP' === $set) {
                $this->aliases = array_merge($this->aliases, self::$imapSet);
            } elseif ('@mbreg' === $set) {
                $this->aliases = array_merge($this->aliases, self::$mbregSet);
            }
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getDefinition()
    {
        return new FixerDefinition(
            'Master functions shall be used instead of aliases.',
            [
                new CodeSample(
                    '<?php
$a = chop($b);
close($b);
$a = doubleval($b);
$a = fputs($b, $c);
$a = get_required_files();
ini_alter($b, $c);
$a = is_double($b);
$a = is_integer($b);
$a = is_long($b);
$a = is_real($b);
$a = is_writeable($b);
$a = join($glue, $pieces);
$a = key_exists($key, $array);
magic_quotes_runtime($new_setting);
$a = pos($array);
$a = show_source($filename, true);
$a = sizeof($b);
$a = strchr($haystack, $needle);
$a = imap_header($imap_stream, 1);
user_error($message);
mbereg_search_getregs();
'
                ),
                new CodeSample(
                    '<?php
$a = is_double($b);
mbereg_search_getregs();
',
                    ['sets' => ['@mbreg']]
                ),
            ],
            null,
            'Risky when any of the alias functions are overridden.'
        );
    }

    /**
     * {@inheritdoc}
     */
    public function isCandidate(Tokens $tokens)
    {
        return $tokens->isTokenKindFound(T_STRING);
    }

    /**
     * {@inheritdoc}
     */
    public function isRisky()
    {
        return true;
    }

    /**
     * {@inheritdoc}
     */
    protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        $functionsAnalyzer = new FunctionsAnalyzer();

        /** @var \PhpCsFixer\Tokenizer\Token $token */
        foreach ($tokens->findGivenKind(T_STRING) as $index => $token) {
            // check mapping hit
            $tokenContent = strtolower($token->getContent());
            if (!isset($this->aliases[$tokenContent])) {
                continue;
            }

            // skip expressions without parameters list
            $nextToken = $tokens[$tokens->getNextMeaningfulToken($index)];
            if (!$nextToken->equals('(')) {
                continue;
            }

            if (!$functionsAnalyzer->isGlobalFunctionCall($tokens, $index)) {
                continue;
            }

            $tokens[$index] = new Token([T_STRING, $this->aliases[$tokenContent]]);
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function createConfigurationDefinition()
    {
        $sets = ['@internal', '@IMAP', '@mbreg', '@all'];

        return new FixerConfigurationResolver([
            (new FixerOptionBuilder('sets', 'List of sets to fix. Defined sets are `@internal` (native functions), `@IMAP` (IMAP functions), `@mbreg` (from `ext-mbstring`) `@all` (all listed sets).'))
                ->setAllowedTypes(['array'])
                ->setAllowedValues([new AllowedValueSubset($sets)])
                ->setDefault(['@internal', '@IMAP'])
                ->getOption(),
        ]);
    }
}


<?php

/*
 * 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\Report;

use Symfony\Component\Finder\Finder as SymfonyFinder;
use Symfony\Component\Finder\SplFileInfo;

/**
 * @author Boris Gorbylev <ekho@ekho.name>
 *
 * @internal
 */
final class ReporterFactory
{
    /** @var ReporterInterface[] */
    private $reporters = [];

    public static function create()
    {
        return new self();
    }

    public function registerBuiltInReporters()
    {
        /** @var string[] $builtInReporters */
        static $builtInReporters;

        if (null === $builtInReporters) {
            $builtInReporters = [];

            /** @var SplFileInfo $file */
            foreach (SymfonyFinder::create()->files()->name('*Reporter.php')->in(__DIR__) as $file) {
                $relativeNamespace = $file->getRelativePath();
                $builtInReporters[] = sprintf(
                    '%s\\%s%s',
                    __NAMESPACE__,
                    $relativeNamespace ? $relativeNamespace.'\\' : '',
                    $file->getBasename('.php')
                );
            }
        }

        foreach ($builtInReporters as $reporterClass) {
            $this->registerReporter(new $reporterClass());
        }

        return $this;
    }

    /**
     * @param ReporterInterface $reporter
     *
     * @return $this
     */
    public function registerReporter(ReporterInterface $reporter)
    {
        $format = $reporter->getFormat();

        if (isset($this->reporters[$format])) {
            throw new \UnexpectedValueException(sprintf('Reporter for format "%s" is already registered.', $format));
        }

        $this->reporters[$format] = $reporter;

        return $this;
    }

    /**
     * @return string[]
     */
    public function getFormats()
    {
        $formats = array_keys($this->reporters);
        sort($formats);

        return $formats;
    }

    /**
     * @param string $format
     *
     * @return ReporterInterface
     */
    public function getReporter($format)
    {
        if (!isset($this->reporters[$format])) {
            throw new \UnexpectedValueException(sprintf('Reporter for format "%s" is not registered.', $format));
        }

        return $this->reporters[$format];
    }
}


<?php

/*
 * 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;

/**
 * Handles files removal with possibility to remove them on shutdown.
 *
 * @author Adam Klvač <adam@klva.cz>
 * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
 *
 * @internal
 */
final class FileRemoval
{
    /**
     * List of observed files to be removed.
     *
     * @var array
     */
    private $files = [];

    public function __construct()
    {
        register_shutdown_function([$this, 'clean']);
    }

    public function __destruct()
    {
        $this->clean();
    }

    /**
     * Adds a file to be removed.
     *
     * @param string $path
     */
    public function observe($path)
    {
        $this->files[$path] = true;
    }

    /**
     * Removes a file from shutdown removal.
     *
     * @param string $path
     */
    public function delete($path)
    {
        if (isset($this->files[$path])) {
            unset($this->files[$path]);
        }
        $this->unlink($path);
    }

    /**
     * Removes attached files.
     */
    public function clean()
    {
        foreach ($this->files as $file => $value) {
            $this->unlink($file);
        }
        $this->files = [];
    }

    private function unlink($path)
    {
        @unlink($path);
    }
}


<?php

/*
 * 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\Operator;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;

/**
 * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
 */
final class StandardizeNotEqualsFixer extends AbstractFixer
{
    /**
     * {@inheritdoc}
     */
    public function getDefinition()
    {
        return new FixerDefinition(
            'Replace all `<>` with `!=`.',
            [new CodeSample("<?php\n\$a = \$b <> \$c;\n")]
        );
    }

    /**
     * {@inheritdoc}
     */
    public function isCandidate(Tokens $tokens)
    {
        return $tokens->isTokenKindFound(T_IS_NOT_EQUAL);
    }

    /**
     * {@inheritdoc}
     */
    protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        foreach ($tokens as $index => $token) {
            if ($token->isGivenKind(T_IS_NOT_EQUAL)) {
                $tokens[$index] = new Token([T_IS_NOT_EQUAL, '!=']);
            }
        }
    }
}


<?php

/*
 * 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\PhpTag;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;

/**
 * @author Vincent Klaiber <hello@vinkla.com>
 */
final class NoShortEchoTagFixer extends AbstractFixer
{
    /**
     * {@inheritdoc}
     */
    public function getDefinition()
    {
        return new FixerDefinition(
            'Replace short-echo `<?=` with long format `<?php echo` syntax.',
            [new CodeSample("<?= \"foo\";\n")]
        );
    }

    /**
     * {@inheritdoc}
     */
    public function isCandidate(Tokens $tokens)
    {
        return $tokens->isTokenKindFound(T_OPEN_TAG_WITH_ECHO);
    }

    /**
     * {@inheritdoc}
     */
    protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        $i = \count($tokens);

        while ($i--) {
            $token = $tokens[$i];

            if (!$token->isGivenKind(T_OPEN_TAG_WITH_ECHO)) {
                continue;
            }

            $nextIndex = $i + 1;

            $tokens[$i] = new Token([T_OPEN_TAG, '<?php ']);

            if (!$tokens[$nextIndex]->isWhitespace()) {
                $tokens->insertAt($nextIndex, new Token([T_WHITESPACE, ' ']));
            }

            $tokens->insertAt($nextIndex, new Token([T_ECHO, 'echo']));
        }
    }
}


<?php

/*
 * 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;

use PhpCsFixer\Fixer\FixerInterface;
use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface;
use PhpCsFixer\Tokenizer\Tokens;

/**
 * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
 *
 * @internal
 */
abstract class AbstractProxyFixer extends AbstractFixer
{
    /**
     * @var array<string, FixerInterface>
     */
    protected $proxyFixers;

    public function __construct()
    {
        foreach (Utils::sortFixers($this->createProxyFixers()) as $proxyFixer) {
            $this->proxyFixers[$proxyFixer->getName()] = $proxyFixer;
        }

        parent::__construct();
    }

    /**
     * {@inheritdoc}
     */
    public function isCandidate(Tokens $tokens)
    {
        foreach ($this->proxyFixers as $fixer) {
            if ($fixer->isCandidate($tokens)) {
                return true;
            }
        }

        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function isRisky()
    {
        foreach ($this->proxyFixers as $fixer) {
            if ($fixer->isRisky()) {
                return true;
            }
        }

        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function getPriority()
    {
        if (\count($this->proxyFixers) > 1) {
            throw new \LogicException('You need to override this method to provide the priority of combined fixers.');
        }

        return reset($this->proxyFixers)->getPriority();
    }

    /**
     * {@inheritdoc}
     */
    public function supports(\SplFileInfo $file)
    {
        foreach ($this->proxyFixers as $fixer) {
            if ($fixer->supports($file)) {
                return true;
            }
        }

        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function setWhitespacesConfig(WhitespacesFixerConfig $config)
    {
        parent::setWhitespacesConfig($config);

        foreach ($this->proxyFixers as $fixer) {
            if ($fixer instanceof WhitespacesAwareFixerInterface) {
                $fixer->setWhitespacesConfig($config);
            }
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        foreach ($this->proxyFixers as $fixer) {
            $fixer->fix($file, $tokens);
        }
    }

    /**
     * @return FixerInterface[]
     */
    abstract protected function createProxyFixers();
}


<?php

/*
 * 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\Tokenizer;

use PhpCsFixer\Utils;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;

/**
 * Collection of Transformer classes.
 *
 * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
 *
 * @internal
 */
final class Transformers
{
    /**
     * The registered transformers.
     *
     * @var TransformerInterface[]
     */
    private $items = [];

    /**
     * Register built in Transformers.
     */
    private function __construct()
    {
        $this->registerBuiltInTransformers();

        usort($this->items, static function (TransformerInterface $a, TransformerInterface $b) {
            return Utils::cmpInt($b->getPriority(), $a->getPriority());
        });
    }

    /**
     * @return Transformers
     */
    public static function create()
    {
        static $instance = null;

        if (!$instance) {
            $instance = new self();
        }

        return $instance;
    }

    /**
     * Transform given Tokens collection through all Transformer classes.
     *
     * @param Tokens $tokens Tokens collection
     */
    public function transform(Tokens $tokens)
    {
        foreach ($this->items as $transformer) {
            foreach ($tokens as $index => $token) {
                $transformer->process($tokens, $token, $index);
            }
        }
    }

    /**
     * @param TransformerInterface $transformer Transformer
     */
    private function registerTransformer(TransformerInterface $transformer)
    {
        if (\PHP_VERSION_ID >= $transformer->getRequiredPhpVersionId()) {
            $this->items[] = $transformer;
        }
    }

    private function registerBuiltInTransformers()
    {
        static $registered = false;

        if ($registered) {
            return;
        }

        $registered = true;

        foreach ($this->findBuiltInTransformers() as $transformer) {
            $this->registerTransformer($transformer);
        }
    }

    /**
     * @return \Generator|TransformerInterface[]
     */
    private function findBuiltInTransformers()
    {
        /** @var SplFileInfo $file */
        foreach (Finder::create()->files()->in(__DIR__.'/Transformer') as $file) {
            $relativeNamespace = $file->getRelativePath();
            $class = __NAMESPACE__.'\\Transformer\\'.($relativeNamespace ? $relativeNamespace.'\\' : '').$file->getBasename('.php');

            yield new $class();
        }
    }
}


<?php

/*
 * 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\Import;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
use PhpCsFixer\Tokenizer\TokensAnalyzer;
use PhpCsFixer\Utils;

/**
 * Fixer for rules defined in PSR2 ¶3.
 *
 * @author Ceeram <ceeram@cakephp.org>
 * @author Graham Campbell <graham@alt-three.com>
 */
final class SingleLineAfterImportsFixer extends AbstractFixer implements WhitespacesAwareFixerInterface
{
    /**
     * {@inheritdoc}
     */
    public function isCandidate(Tokens $tokens)
    {
        return $tokens->isTokenKindFound(T_USE);
    }

    /**
     * {@inheritdoc}
     */
    public function getDefinition()
    {
        return new FixerDefinition(
            'Each namespace use MUST go on its own line and there MUST be one blank line after the use statements block.',
            [
                new CodeSample(
                    '<?php
namespace Foo;

use Bar;
use Baz;
final class Example
{
}
'
                ),
                new CodeSample(
                    '<?php
namespace Foo;

use Bar;
use Baz;

final class Example
{
}
'
                ),
            ]
        );
    }

    /**
     * {@inheritdoc}
     */
    protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        $ending = $this->whitespacesConfig->getLineEnding();
        $tokensAnalyzer = new TokensAnalyzer($tokens);

        $added = 0;
        foreach ($tokensAnalyzer->getImportUseIndexes() as $index) {
            $index += $added;
            $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, [';', [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(';'));
                ++$added;
            }

            if ($semicolonIndex === \count($tokens) - 1) {
                $tokens->insertAt($insertIndex + 1, new Token([T_WHITESPACE, $ending.$ending.$indent]));
                ++$added;
            } 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) {
                            $tokens[$insertIndex] = new Token([T_WHITESPACE, $newline.$indent.ltrim($nextToken->getContent())]);
                        }
                    } else {
                        $tokens[$insertIndex] = new Token([T_WHITESPACE, $newline.$indent.ltrim($nextToken->getContent())]);
                    }
                } else {
                    $tokens->insertAt($insertIndex, new Token([T_WHITESPACE, $newline.$indent]));
                    ++$added;
                }
            }
        }
    }
}


<?php

/*
 * 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\Casing;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Tokenizer\CT;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;

/**
 * Fixer for rules defined in PSR2 ¶2.5.
 *
 * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
 */
final class LowercaseConstantsFixer extends AbstractFixer
{
    /**
     * {@inheritdoc}
     */
    public function getDefinition()
    {
        return new FixerDefinition(
            'The PHP constants `true`, `false`, and `null` MUST be in lower case.',
            [new CodeSample("<?php\n\$a = FALSE;\n\$b = True;\n\$c = nuLL;\n")]
        );
    }

    /**
     * {@inheritdoc}
     */
    public function isCandidate(Tokens $tokens)
    {
        return $tokens->isTokenKindFound(T_STRING);
    }

    /**
     * {@inheritdoc}
     */
    protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        foreach ($tokens as $index => $token) {
            if (!$token->isNativeConstant()) {
                continue;
            }

            if (
                $this->isNeighbourAccepted($tokens, $tokens->getPrevMeaningfulToken($index)) &&
                $this->isNeighbourAccepted($tokens, $tokens->getNextMeaningfulToken($index))
            ) {
                $tokens[$index] = new Token([$token->getId(), strtolower($token->getContent())]);
            }
        }
    }

    /**
     * @param Tokens $tokens
     * @param int    $index
     *
     * @return bool
     */
    private function isNeighbourAccepted(Tokens $tokens, $index)
    {
        static $forbiddenTokens = [
            T_AS,
            T_CLASS,
            T_CONST,
            T_EXTENDS,
            T_IMPLEMENTS,
            T_INSTANCEOF,
            T_INSTEADOF,
            T_INTERFACE,
            T_NEW,
            T_NS_SEPARATOR,
            T_OBJECT_OPERATOR,
            T_PAAMAYIM_NEKUDOTAYIM,
            T_TRAIT,
            T_USE,
            CT::T_USE_TRAIT,
            CT::T_USE_LAMBDA,
        ];

        $token = $tokens[$index];

        if ($token->equalsAny(['{', '}'])) {
            return false;
        }

        return !$token->isGivenKind($forbiddenTokens);
    }
}


<?php

/*
 * 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\Comment;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Preg;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;

/**
 * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
 */
final class NoTrailingWhitespaceInCommentFixer extends AbstractFixer
{
    /**
     * {@inheritdoc}
     */
    public function getDefinition()
    {
        return new FixerDefinition(
            'There MUST be no trailing spaces inside comment or PHPDoc.',
            [new CodeSample('<?php
// This is '.'
// a comment. '.'
')]
        );
    }

    /**
     * {@inheritdoc}
     */
    public function isCandidate(Tokens $tokens)
    {
        return $tokens->isAnyTokenKindsFound([T_COMMENT, T_DOC_COMMENT]);
    }

    /**
     * {@inheritdoc}
     */
    protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        foreach ($tokens as $index => $token) {
            if ($token->isGivenKind(T_DOC_COMMENT)) {
                $tokens[$index] = new Token([T_DOC_COMMENT, Preg::replace('/(*ANY)[ \t]+$/m', '', $token->getContent())]);

                continue;
            }

            if ($token->isGivenKind(T_COMMENT)) {
                if ('/*' === substr($token->getContent(), 0, 2)) {
                    $tokens[$index] = new Token([T_COMMENT, Preg::replace('/(*ANY)[ \t]+$/m', '', $token->getContent())]);
                } elseif (isset($tokens[$index + 1]) && $tokens[$index + 1]->isWhitespace()) {
                    $trimmedContent = ltrim($tokens[$index + 1]->getContent(), " \t");
                    if ('' !== $trimmedContent) {
                        $tokens[$index + 1] = new Token([T_WHITESPACE, $trimmedContent]);
                    } else {
                        $tokens->clearAt($index + 1);
                    }
                }
            }
        }
    }
}


<?php

/*
 * 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\ArrayNotation;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Tokenizer\CT;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
use PhpCsFixer\Tokenizer\TokensAnalyzer;

/**
 * @author Sebastiaan Stok <s.stok@rollerscapes.net>
 * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
 */
final class TrailingCommaInMultilineArrayFixer extends AbstractFixer
{
    /**
     * {@inheritdoc}
     */
    public function getDefinition()
    {
        return new FixerDefinition(
            'PHP multi-line arrays should have a trailing comma.',
            [new CodeSample("<?php\narray(\n    1,\n    2\n);\n")]
        );
    }

    /**
     * {@inheritdoc}
     */
    public function isCandidate(Tokens $tokens)
    {
        return $tokens->isAnyTokenKindsFound([T_ARRAY, CT::T_ARRAY_SQUARE_BRACE_OPEN]);
    }

    /**
     * {@inheritdoc}
     */
    protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        $tokensAnalyzer = new TokensAnalyzer($tokens);

        for ($index = $tokens->count() - 1; $index >= 0; --$index) {
            if ($tokensAnalyzer->isArray($index) && $tokensAnalyzer->isArrayMultiLine($index)) {
                $this->fixArray($tokens, $index);
            }
        }
    }

    /**
     * @param Tokens $tokens
     * @param int    $index
     */
    private function fixArray(Tokens $tokens, $index)
    {
        $startIndex = $index;

        if ($tokens[$startIndex]->isGivenKind(T_ARRAY)) {
            $startIndex = $tokens->getNextTokenOfKind($startIndex, ['(']);
            $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $startIndex);
        } else {
            $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, $startIndex);
        }

        $beforeEndIndex = $tokens->getPrevMeaningfulToken($endIndex);
        $beforeEndToken = $tokens[$beforeEndIndex];

        // if there is some item between braces then add `,` after it
        if ($startIndex !== $beforeEndIndex && !$beforeEndToken->equalsAny([',', [T_END_HEREDOC]])) {
            $tokens->insertAt($beforeEndIndex + 1, new Token(','));

            $endToken = $tokens[$endIndex];

            if (!$endToken->isComment() && !$endToken->isWhitespace()) {
                $tokens->ensureWhitespaceAtIndex($endIndex, 1, ' ');
            }
        }
    }
}


<?php

/*
 * 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\PhpUnit;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\Fixer\ConfigurationDefinitionFixerInterface;
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver;
use PhpCsFixer\FixerConfiguration\FixerOptionBuilder;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Indicator\PhpUnitTestCaseIndicator;
use PhpCsFixer\Tokenizer\Analyzer\ArgumentsAnalyzer;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;

/**
 * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
 */
final class PhpUnitMockFixer extends AbstractFixer implements ConfigurationDefinitionFixerInterface
{
    /**
     * @var bool
     */
    private $fixCreatePartialMock;

    /**
     * {@inheritdoc}
     */
    public function getDefinition()
    {
        return new FixerDefinition(
            'Usages of `->getMock` and `->getMockWithoutInvokingTheOriginalConstructor` methods MUST be replaced by `->createMock` or `->createPartialMock` methods.',
            [
                new CodeSample(
                    '<?php
final class MyTest extends \PHPUnit_Framework_TestCase
{
    public function testFoo()
    {
        $mock = $this->getMockWithoutInvokingTheOriginalConstructor("Foo");
        $mock1 = $this->getMock("Foo");
        $mock1 = $this->getMock("Bar", ["aaa"]);
        $mock1 = $this->getMock("Baz", ["aaa"], ["argument"]); // version with more than 2 params is not supported
    }
}
'
                ),
                new CodeSample(
                    '<?php
final class MyTest extends \PHPUnit_Framework_TestCase
{
    public function testFoo()
    {
        $mock1 = $this->getMock("Foo");
        $mock1 = $this->getMock("Bar", ["aaa"]); // version with multiple params is not supported
    }
}
',
                    ['target' => PhpUnitTargetVersion::VERSION_5_4]
                ),
            ],
            null,
            'Risky when PHPUnit classes are overridden or not accessible, or when project has PHPUnit incompatibilities.'
        );
    }

    /**
     * {@inheritdoc}
     */
    public function isCandidate(Tokens $tokens)
    {
        return $tokens->isTokenKindFound(T_CLASS);
    }

    /**
     * {@inheritdoc}
     */
    public function isRisky()
    {
        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function configure(array $configuration = null)
    {
        parent::configure($configuration);

        $this->fixCreatePartialMock = PhpUnitTargetVersion::fulfills($this->configuration['target'], PhpUnitTargetVersion::VERSION_5_5);
    }

    /**
     * {@inheritdoc}
     */
    protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        $phpUnitTestCaseIndicator = new PhpUnitTestCaseIndicator();
        $argumentsAnalyzer = new ArgumentsAnalyzer();

        foreach ($phpUnitTestCaseIndicator->findPhpUnitClasses($tokens) as $indexes) {
            for ($index = $indexes[0]; $index < $indexes[1]; ++$index) {
                if (!$tokens[$index]->isGivenKind(T_OBJECT_OPERATOR)) {
                    continue;
                }

                $index = $tokens->getNextMeaningfulToken($index);

                if ($tokens[$index]->equals([T_STRING, 'getMockWithoutInvokingTheOriginalConstructor'], false)) {
                    $tokens[$index] = new Token([T_STRING, 'createMock']);
                } elseif ($tokens[$index]->equals([T_STRING, 'getMock'], false)) {
                    $openingParenthesis = $tokens->getNextMeaningfulToken($index);
                    $closingParenthesis = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $openingParenthesis);

                    $argumentsCount = $argumentsAnalyzer->countArguments($tokens, $openingParenthesis, $closingParenthesis);

                    if (1 === $argumentsCount) {
                        $tokens[$index] = new Token([T_STRING, 'createMock']);
                    } elseif (2 === $argumentsCount && true === $this->fixCreatePartialMock) {
                        $tokens[$index] = new Token([T_STRING, 'createPartialMock']);
                    }
                }
            }
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function createConfigurationDefinition()
    {
        return new FixerConfigurationResolver([
            (new FixerOptionBuilder('target', 'Target version of PHPUnit.'))
                ->setAllowedTypes(['string'])
                ->setAllowedValues([PhpUnitTargetVersion::VERSION_5_4, PhpUnitTargetVersion::VERSION_5_5, PhpUnitTargetVersion::VERSION_NEWEST])
                ->setDefault(PhpUnitTargetVersion::VERSION_NEWEST)
                ->getOption(),
        ]);
    }
}


<?php

/*
 * 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\Casing;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Tokenizer\CT;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;

/**
 * @author ntzm
 */
final class MagicConstantCasingFixer extends AbstractFixer
{
    /**
     * {@inheritdoc}
     */
    public function getDefinition()
    {
        return new FixerDefinition(
            'Magic constants should be referred to using the correct casing.',
            [new CodeSample("<?php\necho __dir__;\n")]
        );
    }

    /**
     * {@inheritdoc}
     */
    public function isCandidate(Tokens $tokens)
    {
        return $tokens->isAnyTokenKindsFound($this->getMagicConstantTokens());
    }

    /**
     * {@inheritdoc}
     */
    protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        $magicConstants = $this->getMagicConstants();
        $magicConstantTokens = $this->getMagicConstantTokens();

        foreach ($tokens as $index => $token) {
            if ($token->isGivenKind($magicConstantTokens)) {
                $tokens[$index] = new Token([$token->getId(), $magicConstants[$token->getId()]]);
            }
        }
    }

    /**
     * @return array<int, string>
     */
    private function getMagicConstants()
    {
        static $magicConstants = null;

        if (null === $magicConstants) {
            $magicConstants = [
                T_LINE => '__LINE__',
                T_FILE => '__FILE__',
                T_DIR => '__DIR__',
                T_FUNC_C => '__FUNCTION__',
                T_CLASS_C => '__CLASS__',
                T_METHOD_C => '__METHOD__',
                T_NS_C => '__NAMESPACE__',
                CT::T_CLASS_CONSTANT => 'class',
                T_TRAIT_C => '__TRAIT__',
            ];
        }

        return $magicConstants;
    }

    /**
     * @return array<int>
     */
    private function getMagicConstantTokens()
    {
        static $magicConstantTokens = null;

        if (null === $magicConstantTokens) {
            $magicConstantTokens = array_keys($this->getMagicConstants());
        }

        return $magicConstantTokens;
    }
}


<?php

/*
 * 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\Tokenizer;

use PhpCsFixer\Utils;

/**
 * Representation of single token.
 * As a token prototype you should understand a single element generated by token_get_all.
 *
 * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
 */
class Token
{
    /**
     * Content of token prototype.
     *
     * @var string
     */
    private $content;

    /**
     * ID of token prototype, if available.
     *
     * @var null|int
     */
    private $id;

    /**
     * If token prototype is an array.
     *
     * @var bool
     */
    private $isArray;

    /**
     * Flag is token was changed.
     *
     * @var bool
     */
    private $changed = false;

    /**
     * @param array|string $token token prototype
     */
    public function __construct($token)
    {
        if (\is_array($token)) {
            if (!\is_int($token[0])) {
                throw new \InvalidArgumentException(sprintf(
                    'Id must be an int, got "%s".',
                    \is_object($token[0]) ? \get_class($token[0]) : \gettype($token[0])
                ));
            }

            if (!\is_string($token[1])) {
                throw new \InvalidArgumentException(sprintf(
                    'Content must be a string, got "%s".',
                    \is_object($token[1]) ? \get_class($token[1]) : \gettype($token[1])
                ));
            }

            if ('' === $token[1]) {
                throw new \InvalidArgumentException('Cannot set empty content for id-based Token.');
            }

            $this->isArray = true;
            $this->id = $token[0];
            $this->content = $token[1];

            if ($token[0] && '' === $token[1]) {
                throw new \InvalidArgumentException('Cannot set empty content for id-based Token.');
            }
        } elseif (\is_string($token)) {
            $this->isArray = false;
            $this->content = $token;
        } else {
            throw new \InvalidArgumentException(sprintf(
                'Cannot recognize input value as valid Token prototype, got "%s".',
                \is_object($token) ? \get_class($token) : \gettype($token)
            ));
        }
    }

    /**
     * @return int[]
     */
    public static function getCastTokenKinds()
    {
        static $castTokens = [T_ARRAY_CAST, T_BOOL_CAST, T_DOUBLE_CAST, T_INT_CAST, T_OBJECT_CAST, T_STRING_CAST, T_UNSET_CAST];

        return $castTokens;
    }

    /**
     * Get classy tokens kinds: T_CLASS, T_INTERFACE and T_TRAIT.
     *
     * @return int[]
     */
    public static function getClassyTokenKinds()
    {
        static $classTokens = [T_CLASS, T_TRAIT, T_INTERFACE];

        return $classTokens;
    }

    /**
     * Clear token at given index.
     *
     * Clearing means override token by empty string.
     *
     * @deprecated since 2.4
     */
    public function clear()
    {
        @trigger_error(__METHOD__.' is deprecated and will be removed in 3.0.', E_USER_DEPRECATED);
        Tokens::setLegacyMode(true);

        $this->content = '';
        $this->id = null;
        $this->isArray = false;
    }

    /**
     * Clear internal flag if token was changed.
     *
     * @deprecated since 2.4
     */
    public function clearChanged()
    {
        @trigger_error(__METHOD__.' is deprecated and will be removed in 3.0.', E_USER_DEPRECATED);
        Tokens::setLegacyMode(true);

        $this->changed = false;
    }

    /**
     * Check if token is equals to given one.
     *
     * If tokens are arrays, then only keys defined in parameter token are checked.
     *
     * @param array|string|Token $other         token or it's prototype
     * @param bool               $caseSensitive perform a case sensitive comparison
     *
     * @return bool
     */
    public function equals($other, $caseSensitive = true)
    {
        if ($other instanceof self) {
            // Inlined getPrototype() on this very hot path.
            // We access the private properties of $other directly to save function call overhead.
            // This is only possible because $other is of the same class as `self`.
            if (!$other->isArray) {
                $otherPrototype = $other->content;
            } else {
                $otherPrototype = [
                    $other->id,
                    $other->content,
                ];
            }
        } else {
            $otherPrototype = $other;
        }

        if ($this->isArray !== \is_array($otherPrototype)) {
            return false;
        }

        if (!$this->isArray) {
            return $this->content === $otherPrototype;
        }

        if ($this->id !== $otherPrototype[0]) {
            return false;
        }

        if (isset($otherPrototype[1])) {
            if ($caseSensitive) {
                if ($this->content !== $otherPrototype[1]) {
                    return false;
                }
            } elseif (0 !== strcasecmp($this->content, $otherPrototype[1])) {
                return false;
            }
        }

        // detect unknown keys
        unset($otherPrototype[0], $otherPrototype[1]);

        return empty($otherPrototype);
    }

    /**
     * Check if token is equals to one of given.
     *
     * @param array $others        array of tokens or token prototypes
     * @param bool  $caseSensitive perform a case sensitive comparison
     *
     * @return bool
     */
    public function equalsAny(array $others, $caseSensitive = true)
    {
        foreach ($others as $other) {
            if ($this->equals($other, $caseSensitive)) {
                return true;
            }
        }

        return false;
    }

    /**
     * A helper method used to find out whether or not a certain input token has to be case-sensitively matched.
     *
     * @param array<int, bool>|bool $caseSensitive global case sensitiveness or an array of booleans, whose keys should match
     *                                             the ones used in $others. If any is missing, the default case-sensitive
     *                                             comparison is used
     * @param int                   $key           the key of the token that has to be looked up
     *
     * @return bool
     */
    public static function isKeyCaseSensitive($caseSensitive, $key)
    {
        if (\is_array($caseSensitive)) {
            return isset($caseSensitive[$key]) ? $caseSensitive[$key] : true;
        }

        return $caseSensitive;
    }

    /**
     * @return array|string token prototype
     */
    public function getPrototype()
    {
        if (!$this->isArray) {
            return $this->content;
        }

        return [
            $this->id,
            $this->content,
        ];
    }

    /**
     * Get token's content.
     *
     * It shall be used only for getting the content of token, not for checking it against excepted value.
     *
     * @return string
     */
    public function getContent()
    {
        return $this->content;
    }

    /**
     * Get token's id.
     *
     * It shall be used only for getting the internal id of token, not for checking it against excepted value.
     *
     * @return null|int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Get token's name.
     *
     * It shall be used only for getting the name of token, not for checking it against excepted value.
     *
     * @return null|string token name
     */
    public function getName()
    {
        if (null === $this->id) {
            return null;
        }

        return self::getNameForId($this->id);
    }

    /**
     * Get token's name.
     *
     * It shall be used only for getting the name of token, not for checking it against excepted value.
     *
     * @param int $id
     *
     * @return null|string token name
     */
    public static function getNameForId($id)
    {
        if (CT::has($id)) {
            return CT::getName($id);
        }

        $name = token_name($id);

        return 'UNKNOWN' === $name ? null : $name;
    }

    /**
     * Generate array containing all keywords that exists in PHP version in use.
     *
     * @return array<int, int>
     */
    public static function getKeywords()
    {
        static $keywords = null;

        if (null === $keywords) {
            $keywords = self::getTokenKindsForNames(['T_ABSTRACT', 'T_ARRAY', 'T_AS', 'T_BREAK', 'T_CALLABLE', 'T_CASE',
                'T_CATCH', 'T_CLASS', 'T_CLONE', 'T_CONST', 'T_CONTINUE', 'T_DECLARE', 'T_DEFAULT', 'T_DO',
                'T_ECHO', 'T_ELSE', 'T_ELSEIF', 'T_EMPTY', 'T_ENDDECLARE', 'T_ENDFOR', 'T_ENDFOREACH',
                'T_ENDIF', 'T_ENDSWITCH', 'T_ENDWHILE', 'T_EVAL', 'T_EXIT', 'T_EXTENDS', 'T_FINAL',
                'T_FINALLY', 'T_FOR', 'T_FOREACH', 'T_FUNCTION', 'T_GLOBAL', 'T_GOTO', 'T_HALT_COMPILER',
                'T_IF', 'T_IMPLEMENTS', 'T_INCLUDE', 'T_INCLUDE_ONCE', 'T_INSTANCEOF', 'T_INSTEADOF',
                'T_INTERFACE', 'T_ISSET', 'T_LIST', 'T_LOGICAL_AND', 'T_LOGICAL_OR', 'T_LOGICAL_XOR',
                'T_NAMESPACE', 'T_NEW', 'T_PRINT', 'T_PRIVATE', 'T_PROTECTED', 'T_PUBLIC', 'T_REQUIRE',
                'T_REQUIRE_ONCE', 'T_RETURN', 'T_STATIC', 'T_SWITCH', 'T_THROW', 'T_TRAIT', 'T_TRY',
                'T_UNSET', 'T_USE', 'T_VAR', 'T_WHILE', 'T_YIELD', 'T_YIELD_FROM',
            ]) + [
                CT::T_ARRAY_TYPEHINT => CT::T_ARRAY_TYPEHINT,
                CT::T_CLASS_CONSTANT => CT::T_CLASS_CONSTANT,
                CT::T_CONST_IMPORT => CT::T_CONST_IMPORT,
                CT::T_FUNCTION_IMPORT => CT::T_FUNCTION_IMPORT,
                CT::T_NAMESPACE_OPERATOR => CT::T_NAMESPACE_OPERATOR,
                CT::T_USE_TRAIT => CT::T_USE_TRAIT,
                CT::T_USE_LAMBDA => CT::T_USE_LAMBDA,
            ];
        }

        return $keywords;
    }

    /**
     * Generate array containing all predefined constants that exists in PHP version in use.
     *
     * @see https://php.net/manual/en/language.constants.predefined.php
     *
     * @return array<int, int>
     */
    public static function getMagicConstants()
    {
        static $magicConstants = null;

        if (null === $magicConstants) {
            $magicConstants = self::getTokenKindsForNames(['T_CLASS_C', 'T_DIR', 'T_FILE', 'T_FUNC_C', 'T_LINE', 'T_METHOD_C', 'T_NS_C', 'T_TRAIT_C']);
        }

        return $magicConstants;
    }

    /**
     * Check if token prototype is an array.
     *
     * @return bool is array
     */
    public function isArray()
    {
        return $this->isArray;
    }

    /**
     * Check if token is one of type cast tokens.
     *
     * @return bool
     */
    public function isCast()
    {
        return $this->isGivenKind(self::getCastTokenKinds());
    }

    /**
     * Check if token was changed.
     *
     * @return bool
     *
     * @deprecated since 2.4
     */
    public function isChanged()
    {
        @trigger_error(__METHOD__.' is deprecated and will be removed in 3.0.', E_USER_DEPRECATED);

        return $this->changed;
    }

    /**
     * Check if token is one of classy tokens: T_CLASS, T_INTERFACE or T_TRAIT.
     *
     * @return bool
     */
    public function isClassy()
    {
        return $this->isGivenKind(self::getClassyTokenKinds());
    }

    /**
     * Check if token is one of comment tokens: T_COMMENT or T_DOC_COMMENT.
     *
     * @return bool
     */
    public function isComment()
    {
        static $commentTokens = [T_COMMENT, T_DOC_COMMENT];

        return $this->isGivenKind($commentTokens);
    }

    /**
     * Check if token is empty, e.g. because of clearing.
     *
     * @return bool
     *
     * @deprecated since 2.4
     */
    public function isEmpty()
    {
        @trigger_error(__METHOD__.' is deprecated and will be removed in 3.0.', E_USER_DEPRECATED);

        return null === $this->id && ('' === $this->content || null === $this->content);
    }

    /**
     * Check if token is one of given kind.
     *
     * @param int|int[] $possibleKind kind or array of kinds
     *
     * @return bool
     */
    public function isGivenKind($possibleKind)
    {
        return $this->isArray && (\is_array($possibleKind) ? \in_array($this->id, $possibleKind, true) : $this->id === $possibleKind);
    }

    /**
     * Check if token is a keyword.
     *
     * @return bool
     */
    public function isKeyword()
    {
        $keywords = static::getKeywords();

        return $this->isArray && isset($keywords[$this->id]);
    }

    /**
     * Check if token is a native PHP constant: true, false or null.
     *
     * @return bool
     */
    public function isNativeConstant()
    {
        static $nativeConstantStrings = ['true', 'false', 'null'];

        return $this->isArray && \in_array(strtolower($this->content), $nativeConstantStrings, true);
    }

    /**
     * Returns if the token is of a Magic constants type.
     *
     * @see https://php.net/manual/en/language.constants.predefined.php
     *
     * @return bool
     */
    public function isMagicConstant()
    {
        $magicConstants = static::getMagicConstants();

        return $this->isArray && isset($magicConstants[$this->id]);
    }

    /**
     * Check if token is whitespace.
     *
     * @param null|string $whitespaces whitespace characters, default is " \t\n\r\0\x0B"
     *
     * @return bool
     */
    public function isWhitespace($whitespaces = " \t\n\r\0\x0B")
    {
        if (null === $whitespaces) {
            $whitespaces = " \t\n\r\0\x0B";
        }

        if ($this->isArray && !$this->isGivenKind(T_WHITESPACE)) {
            return false;
        }

        return '' === trim($this->content, $whitespaces);
    }

    /**
     * Override token.
     *
     * If called on Token inside Tokens collection please use `Tokens::overrideAt` instead.
     *
     * @param array|string|Token $other token prototype
     *
     * @deprecated since 2.4
     */
    public function override($other)
    {
        @trigger_error(__METHOD__.' is deprecated and will be removed in 3.0.', E_USER_DEPRECATED);
        Tokens::setLegacyMode(true);

        $prototype = $other instanceof self ? $other->getPrototype() : $other;

        if ($this->equals($prototype)) {
            return;
        }

        $this->changed = true;

        if (\is_array($prototype)) {
            $this->isArray = true;
            $this->id = $prototype[0];
            $this->content = $prototype[1];

            return;
        }

        $this->isArray = false;
        $this->id = null;
        $this->content = $prototype;
    }

    /**
     * @param string $content
     *
     * @deprecated since 2.4
     */
    public function setContent($content)
    {
        @trigger_error(__METHOD__.' is deprecated and will be removed in 3.0.', E_USER_DEPRECATED);
        Tokens::setLegacyMode(true);

        if ($this->content === $content) {
            return;
        }

        $this->changed = true;
        $this->content = $content;

        // setting empty content is clearing the token
        if ('' === $content) {
            @trigger_error(__METHOD__.' shall not be used to clear token, use Tokens::clearAt instead.', E_USER_DEPRECATED);
            $this->id = null;
            $this->isArray = false;
        }
    }

    public function toArray()
    {
        return [
            'id' => $this->id,
            'name' => $this->getName(),
            'content' => $this->content,
            'isArray' => $this->isArray,
            'changed' => $this->changed,
        ];
    }

    /**
     * @param null|string[] $options JSON encode option
     *
     * @return string
     */
    public function toJson(array $options = null)
    {
        static $defaultOptions = null;

        if (null === $options) {
            if (null === $defaultOptions) {
                $defaultOptions = Utils::calculateBitmask(['JSON_PRETTY_PRINT', 'JSON_NUMERIC_CHECK']);
            }

            $options = $defaultOptions;
        } else {
            $options = Utils::calculateBitmask($options);
        }

        return json_encode($this->toArray(), $options);
    }

    /**
     * @param string[] $tokenNames
     *
     * @return array<int, int>
     */
    private static function getTokenKindsForNames(array $tokenNames)
    {
        $keywords = [];
        foreach ($tokenNames as $keywordName) {
            if (\defined($keywordName)) {
                $keyword = \constant($keywordName);
                $keywords[$keyword] = $keyword;
            }
        }

        return $keywords;
    }
}


<?php

/*
 * 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\Tokenizer\Transformer;

use PhpCsFixer\Tokenizer\AbstractTransformer;
use PhpCsFixer\Tokenizer\CT;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;

/**
 * Transform `namespace` operator from T_NAMESPACE into CT::T_NAMESPACE_OPERATOR.
 *
 * @author Gregor Harlan <gharlan@web.de>
 *
 * @internal
 */
final class NamespaceOperatorTransformer extends AbstractTransformer
{
    /**
     * {@inheritdoc}
     */
    public function getCustomTokens()
    {
        return [CT::T_NAMESPACE_OPERATOR];
    }

    /**
     * {@inheritdoc}
     */
    public function getRequiredPhpVersionId()
    {
        return 50300;
    }

    /**
     * {@inheritdoc}
     */
    public function process(Tokens $tokens, Token $token, $index)
    {
        if (!$token->isGivenKind(T_NAMESPACE)) {
            return;
        }

        $nextIndex = $tokens->getNextMeaningfulToken($index);
        $nextToken = $tokens[$nextIndex];

        if ($nextToken->isGivenKind(T_NS_SEPARATOR)) {
            $tokens[$index] = new Token([CT::T_NAMESPACE_OPERATOR, $token->getContent()]);
        }
    }
}