Merge pull request #3321 from rectorphp/todo-6

Resolving todos #6
This commit is contained in:
kodiakhq[bot] 2020-05-06 15:15:44 +00:00 committed by GitHub
commit e299302591
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 65 additions and 106 deletions

View File

@ -83,7 +83,9 @@ abstract class AbstractTagValueNode implements AttributeAwareNodeInterface, PhpD
public function __toString(): string
{
$items = $this->completeItemsQuotes($this->items);
$items = $this->filterOutMissingItems($items);
$items = $this->makeKeysExplicit($items);
return $this->printContentItems($items);
}
@ -119,6 +121,10 @@ abstract class AbstractTagValueNode implements AttributeAwareNodeInterface, PhpD
$json = Strings::replace($json, '#"#');
}
if ($this->originalContent !== null && $key !== null) {
$json = $this->quoteKeys($item, $key, $json, $this->originalContent);
}
return $keyPart . $json;
}
@ -146,8 +152,9 @@ abstract class AbstractTagValueNode implements AttributeAwareNodeInterface, PhpD
continue;
}
$arrayItemAsString = $this->printArrayItem($value, $key);
/** @var string $key */
$items[$key] = $this->printArrayItem($value, $key);
$items[$key] = $arrayItemAsString;
}
return sprintf(
@ -304,4 +311,19 @@ abstract class AbstractTagValueNode implements AttributeAwareNodeInterface, PhpD
// @see https://regex101.com/r/VgvK8C/3/
return sprintf('#%s="#', $escapedKey);
}
private function quoteKeys(array $item, string $key, string $json, string $originalContent): string
{
foreach (array_keys($item) as $itemKey) {
// @see https://regex101.com/r/V7nq5D/1
$quotedKeyPattern = '#' . $key . '={(.*?)?\"' . $itemKey . '\"(.*?)?}#';
$isKeyQuoted = (bool) Strings::match($originalContent, $quotedKeyPattern);
if (! $isKeyQuoted) {
continue;
}
$json = Strings::replace($json, '#([^\"])' . $itemKey . '([^\"])#', '$1"' . $itemKey . '"$2');
}
return $json;
}
}

View File

@ -9,7 +9,7 @@ use Doctrine\ORM\Mapping as ORM;
final class QuotesInNestedArray
{
/**
* @ORM\Column(options={"unsigned":true, "default":0})
* @ORM\Column(options={"unsigned"=true, "default"=0})
*/
private $loginCount;
}

View File

@ -5,7 +5,6 @@ declare(strict_types=1);
namespace Rector\BetterPhpDocParser\Tests\PhpDocParser\TagValueNodeReprint;
use Iterator;
use Nette\Utils\Strings;
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_\EntityTagValueNode;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_\TableTagValueNode;
@ -28,10 +27,6 @@ final class TagValueNodeReprintTest extends AbstractPhpDocInfoTest
*/
public function test(string $filePath, string $tagValueNodeClass): void
{
if (Strings::endsWith($filePath, 'QuotesInNestedArray.php')) {
$this->markTestSkipped('Quoting nested keys in annotations is in progress');
}
$this->doTestPrintedPhpDocInfo($filePath, $tagValueNodeClass);
}

View File

