Updated Rector to commit 29562a6545

29562a6545 [CodingStyle] Remove custom code rule ManualJsonStringToJsonEncodeArrayRector, not much generic (#1398)
This commit is contained in:
Tomas Votruba 2021-12-05 21:47:27 +00:00
parent 4b0732e6b8
commit ea32bebe15
17 changed files with 21 additions and 748 deletions

View File

@ -3,7 +3,6 @@
declare (strict_types=1);
namespace RectorPrefix20211205;
use Rector\CodingStyle\Rector\Assign\ManualJsonStringToJsonEncodeArrayRector;
use Rector\CodingStyle\Rector\Assign\PHPStormVarAnnotationRector;
use Rector\CodingStyle\Rector\Assign\SplitDoubleAssignRector;
use Rector\CodingStyle\Rector\Catch_\CatchExceptionNameMatchingTypeRector;
@ -55,7 +54,6 @@ return static function (\Symfony\Component\DependencyInjection\Loader\Configurat
$services->set(\Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector::class);
$services->set(\Rector\CodingStyle\Rector\Encapsed\WrapEncapsedVariableInCurlyBracesRector::class);
$services->set(\Rector\CodingStyle\Rector\ClassMethod\NewlineBeforeNewAssignSetRector::class);
$services->set(\Rector\CodingStyle\Rector\Assign\ManualJsonStringToJsonEncodeArrayRector::class);
$services->set(\Rector\CodingStyle\Rector\Class_\AddArrayDefaultToArrayPropertyRector::class);
$services->set(\Rector\CodingStyle\Rector\Property\AddFalseDefaultToBoolPropertyRector::class);
$services->set(\Rector\CodingStyle\Rector\ClassMethod\MakeInheritedMethodVisibilitySameAsParentRector::class);

View File

@ -1,4 +1,4 @@
# 504 Rules Overview
# 503 Rules Overview
<br>
@ -12,7 +12,7 @@
- [CodeQuality](#codequality) (70)
- [CodingStyle](#codingstyle) (37)
- [CodingStyle](#codingstyle) (36)
- [Compatibility](#compatibility) (1)
@ -2130,31 +2130,6 @@ Make method visibility same as parent one
<br>
### ManualJsonStringToJsonEncodeArrayRector
Convert manual JSON string to JSON::encode array
- class: [`Rector\CodingStyle\Rector\Assign\ManualJsonStringToJsonEncodeArrayRector`](../rules/CodingStyle/Rector/Assign/ManualJsonStringToJsonEncodeArrayRector.php)
```diff
+use Nette\Utils\Json;
+
final class SomeClass
{
public function run()
{
- $someJsonAsString = '{"role_name":"admin","numberz":{"id":"10"}}';
+ $data = [
+ 'role_name' => 'admin',
+ 'numberz' => ['id' => 10]
+ ];
+ $someJsonAsString = Json::encode($data);
}
}
```
<br>
### NewlineAfterStatementRector
Add new line after statements to tidify code

View File

@ -1,52 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\CodingStyle\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\BinaryOp\Concat;
use PhpParser\Node\Scalar\String_;
use Rector\CodingStyle\ValueObject\ConcatStringAndPlaceholders;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class ConcatJoiner
{
/**
* @var string
*/
private $content = '';
/**
* @var Expr[]
*/
private $placeholderNodes = [];
/**
* Joins all String_ nodes to string.
* Returns that string + array of non-string nodes that were replaced by hash placeholders
*/
public function joinToStringAndPlaceholderNodes(\PhpParser\Node\Expr\BinaryOp\Concat $concat) : \Rector\CodingStyle\ValueObject\ConcatStringAndPlaceholders
{
$parentNode = $concat->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::PARENT_NODE);
if (!$parentNode instanceof \PhpParser\Node\Expr\BinaryOp\Concat) {
$this->reset();
}
$this->processConcatSide($concat->left);
$this->processConcatSide($concat->right);
return new \Rector\CodingStyle\ValueObject\ConcatStringAndPlaceholders($this->content, $this->placeholderNodes);
}
private function reset() : void
{
$this->content = '';
$this->placeholderNodes = [];
}
private function processConcatSide(\PhpParser\Node\Expr $expr) : void
{
if ($expr instanceof \PhpParser\Node\Scalar\String_) {
$this->content .= $expr->value;
} elseif ($expr instanceof \PhpParser\Node\Expr\BinaryOp\Concat) {
$this->joinToStringAndPlaceholderNodes($expr);
} else {
$objectHash = '____' . \spl_object_hash($expr) . '____';
$this->placeholderNodes[$objectHash] = $expr;
$this->content .= $objectHash;
}
}
}

View File

@ -1,55 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\CodingStyle\Node;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\BinaryOp\Concat;
use Rector\Core\PhpParser\Comparing\NodeComparator;
use RectorPrefix20211205\Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
final class ConcatManipulator
{
/**
* @readonly
* @var \Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser
*/
private $simpleCallableNodeTraverser;
/**
* @readonly
* @var \Rector\Core\PhpParser\Comparing\NodeComparator
*/
private $nodeComparator;
public function __construct(\RectorPrefix20211205\Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser $simpleCallableNodeTraverser, \Rector\Core\PhpParser\Comparing\NodeComparator $nodeComparator)
{
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
$this->nodeComparator = $nodeComparator;
}
public function getFirstConcatItem(\PhpParser\Node\Expr\BinaryOp\Concat $concat) : \PhpParser\Node\Expr
{
// go to the deep, until there is no concat
while ($concat->left instanceof \PhpParser\Node\Expr\BinaryOp\Concat) {
$concat = $concat->left;
}
return $concat->left;
}
public function removeFirstItemFromConcat(\PhpParser\Node\Expr\BinaryOp\Concat $concat) : \PhpParser\Node\Expr
{
// just 2 items, return right one
if (!$concat->left instanceof \PhpParser\Node\Expr\BinaryOp\Concat) {
return $concat->right;
}
$newConcat = clone $concat;
$firstConcatItem = $this->getFirstConcatItem($concat);
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($newConcat, function (\PhpParser\Node $node) use($firstConcatItem) : ?Expr {
if (!$node instanceof \PhpParser\Node\Expr\BinaryOp\Concat) {
return null;
}
if (!$this->nodeComparator->areNodesEqual($node->left, $firstConcatItem)) {
return null;
}
return $node->right;
});
return $newConcat;
}
}

View File

@ -1,54 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\CodingStyle\NodeAnalyzer;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Scalar\String_;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\NodeNameResolver\NodeNameResolver;
final class ImplodeAnalyzer
{
/**
* @readonly
* @var \Rector\NodeNameResolver\NodeNameResolver
*/
private $nodeNameResolver;
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(\Rector\NodeNameResolver\NodeNameResolver $nodeNameResolver, \Rector\Core\NodeAnalyzer\ArgsAnalyzer $argsAnalyzer)
{
$this->nodeNameResolver = $nodeNameResolver;
$this->argsAnalyzer = $argsAnalyzer;
}
/**
* Matches: "implode('","', $items)"
*/
public function isImplodeToJson(\PhpParser\Node\Expr $expr) : bool
{
if (!$expr instanceof \PhpParser\Node\Expr\FuncCall) {
return \false;
}
if (!$this->nodeNameResolver->isName($expr, 'implode')) {
return \false;
}
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($expr->args, 1)) {
return \false;
}
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($expr->args, 0)) {
return \false;
}
/** @var Arg $firstArg */
$firstArg = $expr->args[0];
$firstArgumentValue = $firstArg->value;
if (!$firstArgumentValue instanceof \PhpParser\Node\Scalar\String_) {
return \true;
}
return $firstArgumentValue->value === '","';
}
}

View File

@ -1,92 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\CodingStyle\NodeFactory;
use RectorPrefix20211205\Nette\Utils\Json;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Scalar\String_;
use Rector\CodingStyle\NodeAnalyzer\ImplodeAnalyzer;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Node\NodeFactory;
use RectorPrefix20211205\Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
final class JsonArrayFactory
{
/**
* @readonly
* @var \Rector\Core\PhpParser\Node\NodeFactory
*/
private $nodeFactory;
/**
* @readonly
* @var \Rector\CodingStyle\NodeAnalyzer\ImplodeAnalyzer
*/
private $implodeAnalyzer;
/**
* @readonly
* @var \Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser
*/
private $simpleCallableNodeTraverser;
public function __construct(\Rector\Core\PhpParser\Node\NodeFactory $nodeFactory, \Rector\CodingStyle\NodeAnalyzer\ImplodeAnalyzer $implodeAnalyzer, \RectorPrefix20211205\Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser $simpleCallableNodeTraverser)
{
$this->nodeFactory = $nodeFactory;
$this->implodeAnalyzer = $implodeAnalyzer;
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
}
public function createFromJsonString(string $stringValue) : \PhpParser\Node\Expr\Array_
{
$array = \RectorPrefix20211205\Nette\Utils\Json::decode($stringValue, \RectorPrefix20211205\Nette\Utils\Json::FORCE_ARRAY);
return $this->nodeFactory->createArray($array);
}
/**
* @param Expr[] $placeholderNodes
*/
public function createFromJsonStringAndPlaceholders(string $jsonString, array $placeholderNodes) : \PhpParser\Node\Expr\Array_
{
$jsonArray = $this->createFromJsonString($jsonString);
$this->replaceNodeObjectHashPlaceholdersWithNodes($jsonArray, $placeholderNodes);
return $jsonArray;
}
/**
* @param Expr[] $placeholderNodes
*/
private function replaceNodeObjectHashPlaceholdersWithNodes(\PhpParser\Node\Expr\Array_ $array, array $placeholderNodes) : void
{
// traverse and replace placeholder by original nodes
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($array, function (\PhpParser\Node $node) use($placeholderNodes) : ?Expr {
if ($node instanceof \PhpParser\Node\Expr\Array_ && \count($node->items) === 1) {
$onlyItem = $node->items[0];
if (!$onlyItem instanceof \PhpParser\Node\Expr\ArrayItem) {
throw new \Rector\Core\Exception\ShouldNotHappenException();
}
$placeholderNode = $this->matchPlaceholderNode($onlyItem->value, $placeholderNodes);
if ($placeholderNode instanceof \PhpParser\Node\Expr && $this->implodeAnalyzer->isImplodeToJson($placeholderNode)) {
/**
* @var FuncCall $placeholderNode
* @var Arg $firstArg
*
* Arg check already on $this->implodeAnalyzer->isImplodeToJson() above
*/
$firstArg = $placeholderNode->args[1];
return $firstArg->value;
}
}
return $this->matchPlaceholderNode($node, $placeholderNodes);
});
}
/**
* @param Expr[] $placeholderNodes
*/
private function matchPlaceholderNode(\PhpParser\Node $node, array $placeholderNodes) : ?\PhpParser\Node\Expr
{
if (!$node instanceof \PhpParser\Node\Scalar\String_) {
return null;
}
return $placeholderNodes[$node->value] ?? null;
}
}

View File

@ -1,41 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\CodingStyle\NodeFactory;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Variable;
use Rector\Core\PhpParser\Node\NodeFactory;
/**
* Creates + adds
*
* $jsonData = ['...'];
* $json = Nette\Utils\Json::encode($jsonData);
*/
final class JsonEncodeStaticCallFactory
{
/**
* @readonly
* @var \Rector\Core\PhpParser\Node\NodeFactory
*/
private $nodeFactory;
public function __construct(\Rector\Core\PhpParser\Node\NodeFactory $nodeFactory)
{
$this->nodeFactory = $nodeFactory;
}
/**
* Creates + adds
*
* $jsonData = ['...'];
* $json = Nette\Utils\Json::encode($jsonData);
*/
public function createFromArray(\PhpParser\Node\Expr $assignExpr, \PhpParser\Node\Expr\Array_ $jsonArray) : \PhpParser\Node\Expr\Assign
{
$jsonDataAssign = new \PhpParser\Node\Expr\Assign($assignExpr, $jsonArray);
$jsonDataVariable = new \PhpParser\Node\Expr\Variable('jsonData');
$jsonDataAssign->expr = $this->nodeFactory->createStaticCall('Nette\\Utils\\Json', 'encode', [$jsonDataVariable]);
return $jsonDataAssign;
}
}

View File

@ -1,265 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\CodingStyle\Rector\Assign;
use RectorPrefix20211205\Nette\Utils\Json;
use RectorPrefix20211205\Nette\Utils\JsonException;
use RectorPrefix20211205\Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\AssignOp\Concat as ConcatAssign;
use PhpParser\Node\Expr\BinaryOp\Concat;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Expression;
use PHPStan\Reflection\ReflectionProvider;
use Rector\CodingStyle\Node\ConcatJoiner;
use Rector\CodingStyle\Node\ConcatManipulator;
use Rector\CodingStyle\NodeFactory\JsonArrayFactory;
use Rector\CodingStyle\NodeFactory\JsonEncodeStaticCallFactory;
use Rector\CodingStyle\ValueObject\ConcatExpressionJoinData;
use Rector\CodingStyle\ValueObject\NodeToRemoveAndConcatItem;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\Util\StringUtils;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\CodingStyle\Rector\Assign\ManualJsonStringToJsonEncodeArrayRector\ManualJsonStringToJsonEncodeArrayRectorTest
*/
final class ManualJsonStringToJsonEncodeArrayRector extends \Rector\Core\Rector\AbstractRector
{
/**
* @var string
* @see https://regex101.com/r/85PZHm/1
*/
private const UNQUOTED_OBJECT_HASH_REGEX = '#(?<start>[^\\"])(?<hash>____\\w+____)#';
/**
* @var string
* @see https://regex101.com/r/jdJ6n9/1
*/
private const JSON_STRING_REGEX = '#{(.*?\\:.*?)}#s';
/**
* @var string
*/
private const JSON_DATA = 'jsonData';
/**
* @readonly
* @var \Rector\CodingStyle\Node\ConcatJoiner
*/
private $concatJoiner;
/**
* @readonly
* @var \Rector\CodingStyle\Node\ConcatManipulator
*/
private $concatManipulator;
/**
* @readonly
* @var \Rector\CodingStyle\NodeFactory\JsonEncodeStaticCallFactory
*/
private $jsonEncodeStaticCallFactory;
/**
* @readonly
* @var \Rector\CodingStyle\NodeFactory\JsonArrayFactory
*/
private $jsonArrayFactory;
/**
* @readonly
* @var \PHPStan\Reflection\ReflectionProvider
*/
private $reflectionProvider;
public function __construct(\Rector\CodingStyle\Node\ConcatJoiner $concatJoiner, \Rector\CodingStyle\Node\ConcatManipulator $concatManipulator, \Rector\CodingStyle\NodeFactory\JsonEncodeStaticCallFactory $jsonEncodeStaticCallFactory, \Rector\CodingStyle\NodeFactory\JsonArrayFactory $jsonArrayFactory, \PHPStan\Reflection\ReflectionProvider $reflectionProvider)
{
$this->concatJoiner = $concatJoiner;
$this->concatManipulator = $concatManipulator;
$this->jsonEncodeStaticCallFactory = $jsonEncodeStaticCallFactory;
$this->jsonArrayFactory = $jsonArrayFactory;
$this->reflectionProvider = $reflectionProvider;
}
public function getRuleDefinition() : \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
{
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition('Convert manual JSON string to JSON::encode array', [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample(<<<'CODE_SAMPLE'
final class SomeClass
{
public function run()
{
$someJsonAsString = '{"role_name":"admin","numberz":{"id":"10"}}';
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use Nette\Utils\Json;
final class SomeClass
{
public function run()
{
$data = [
'role_name' => 'admin',
'numberz' => ['id' => 10]
];
$someJsonAsString = Json::encode($data);
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [\PhpParser\Node\Expr\Assign::class];
}
/**
* @param Assign $node
*/
public function refactor(\PhpParser\Node $node) : ?\PhpParser\Node
{
if ($node->expr instanceof \PhpParser\Node\Scalar\String_) {
$stringValue = $node->expr->value;
// A. full json string
$isJsonString = $this->isJsonString($stringValue);
if ($isJsonString) {
$jsonArray = $this->jsonArrayFactory->createFromJsonString($stringValue);
$jsonEncodeAssign = $this->createJsonEncodeAssign($node->var, $jsonArray);
$jsonDataVariable = new \PhpParser\Node\Expr\Variable(self::JSON_DATA);
$jsonDataAssign = new \PhpParser\Node\Expr\Assign($jsonDataVariable, $jsonArray);
$this->nodesToAddCollector->addNodeBeforeNode($jsonDataAssign, $node);
return $jsonEncodeAssign;
}
// B. just start of a json? join with all the strings that concat so same variable
$concatExpressionJoinData = $this->collectContentAndPlaceholderNodesFromNextExpressions($node);
$stringValue .= $concatExpressionJoinData->getString();
return $this->removeNodesAndCreateJsonEncodeFromStringValue($concatExpressionJoinData->getNodesToRemove(), $stringValue, $concatExpressionJoinData->getPlaceholdersToNodes(), $node);
}
if ($node->expr instanceof \PhpParser\Node\Expr\BinaryOp\Concat) {
// process only first concat
$parentNode = $node->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::PARENT_NODE);
if ($parentNode instanceof \PhpParser\Node\Expr\BinaryOp\Concat) {
return null;
}
$concatStringAndPlaceholders = $this->concatJoiner->joinToStringAndPlaceholderNodes($node->expr);
// B. just start of a json? join with all the strings that concat so same variable
$concatExpressionJoinData = $this->collectContentAndPlaceholderNodesFromNextExpressions($node);
$placeholderNodes = \array_merge($concatStringAndPlaceholders->getPlaceholderNodes(), $concatExpressionJoinData->getPlaceholdersToNodes());
$stringValue = $concatStringAndPlaceholders->getContent();
$stringValue .= $concatExpressionJoinData->getString();
return $this->removeNodesAndCreateJsonEncodeFromStringValue($concatExpressionJoinData->getNodesToRemove(), $stringValue, $placeholderNodes, $node);
}
return null;
}
private function isJsonString(string $stringValue) : bool
{
if (!\Rector\Core\Util\StringUtils::isMatch($stringValue, self::JSON_STRING_REGEX)) {
return \false;
}
try {
return (bool) \RectorPrefix20211205\Nette\Utils\Json::decode($stringValue, \RectorPrefix20211205\Nette\Utils\Json::FORCE_ARRAY);
} catch (\RectorPrefix20211205\Nette\Utils\JsonException $exception) {
return \false;
}
}
private function collectContentAndPlaceholderNodesFromNextExpressions(\PhpParser\Node\Expr\Assign $assign) : \Rector\CodingStyle\ValueObject\ConcatExpressionJoinData
{
$concatExpressionJoinData = new \Rector\CodingStyle\ValueObject\ConcatExpressionJoinData();
$currentNode = $assign;
while ($nextExprAndConcatItem = $this->matchNextExprAssignConcatToSameVariable($assign->var, $currentNode)) {
$concatItemNode = $nextExprAndConcatItem->getConcatItemNode();
if ($concatItemNode instanceof \PhpParser\Node\Scalar\String_) {
$concatExpressionJoinData->addString($concatItemNode->value);
} elseif ($concatItemNode instanceof \PhpParser\Node\Expr\BinaryOp\Concat) {
$joinToStringAndPlaceholderNodes = $this->concatJoiner->joinToStringAndPlaceholderNodes($concatItemNode);
$content = $joinToStringAndPlaceholderNodes->getContent();
$concatExpressionJoinData->addString($content);
foreach ($joinToStringAndPlaceholderNodes->getPlaceholderNodes() as $placeholder => $expr) {
/** @var string $placeholder */
$concatExpressionJoinData->addPlaceholderToNode($placeholder, $expr);
}
} elseif ($concatItemNode instanceof \PhpParser\Node\Expr) {
$objectHash = '____' . \spl_object_hash($concatItemNode) . '____';
$concatExpressionJoinData->addString($objectHash);
$concatExpressionJoinData->addPlaceholderToNode($objectHash, $concatItemNode);
}
$concatExpressionJoinData->addNodeToRemove($nextExprAndConcatItem->getRemovedExpr());
// jump to next one
$currentNode = $this->getNextExpression($currentNode);
if (!$currentNode instanceof \PhpParser\Node) {
return $concatExpressionJoinData;
}
}
return $concatExpressionJoinData;
}
/**
* @param Node[] $nodesToRemove
* @param Expr[] $placeholderNodes
*/
private function removeNodesAndCreateJsonEncodeFromStringValue(array $nodesToRemove, string $stringValue, array $placeholderNodes, \PhpParser\Node\Expr\Assign $assign) : ?\PhpParser\Node\Expr\Assign
{
$stringValue = \RectorPrefix20211205\Nette\Utils\Strings::replace($stringValue, self::UNQUOTED_OBJECT_HASH_REGEX, '$1"$2"');
if (!$this->isJsonString($stringValue)) {
return null;
}
$this->removeNodes($nodesToRemove);
$jsonArray = $this->jsonArrayFactory->createFromJsonStringAndPlaceholders($stringValue, $placeholderNodes);
$jsonDataVariable = new \PhpParser\Node\Expr\Variable(self::JSON_DATA);
$jsonDataAssign = new \PhpParser\Node\Expr\Assign($jsonDataVariable, $jsonArray);
$this->nodesToAddCollector->addNodeBeforeNode($jsonDataAssign, $assign);
return $this->createJsonEncodeAssign($assign->var, $jsonArray);
}
private function matchNextExprAssignConcatToSameVariable(\PhpParser\Node\Expr $expr, \PhpParser\Node $currentNode) : ?\Rector\CodingStyle\ValueObject\NodeToRemoveAndConcatItem
{
$nextExpression = $this->getNextExpression($currentNode);
if (!$nextExpression instanceof \PhpParser\Node\Stmt\Expression) {
return null;
}
$nextExpressionNode = $nextExpression->expr;
if ($nextExpressionNode instanceof \PhpParser\Node\Expr\AssignOp\Concat) {
// is assign to same variable?
if (!$this->nodeComparator->areNodesEqual($expr, $nextExpressionNode->var)) {
return null;
}
return new \Rector\CodingStyle\ValueObject\NodeToRemoveAndConcatItem($nextExpressionNode, $nextExpressionNode->expr);
}
// $value = $value . '...';
if ($nextExpressionNode instanceof \PhpParser\Node\Expr\Assign) {
if (!$nextExpressionNode->expr instanceof \PhpParser\Node\Expr\BinaryOp\Concat) {
return null;
}
// is assign to same variable?
if (!$this->nodeComparator->areNodesEqual($expr, $nextExpressionNode->var)) {
return null;
}
$firstConcatItem = $this->concatManipulator->getFirstConcatItem($nextExpressionNode->expr);
// is the first concat the same variable
if (!$this->nodeComparator->areNodesEqual($expr, $firstConcatItem)) {
return null;
}
// return all but first node
$allButFirstConcatItem = $this->concatManipulator->removeFirstItemFromConcat($nextExpressionNode->expr);
return new \Rector\CodingStyle\ValueObject\NodeToRemoveAndConcatItem($nextExpressionNode, $allButFirstConcatItem);
}
return null;
}
private function getNextExpression(\PhpParser\Node $node) : ?\PhpParser\Node
{
$currentExpression = $node->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::CURRENT_STATEMENT);
if (!$currentExpression instanceof \PhpParser\Node\Stmt\Expression) {
return null;
}
return $currentExpression->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::NEXT_NODE);
}
private function createJsonEncodeAssign(\PhpParser\Node\Expr $assignExpr, \PhpParser\Node\Expr\Array_ $jsonArray) : \PhpParser\Node\Expr\Assign
{
if ($this->reflectionProvider->hasClass('Nette\\Utils\\Json')) {
return $this->jsonEncodeStaticCallFactory->createFromArray($assignExpr, $jsonArray);
}
$jsonDataAssign = new \PhpParser\Node\Expr\Assign($assignExpr, $jsonArray);
$jsonDataVariable = new \PhpParser\Node\Expr\Variable(self::JSON_DATA);
$jsonDataAssign->expr = $this->nodeFactory->createFuncCall('json_encode', [$jsonDataVariable]);
return $jsonDataAssign;
}
}

View File

@ -1,52 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\CodingStyle\ValueObject;
use PhpParser\Node;
use PhpParser\Node\Expr;
final class ConcatExpressionJoinData
{
/**
* @var string[]
*/
private $values = [];
/**
* @var Node[]
*/
private $nodesToRemove = [];
/**
* @var Expr[]
*/
private $placeholdersToNodes = [];
public function addString(string $value) : void
{
$this->values[] = $value;
}
public function addNodeToRemove(\PhpParser\Node $node) : void
{
$this->nodesToRemove[] = $node;
}
public function getString() : string
{
return \implode('', $this->values);
}
/**
* @return Node[]
*/
public function getNodesToRemove() : array
{
return $this->nodesToRemove;
}
public function addPlaceholderToNode(string $objectHash, \PhpParser\Node\Expr $expr) : void
{
$this->placeholdersToNodes[$objectHash] = $expr;
}
/**
* @return Expr[]
*/
public function getPlaceholdersToNodes() : array
{
return $this->placeholdersToNodes;
}
}

View File

@ -1,38 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\CodingStyle\ValueObject;
use PhpParser\Node\Expr;
final class ConcatStringAndPlaceholders
{
/**
* @readonly
* @var string
*/
private $content;
/**
* @var \PhpParser\Node\Expr[]
* @readonly
*/
private $placeholderNodes;
/**
* @param Expr[] $placeholderNodes
*/
public function __construct(string $content, array $placeholderNodes)
{
$this->content = $content;
$this->placeholderNodes = $placeholderNodes;
}
public function getContent() : string
{
return $this->content;
}
/**
* @return Expr[]
*/
public function getPlaceholderNodes() : array
{
return $this->placeholderNodes;
}
}

View File

@ -1,33 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\CodingStyle\ValueObject;
use PhpParser\Node;
use PhpParser\Node\Expr;
final class NodeToRemoveAndConcatItem
{
/**
* @readonly
* @var \PhpParser\Node\Expr
*/
private $removedExpr;
/**
* @readonly
* @var \PhpParser\Node
*/
private $concatItemNode;
public function __construct(\PhpParser\Node\Expr $removedExpr, \PhpParser\Node $concatItemNode)
{
$this->removedExpr = $removedExpr;
$this->concatItemNode = $concatItemNode;
}
public function getRemovedExpr() : \PhpParser\Node\Expr
{
return $this->removedExpr;
}
public function getConcatItemNode() : \PhpParser\Node
{
return $this->concatItemNode;
}
}

View File

@ -16,11 +16,11 @@ final class VersionResolver
/**
* @var string
*/
public const PACKAGE_VERSION = 'f99d8792f6633450b093dde042fd4e3f12879168';
public const PACKAGE_VERSION = '29562a6545a99f893416d5ffed3767d30f41f1a6';
/**
* @var string
*/
public const RELEASE_DATE = '2021-12-05 21:06:53';
public const RELEASE_DATE = '2021-12-05 22:34:03';
public static function resolvePackageVersion() : string
{
$process = new \RectorPrefix20211205\Symfony\Component\Process\Process(['git', 'log', '--pretty="%H"', '-n1', 'HEAD'], __DIR__);

2
vendor/autoload.php vendored
View File

@ -4,4 +4,4 @@
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit439ed022b1f73ae246b1b5414e67b710::getLoader();
return ComposerAutoloaderInitc0bfbfcdeea8e80344d153233076feea::getLoader();

View File

@ -1548,16 +1548,10 @@ return array(
'Rector\\CodingStyle\\Contract\\ClassNameImport\\ClassNameImportSkipVoterInterface' => $baseDir . '/rules/CodingStyle/Contract/ClassNameImport/ClassNameImportSkipVoterInterface.php',
'Rector\\CodingStyle\\Enum\\PreferenceSelfThis' => $baseDir . '/rules/CodingStyle/Enum/PreferenceSelfThis.php',
'Rector\\CodingStyle\\Naming\\ClassNaming' => $baseDir . '/rules/CodingStyle/Naming/ClassNaming.php',
'Rector\\CodingStyle\\NodeAnalyzer\\ImplodeAnalyzer' => $baseDir . '/rules/CodingStyle/NodeAnalyzer/ImplodeAnalyzer.php',
'Rector\\CodingStyle\\NodeAnalyzer\\SpreadVariablesCollector' => $baseDir . '/rules/CodingStyle/NodeAnalyzer/SpreadVariablesCollector.php',
'Rector\\CodingStyle\\NodeAnalyzer\\UseImportNameMatcher' => $baseDir . '/rules/CodingStyle/NodeAnalyzer/UseImportNameMatcher.php',
'Rector\\CodingStyle\\NodeFactory\\ArrayCallableToMethodCallFactory' => $baseDir . '/rules/CodingStyle/NodeFactory/ArrayCallableToMethodCallFactory.php',
'Rector\\CodingStyle\\NodeFactory\\JsonArrayFactory' => $baseDir . '/rules/CodingStyle/NodeFactory/JsonArrayFactory.php',
'Rector\\CodingStyle\\NodeFactory\\JsonEncodeStaticCallFactory' => $baseDir . '/rules/CodingStyle/NodeFactory/JsonEncodeStaticCallFactory.php',
'Rector\\CodingStyle\\Node\\ConcatJoiner' => $baseDir . '/rules/CodingStyle/Node/ConcatJoiner.php',
'Rector\\CodingStyle\\Node\\ConcatManipulator' => $baseDir . '/rules/CodingStyle/Node/ConcatManipulator.php',
'Rector\\CodingStyle\\Node\\NameImporter' => $baseDir . '/rules/CodingStyle/Node/NameImporter.php',
'Rector\\CodingStyle\\Rector\\Assign\\ManualJsonStringToJsonEncodeArrayRector' => $baseDir . '/rules/CodingStyle/Rector/Assign/ManualJsonStringToJsonEncodeArrayRector.php',
'Rector\\CodingStyle\\Rector\\Assign\\PHPStormVarAnnotationRector' => $baseDir . '/rules/CodingStyle/Rector/Assign/PHPStormVarAnnotationRector.php',
'Rector\\CodingStyle\\Rector\\Assign\\SplitDoubleAssignRector' => $baseDir . '/rules/CodingStyle/Rector/Assign/SplitDoubleAssignRector.php',
'Rector\\CodingStyle\\Rector\\Catch_\\CatchExceptionNameMatchingTypeRector' => $baseDir . '/rules/CodingStyle/Rector/Catch_/CatchExceptionNameMatchingTypeRector.php',
@ -1596,9 +1590,6 @@ return array(
'Rector\\CodingStyle\\Rector\\Use_\\SeparateMultiUseImportsRector' => $baseDir . '/rules/CodingStyle/Rector/Use_/SeparateMultiUseImportsRector.php',
'Rector\\CodingStyle\\Reflection\\VendorLocationDetector' => $baseDir . '/rules/CodingStyle/Reflection/VendorLocationDetector.php',
'Rector\\CodingStyle\\TypeAnalyzer\\IterableTypeAnalyzer' => $baseDir . '/rules/CodingStyle/TypeAnalyzer/IterableTypeAnalyzer.php',
'Rector\\CodingStyle\\ValueObject\\ConcatExpressionJoinData' => $baseDir . '/rules/CodingStyle/ValueObject/ConcatExpressionJoinData.php',
'Rector\\CodingStyle\\ValueObject\\ConcatStringAndPlaceholders' => $baseDir . '/rules/CodingStyle/ValueObject/ConcatStringAndPlaceholders.php',
'Rector\\CodingStyle\\ValueObject\\NodeToRemoveAndConcatItem' => $baseDir . '/rules/CodingStyle/ValueObject/NodeToRemoveAndConcatItem.php',
'Rector\\CodingStyle\\ValueObject\\ObjectMagicMethods' => $baseDir . '/rules/CodingStyle/ValueObject/ObjectMagicMethods.php',
'Rector\\CodingStyle\\ValueObject\\ReturnArrayClassMethodToYield' => $baseDir . '/rules/CodingStyle/ValueObject/ReturnArrayClassMethodToYield.php',
'Rector\\Comments\\CommentRemover' => $baseDir . '/packages/Comments/CommentRemover.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit439ed022b1f73ae246b1b5414e67b710
class ComposerAutoloaderInitc0bfbfcdeea8e80344d153233076feea
{
private static $loader;
@ -22,15 +22,15 @@ class ComposerAutoloaderInit439ed022b1f73ae246b1b5414e67b710
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit439ed022b1f73ae246b1b5414e67b710', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInitc0bfbfcdeea8e80344d153233076feea', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
spl_autoload_unregister(array('ComposerAutoloaderInit439ed022b1f73ae246b1b5414e67b710', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInitc0bfbfcdeea8e80344d153233076feea', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit439ed022b1f73ae246b1b5414e67b710::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInitc0bfbfcdeea8e80344d153233076feea::getInitializer($loader));
} else {
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
@ -42,19 +42,19 @@ class ComposerAutoloaderInit439ed022b1f73ae246b1b5414e67b710
$loader->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit439ed022b1f73ae246b1b5414e67b710::$files;
$includeFiles = Composer\Autoload\ComposerStaticInitc0bfbfcdeea8e80344d153233076feea::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire439ed022b1f73ae246b1b5414e67b710($fileIdentifier, $file);
composerRequirec0bfbfcdeea8e80344d153233076feea($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequire439ed022b1f73ae246b1b5414e67b710($fileIdentifier, $file)
function composerRequirec0bfbfcdeea8e80344d153233076feea($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInit439ed022b1f73ae246b1b5414e67b710
class ComposerStaticInitc0bfbfcdeea8e80344d153233076feea
{
public static $files = array (
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
@ -1945,16 +1945,10 @@ class ComposerStaticInit439ed022b1f73ae246b1b5414e67b710
'Rector\\CodingStyle\\Contract\\ClassNameImport\\ClassNameImportSkipVoterInterface' => __DIR__ . '/../..' . '/rules/CodingStyle/Contract/ClassNameImport/ClassNameImportSkipVoterInterface.php',
'Rector\\CodingStyle\\Enum\\PreferenceSelfThis' => __DIR__ . '/../..' . '/rules/CodingStyle/Enum/PreferenceSelfThis.php',
'Rector\\CodingStyle\\Naming\\ClassNaming' => __DIR__ . '/../..' . '/rules/CodingStyle/Naming/ClassNaming.php',
'Rector\\CodingStyle\\NodeAnalyzer\\ImplodeAnalyzer' => __DIR__ . '/../..' . '/rules/CodingStyle/NodeAnalyzer/ImplodeAnalyzer.php',
'Rector\\CodingStyle\\NodeAnalyzer\\SpreadVariablesCollector' => __DIR__ . '/../..' . '/rules/CodingStyle/NodeAnalyzer/SpreadVariablesCollector.php',
'Rector\\CodingStyle\\NodeAnalyzer\\UseImportNameMatcher' => __DIR__ . '/../..' . '/rules/CodingStyle/NodeAnalyzer/UseImportNameMatcher.php',
'Rector\\CodingStyle\\NodeFactory\\ArrayCallableToMethodCallFactory' => __DIR__ . '/../..' . '/rules/CodingStyle/NodeFactory/ArrayCallableToMethodCallFactory.php',
'Rector\\CodingStyle\\NodeFactory\\JsonArrayFactory' => __DIR__ . '/../..' . '/rules/CodingStyle/NodeFactory/JsonArrayFactory.php',
'Rector\\CodingStyle\\NodeFactory\\JsonEncodeStaticCallFactory' => __DIR__ . '/../..' . '/rules/CodingStyle/NodeFactory/JsonEncodeStaticCallFactory.php',
'Rector\\CodingStyle\\Node\\ConcatJoiner' => __DIR__ . '/../..' . '/rules/CodingStyle/Node/ConcatJoiner.php',
'Rector\\CodingStyle\\Node\\ConcatManipulator' => __DIR__ . '/../..' . '/rules/CodingStyle/Node/ConcatManipulator.php',
'Rector\\CodingStyle\\Node\\NameImporter' => __DIR__ . '/../..' . '/rules/CodingStyle/Node/NameImporter.php',
'Rector\\CodingStyle\\Rector\\Assign\\ManualJsonStringToJsonEncodeArrayRector' => __DIR__ . '/../..' . '/rules/CodingStyle/Rector/Assign/ManualJsonStringToJsonEncodeArrayRector.php',
'Rector\\CodingStyle\\Rector\\Assign\\PHPStormVarAnnotationRector' => __DIR__ . '/../..' . '/rules/CodingStyle/Rector/Assign/PHPStormVarAnnotationRector.php',
'Rector\\CodingStyle\\Rector\\Assign\\SplitDoubleAssignRector' => __DIR__ . '/../..' . '/rules/CodingStyle/Rector/Assign/SplitDoubleAssignRector.php',
'Rector\\CodingStyle\\Rector\\Catch_\\CatchExceptionNameMatchingTypeRector' => __DIR__ . '/../..' . '/rules/CodingStyle/Rector/Catch_/CatchExceptionNameMatchingTypeRector.php',
@ -1993,9 +1987,6 @@ class ComposerStaticInit439ed022b1f73ae246b1b5414e67b710
'Rector\\CodingStyle\\Rector\\Use_\\SeparateMultiUseImportsRector' => __DIR__ . '/../..' . '/rules/CodingStyle/Rector/Use_/SeparateMultiUseImportsRector.php',
'Rector\\CodingStyle\\Reflection\\VendorLocationDetector' => __DIR__ . '/../..' . '/rules/CodingStyle/Reflection/VendorLocationDetector.php',
'Rector\\CodingStyle\\TypeAnalyzer\\IterableTypeAnalyzer' => __DIR__ . '/../..' . '/rules/CodingStyle/TypeAnalyzer/IterableTypeAnalyzer.php',
'Rector\\CodingStyle\\ValueObject\\ConcatExpressionJoinData' => __DIR__ . '/../..' . '/rules/CodingStyle/ValueObject/ConcatExpressionJoinData.php',
'Rector\\CodingStyle\\ValueObject\\ConcatStringAndPlaceholders' => __DIR__ . '/../..' . '/rules/CodingStyle/ValueObject/ConcatStringAndPlaceholders.php',
'Rector\\CodingStyle\\ValueObject\\NodeToRemoveAndConcatItem' => __DIR__ . '/../..' . '/rules/CodingStyle/ValueObject/NodeToRemoveAndConcatItem.php',
'Rector\\CodingStyle\\ValueObject\\ObjectMagicMethods' => __DIR__ . '/../..' . '/rules/CodingStyle/ValueObject/ObjectMagicMethods.php',
'Rector\\CodingStyle\\ValueObject\\ReturnArrayClassMethodToYield' => __DIR__ . '/../..' . '/rules/CodingStyle/ValueObject/ReturnArrayClassMethodToYield.php',
'Rector\\Comments\\CommentRemover' => __DIR__ . '/../..' . '/packages/Comments/CommentRemover.php',
@ -3798,9 +3789,9 @@ class ComposerStaticInit439ed022b1f73ae246b1b5414e67b710
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit439ed022b1f73ae246b1b5414e67b710::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit439ed022b1f73ae246b1b5414e67b710::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit439ed022b1f73ae246b1b5414e67b710::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInitc0bfbfcdeea8e80344d153233076feea::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitc0bfbfcdeea8e80344d153233076feea::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitc0bfbfcdeea8e80344d153233076feea::$classMap;
}, null, ClassLoader::class);
}

View File

@ -12,8 +12,8 @@ if (!class_exists('GenerateChangelogCommand', false) && !interface_exists('Gener
if (!class_exists('AutoloadIncluder', false) && !interface_exists('AutoloadIncluder', false) && !trait_exists('AutoloadIncluder', false)) {
spl_autoload_call('RectorPrefix20211205\AutoloadIncluder');
}
if (!class_exists('ComposerAutoloaderInit439ed022b1f73ae246b1b5414e67b710', false) && !interface_exists('ComposerAutoloaderInit439ed022b1f73ae246b1b5414e67b710', false) && !trait_exists('ComposerAutoloaderInit439ed022b1f73ae246b1b5414e67b710', false)) {
spl_autoload_call('RectorPrefix20211205\ComposerAutoloaderInit439ed022b1f73ae246b1b5414e67b710');
if (!class_exists('ComposerAutoloaderInitc0bfbfcdeea8e80344d153233076feea', false) && !interface_exists('ComposerAutoloaderInitc0bfbfcdeea8e80344d153233076feea', false) && !trait_exists('ComposerAutoloaderInitc0bfbfcdeea8e80344d153233076feea', false)) {
spl_autoload_call('RectorPrefix20211205\ComposerAutoloaderInitc0bfbfcdeea8e80344d153233076feea');
}
if (!class_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false) && !interface_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false) && !trait_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false)) {
spl_autoload_call('RectorPrefix20211205\Helmich\TypoScriptParser\Parser\AST\Statement');
@ -81,9 +81,9 @@ if (!function_exists('print_node')) {
return \RectorPrefix20211205\print_node(...func_get_args());
}
}
if (!function_exists('composerRequire439ed022b1f73ae246b1b5414e67b710')) {
function composerRequire439ed022b1f73ae246b1b5414e67b710() {
return \RectorPrefix20211205\composerRequire439ed022b1f73ae246b1b5414e67b710(...func_get_args());
if (!function_exists('composerRequirec0bfbfcdeea8e80344d153233076feea')) {
function composerRequirec0bfbfcdeea8e80344d153233076feea() {
return \RectorPrefix20211205\composerRequirec0bfbfcdeea8e80344d153233076feea(...func_get_args());
}
}
if (!function_exists('scanPath')) {