Skip to content

Commit

Permalink
Merge pull request #2 from SpacePossum/liquid207_review
Browse files Browse the repository at this point in the history
review
  • Loading branch information
liquid207 committed Mar 10, 2022
2 parents 2e156d2 + 1718167 commit bbabf9f
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 38 deletions.
106 changes: 70 additions & 36 deletions src/Fixer/FunctionNotation/DateTimeCreateFromFormatCallFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
use PhpCsFixer\Tokenizer\Analyzer\ArgumentsAnalyzer;
use PhpCsFixer\Tokenizer\Analyzer\NamespacesAnalyzer;
use PhpCsFixer\Tokenizer\Analyzer\NamespaceUsesAnalyzer;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
Expand Down Expand Up @@ -47,58 +48,91 @@ public function isCandidate(Tokens $tokens): bool

protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
{
$useDeclarations = (new NamespaceUsesAnalyzer())->getDeclarationsFromTokens($tokens);
$argumentsAnalyzer = new ArgumentsAnalyzer();
$namespacesAnalyzer = new NamespacesAnalyzer();
$namespaceUsesAnalyzer = new NamespaceUsesAnalyzer();

for ($index = 0; $index < \count($tokens); ++$index) {
if (!$tokens[$index]->isGivenKind(T_DOUBLE_COLON)) {
continue;
}
foreach ($namespacesAnalyzer->getDeclarations($tokens) as $namespace) {
$scopeStartIndex = $namespace->getScopeStartIndex();
$useDeclarations = $namespaceUsesAnalyzer->getDeclarationsInNamespace($tokens, $namespace);

$functionNameIndex = $tokens->getNextMeaningfulToken($index);
for ($index = $namespace->getScopeEndIndex(); $index > $scopeStartIndex; --$index) {
if (!$tokens[$index]->isGivenKind(T_DOUBLE_COLON)) {
continue;
}

if (!$tokens[$functionNameIndex]->equals([T_STRING, 'createFromFormat'], false)) {
continue;
}
$functionNameIndex = $tokens->getNextMeaningfulToken($index);

if (!$tokens[$tokens->getNextMeaningfulToken($functionNameIndex)]->equals('(')) {
continue;
}
if (!$tokens[$functionNameIndex]->equals([T_STRING, 'createFromFormat'], false)) {
continue;
}

$classNamePreviousIndex = $tokens->getTokenNotOfKindsSibling($index, -1, [T_NS_SEPARATOR, T_STRING, T_COMMENT]);
$classNameIndex = $tokens->getPrevMeaningfulToken($index);
$className = $tokens->generatePartialCode($tokens->getNextMeaningfulToken($classNamePreviousIndex), $classNameIndex);
if (!$tokens[$tokens->getNextMeaningfulToken($functionNameIndex)]->equals('(')) {
continue;
}

foreach ($useDeclarations as $useDeclaration) {
if ($useDeclaration->getShortName() === $className) {
$className = $useDeclaration->getFullName();
$classNameIndex = $tokens->getPrevMeaningfulToken($index);

break;
if (!$tokens[$classNameIndex]->equals([T_STRING, 'DateTime'], false)) {
continue;
}
}

if (\DateTime::class !== str_replace('\\', '', $className)) {
continue;
}
$preClassNameIndex = $tokens->getPrevMeaningfulToken($classNameIndex);

if ($tokens[$preClassNameIndex]->isGivenKind(T_NS_SEPARATOR)) {
if ($tokens[$tokens->getPrevMeaningfulToken($preClassNameIndex)]->isGivenKind(T_STRING)) {
continue;
}
} elseif (!$namespace->isGlobalNamespace()) {
continue;
} else {
foreach ($useDeclarations as $useDeclaration) {
if ('datetime' === strtolower($useDeclaration->getShortName()) && 'datetime' !== strtolower($useDeclaration->getFullName())) {
continue 2;
}
}
}

$openIndex = $tokens->getNextTokenOfKind($functionNameIndex, ['(']);
$closeIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $openIndex);
$arguments = $argumentsAnalyzer->getArguments($tokens, $openIndex, $closeIndex);
$openIndex = $tokens->getNextTokenOfKind($functionNameIndex, ['(']);
$closeIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $openIndex);

if (2 !== \count($arguments)) {
continue;
}
$argumentIndex = $this->getFirstArgumentTokenIndex($tokens, $argumentsAnalyzer->getArguments($tokens, $openIndex, $closeIndex));

$formatArgumentIndex = $tokens->getNextMeaningfulToken($openIndex);
$formatToken = $tokens[$formatArgumentIndex];
$format = $formatToken->getContent();
if (null === $argumentIndex) {
continue;
}

if (!$formatToken->isGivenKind([T_CONSTANT_ENCAPSED_STRING]) || !\in_array(substr($format, 0, 1), ['\'', '"'], true) || '!' === substr($format, 1, 1)) {
continue;
$format = $tokens[$argumentIndex]->getContent();

if ('!' === substr($format, 1, 1)) {
continue;
}

$tokens->clearAt($argumentIndex);
$tokens->insertAt($argumentIndex, new Token([T_CONSTANT_ENCAPSED_STRING, substr_replace($format, '!', 1, 0)]));
}
}
}

$tokens->clearAt($formatArgumentIndex);
$tokens->insertAt($formatArgumentIndex, new Token([T_CONSTANT_ENCAPSED_STRING, substr_replace($format, '!', 1, 0)]));
private function getFirstArgumentTokenIndex(Tokens $tokens, array $arguments): ?int
{
if (2 !== \count($arguments)) {
return null;
}

$argumentStartIndex = array_key_first($arguments);
$argumentEndIndex = $arguments[$argumentStartIndex];
$argumentStartIndex = $tokens->getNextMeaningfulToken($argumentStartIndex - 1);

if (
$argumentStartIndex !== $argumentEndIndex
&& $tokens->getNextMeaningfulToken($argumentStartIndex) <= $argumentEndIndex
) {
return null; // argument is not a simple single string
}

return $tokens[$argumentStartIndex]->isGivenKind(T_CONSTANT_ENCAPSED_STRING)
? null // first argument is not a string
: $argumentStartIndex;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ public function provideFixCases(): \Generator
'<?php use \Example\DateTime; DateTime::createFromFormat(\'Y-m-d\', \'2022-02-11\');',
];

yield [
'<?php use \Example\datetime; DATETIME::createFromFormat(\'Y-m-d\', \'2022-02-11\');',
];

yield [
'<?php \DateTime::createFromFormat("!Y-m-d", \'2022-02-11\');',
'<?php \DateTime::createFromFormat("Y-m-d", \'2022-02-11\');',
Expand All @@ -61,8 +65,8 @@ public function provideFixCases(): \Generator
];

yield [
'<?php \DateTime::createFromFormat( "!Y-m-d", \'2022-02-11\');',
'<?php \DateTime::createFromFormat( "Y-m-d", \'2022-02-11\');',
'<?php \DATETIME::createFromFormat( "!Y-m-d", \'2022-02-11\');',
'<?php \DATETIME::createFromFormat( "Y-m-d", \'2022-02-11\');',
];

yield [
Expand Down Expand Up @@ -90,5 +94,32 @@ public function provideFixCases(): \Generator
yield [
'<?php A\DateTime::createFromFormat(\'Y-m-d\', \'2022-02-11\');',
];

yield [
'<?php A\DateTime::createFromFormat(\'Y-m-d\'."a", \'2022-02-11\');',
];

yield ['<?php \DateTime::createFromFormat(123, \'2022-02-11\');'];

yield [
'<?php namespace {
\DateTime::createFromFormat(\'!Y-m-d\', \'2022-02-11\');
}
namespace Bar {
class DateTime extends Foo {}
DateTime::createFromFormat(\'Y-m-d\', \'2022-02-11\');
}
',
'<?php namespace {
\DateTime::createFromFormat(\'Y-m-d\', \'2022-02-11\');
}
namespace Bar {
class DateTime extends Foo {}
DateTime::createFromFormat(\'Y-m-d\', \'2022-02-11\');
}
',
];
}
}

0 comments on commit bbabf9f

Please sign in to comment.