%PDF- %PDF-
| Direktori : /home/vacivi36/code/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/ |
| Current File : /home/vacivi36/code/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/MagicMethodCasingFixer.php |
<?php
declare(strict_types=1);
/*
* This file is part of PHP CS Fixer.
*
* (c) Fabien Potencier <fabien@symfony.com>
* Dariusz RumiĆski <dariusz.ruminski@gmail.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace PhpCsFixer\Fixer\Casing;
use PhpCsFixer\AbstractFixer;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
final class MagicMethodCasingFixer extends AbstractFixer
{
/**
* @var array<string,string>
*/
private static array $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(): FixerDefinitionInterface
{
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): bool
{
return $tokens->isTokenKindFound(T_STRING) && $tokens->isAnyTokenKindsFound(array_merge([T_FUNCTION, T_DOUBLE_COLON], Token::getObjectOperatorKinds()));
}
/**
* {@inheritdoc}
*/
protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
{
$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 (!str_starts_with($content, '__')) {
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);
}
}
}
private function isFunctionSignature(Tokens $tokens, int $index): bool
{
$prevIndex = $tokens->getPrevMeaningfulToken($index);
if (!$tokens[$prevIndex]->isGivenKind(T_FUNCTION)) {
return false; // not a method signature
}
return $tokens[$tokens->getNextMeaningfulToken($index)]->equals('(');
}
private function isMethodCall(Tokens $tokens, int $index): bool
{
$prevIndex = $tokens->getPrevMeaningfulToken($index);
if (!$tokens[$prevIndex]->isObjectOperator()) {
return false; // not a "simple" method call
}
return $tokens[$tokens->getNextMeaningfulToken($index)]->equals('(');
}
private function isStaticMethodCall(Tokens $tokens, int $index): bool
{
$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('(');
}
private function isMagicMethodName(string $name): bool
{
return isset(self::$magicNames[$name]);
}
/**
* @param string $name name of a magic method
*/
private function getMagicMethodNameInCorrectCasing(string $name): string
{
return self::$magicNames[$name];
}
private function setTokenToCorrectCasing(Tokens $tokens, int $index, string $nameInCorrectCasing): void
{
$tokens[$index] = new Token([T_STRING, $nameInCorrectCasing]);
}
}