mirror of
https://github.com/rectorphp/rector.git
synced 2025-02-22 18:54:39 +01:00
commit
e299302591
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace Rector\PhpAttribute\PhpDocNode;
|
||||
|
||||
/**
|
||||
* @see https://wiki.php.net/rfc/attributes_v2
|
||||
*/
|
||||
trait PhpAttributePhpDocNodePrintTrait
|
||||
{
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -6,12 +6,12 @@ class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
function fn($value)
|
||||
function reservedFn($value)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
|
||||
fn(5);
|
||||
reservedFn(5);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -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');
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user