mirror of https://github.com/rectorphp/rector.git
83 lines
2.5 KiB
PHP
83 lines
2.5 KiB
PHP
<?php
|
|
|
|
declare (strict_types=1);
|
|
namespace Rector\PhpAttribute\NodeFactory;
|
|
|
|
use RectorPrefix202305\Nette\Utils\Strings;
|
|
use PhpParser\BuilderHelpers;
|
|
use PhpParser\Node\Arg;
|
|
use PhpParser\Node\Expr;
|
|
use PhpParser\Node\Expr\Array_;
|
|
use PhpParser\Node\Expr\ArrayItem;
|
|
use PhpParser\Node\Expr\ClassConstFetch;
|
|
use PhpParser\Node\Identifier;
|
|
use PhpParser\Node\Name;
|
|
use PhpParser\Node\Scalar\String_;
|
|
use Rector\NodeTypeResolver\Node\AttributeKey;
|
|
final class NamedArgsFactory
|
|
{
|
|
/**
|
|
* @see https://regex101.com/r/1bJR0J/1
|
|
* @var string
|
|
*/
|
|
private const CLASS_CONST_REGEX = '#(?<class>\\w+)::(?<constant>\\w+)#';
|
|
/**
|
|
* @param array<string|int, mixed|Expr> $values
|
|
* @return Arg[]
|
|
*/
|
|
public function createFromValues(array $values) : array
|
|
{
|
|
$args = [];
|
|
foreach ($values as $key => $argValue) {
|
|
$expr = BuilderHelpers::normalizeValue($argValue);
|
|
$this->normalizeArrayWithConstFetchKey($expr);
|
|
$name = null;
|
|
// for named arguments
|
|
if (\is_string($key)) {
|
|
$name = new Identifier($key);
|
|
}
|
|
$this->normalizeStringDoubleQuote($expr);
|
|
$args[] = new Arg($expr, \false, \false, [], $name);
|
|
}
|
|
return $args;
|
|
}
|
|
private function normalizeStringDoubleQuote(Expr $expr) : void
|
|
{
|
|
if (!$expr instanceof String_) {
|
|
return;
|
|
}
|
|
// avoid escaping quotes + preserve newlines
|
|
if (\strpos($expr->value, "'") === \false) {
|
|
return;
|
|
}
|
|
if (\strpos($expr->value, "\n") !== \false) {
|
|
return;
|
|
}
|
|
$expr->setAttribute(AttributeKey::KIND, String_::KIND_DOUBLE_QUOTED);
|
|
}
|
|
private function normalizeArrayWithConstFetchKey(Expr $expr) : void
|
|
{
|
|
if (!$expr instanceof Array_) {
|
|
return;
|
|
}
|
|
foreach ($expr->items as $arrayItem) {
|
|
if (!$arrayItem instanceof ArrayItem) {
|
|
continue;
|
|
}
|
|
if (!$arrayItem->key instanceof String_) {
|
|
continue;
|
|
}
|
|
$string = $arrayItem->key;
|
|
$match = Strings::match($string->value, self::CLASS_CONST_REGEX);
|
|
if ($match === null) {
|
|
continue;
|
|
}
|
|
/** @var string $class */
|
|
$class = $match['class'];
|
|
/** @var string $constant */
|
|
$constant = $match['constant'];
|
|
$arrayItem->key = new ClassConstFetch(new Name($class), $constant);
|
|
}
|
|
}
|
|
}
|