@ -4,6 +4,9 @@ declare(strict_types=1);
namespace Rector\PhpAttribute\PhpDocNode;
/**
* @see https://wiki.php.net/rfc/attributes_v2
*/
trait PhpAttributePhpDocNodePrintTrait
{
/**

View File

@ -6,6 +6,7 @@ namespace Rector\Php74\Rector\Function_;
use PhpParser\Node;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Function_;
use Rector\Core\Rector\AbstractRector;
@ -18,6 +19,19 @@ use Rector\Core\RectorDefinition\RectorDefinition;
*/
final class ReservedFnFunctionRector extends AbstractRector
{
/**
* @var string[]
*/
private $reservedNamesToNewOnes = [];
public function __construct(array $reservedNamesToNewOnes = [
// PHP 7.4
'fn' => 'f',
])
{
$this->reservedNamesToNewOnes = $reservedNamesToNewOnes;
}
public function getDefinition(): RectorDefinition
{
return new RectorDefinition('Change fn() function name, since it will be reserved keyword', [
@ -68,12 +82,20 @@ PHP
*/
public function refactor(Node $node): ?Node
{
if (! $this->isName($node, 'fn')) {
return null;
foreach ($this->reservedNamesToNewOnes as $reservedName => $newName) {
if (! $this->isName($node->name, $reservedName)) {
continue;
}
if ($node instanceof FuncCall) {
$node->name = new Name($newName);
} else {
$node->name = new Identifier($newName);
}
return $node;
}
$node->name = new Name('f');
return $node;
return null;
}
}

View File

@ -6,12 +6,12 @@ class SomeClass
{
public function run()
{
function fn($value)
function reservedFn($value)
{
return $value;
}
fn(5);
reservedFn(5);
}
}

View File

@ -5,7 +5,6 @@ declare(strict_types=1);
namespace Rector\Php74\Tests\Rector\Function_\ReservedFnFunctionRector;
use Iterator;
use PhpParser\Parser\Tokens;
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
use Rector\Php74\Rector\Function_\ReservedFnFunctionRector;
@ -16,10 +15,6 @@ final class ReservedFnFunctionRectorTest extends AbstractRectorTestCase
*/
public function test(string $file): void
{
if (defined(Tokens::class . '::T_FN')) {
$this->markTestSkipped('fn is reserved name in PHP 7.4');
}
$this->doTestFile($file);
}
@ -28,8 +23,15 @@ final class ReservedFnFunctionRectorTest extends AbstractRectorTestCase
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
protected function getRectorClass(): string
protected function getRectorsWithConfiguration(): array
{
return ReservedFnFunctionRector::class;
return [
ReservedFnFunctionRector::class => [
'$reservedNamesToNewOnes' => [
// for testing purposes of "fn" even on PHP 7.3-
'reservedFn' => 'f',
],
],
];
}
}

View File

@ -1,63 +0,0 @@
<?php
namespace Rector\RemovingStatic\Tests\Rector\Class_\PassFactoryToEntityRector\Fixture;
use Rector\RemovingStatic\Tests\Rector\Class_\PassFactoryToEntityRector\Source\TurnMeToService;
class SomeClass
{
public function run()
{
return new AnotherClass;
}
}
class AnotherClass
{
public function someFun()
{
return TurnMeToService::someStaticCall();
}
}
?>
-----
<?php
namespace Rector\RemovingStatic\Tests\Rector\Class_\PassFactoryToEntityRector\Fixture;
use Rector\RemovingStatic\Tests\Rector\Class_\PassFactoryToEntityRector\Source\TurnMeToService;
class SomeClass
{
/**
* @var \Rector\RemovingStatic\Tests\Rector\Class_\PassFactoryToEntityRector\Fixture\AnotherClassFactory
*/
private $anotherClassFactory;
public function __construct(\Rector\RemovingStatic\Tests\Rector\Class_\PassFactoryToEntityRector\Fixture\AnotherClassFactory $anotherClassFactory)
{
$this->anotherClassFactory = $anotherClassFactory;
}
public function run()
{
return $this->anotherClassFactory->create();
}
}
class AnotherClass
{
/**
* @var \Rector\RemovingStatic\Tests\Rector\Class_\PassFactoryToEntityRector\Source\TurnMeToService
*/
private $turnMeToService;
public function __construct(\Rector\RemovingStatic\Tests\Rector\Class_\PassFactoryToEntityRector\Source\TurnMeToService $turnMeToService)
{
$this->turnMeToService = $turnMeToService;
}
public function someFun()
{
return $this->turnMeToService->someStaticCall();
}
}
?>

View File

@ -19,23 +19,6 @@ final class PassFactoryToEntityRectorTest extends AbstractRectorTestCase
{
$this->doTestFile($file);
// test factory content
$this->assertFileExists($this->getTempPath() . '/AnotherClassFactory.php');
$this->assertFileEquals(
__DIR__ . '/Source/ExpectedAnotherClassFactory.php',
$this->getTempPath() . '/AnotherClassFactory.php'
);
}
/**
* @dataProvider provideDataMultipleArguments()
*/
public function testMultipleArguments(string $file): void
{
$this->markTestSkipped('Conflicting with previous test() for unknown reason. Works well separately');
$this->doTestFile($file);
// test factory content
$this->assertFileExists($this->getTempPath() . '/AnotherClassWithMoreArgumentsFactory.php');
$this->assertFileEquals(
@ -45,11 +28,6 @@ final class PassFactoryToEntityRectorTest extends AbstractRectorTestCase
}
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
public function provideDataMultipleArguments(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/FixtureWithMultipleArguments');
}