use ConstExprEvaluator instead of NodeValueResolver

This commit is contained in:
TomasVotruba 2018-01-27 20:47:56 +01:00
parent 19afd3d768
commit 201d4919bb
10 changed files with 12 additions and 220 deletions

View File

@ -1,10 +0,0 @@
<?php declare(strict_types=1);
namespace Rector\NodeValueResolver\Contract;
use Rector\NodeValueResolver\NodeValueResolver;
interface NodeValueResolverAwareInterface
{
public function setNodeValueResolver(NodeValueResolver $nodeValueResolver): void;
}

View File

@ -1,15 +0,0 @@
<?php declare(strict_types=1);
namespace Rector\NodeValueResolver\Contract\PerNodeValueResolver;
use PhpParser\Node;
interface PerNodeValueResolverInterface
{
public function getNodeClass(): string;
/**
* @return mixed
*/
public function resolve(Node $node);
}

View File

@ -1,39 +0,0 @@
<?php declare(strict_types=1);
namespace Rector\NodeValueResolver\DependencyInjection\CompilerPass;
use Rector\NodeValueResolver\Contract\NodeValueResolverAwareInterface;
use Rector\NodeValueResolver\Contract\PerNodeValueResolver\PerNodeValueResolverInterface;
use Rector\NodeValueResolver\NodeValueResolver;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symplify\PackageBuilder\DependencyInjection\DefinitionCollector;
final class NodeValueResolverCollectorCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $containerBuilder): void
{
$this->collectPerNodeValueResolversToValueResolver($containerBuilder);
$this->setNodeValueResolverToAware($containerBuilder);
}
private function collectPerNodeValueResolversToValueResolver(ContainerBuilder $containerBuilder): void
{
DefinitionCollector::loadCollectorWithType(
$containerBuilder,
NodeValueResolver::class,
PerNodeValueResolverInterface::class,
'addPerNodeValueResolver'
);
}
private function setNodeValueResolverToAware(ContainerBuilder $containerBuilder): void
{
DefinitionCollector::loadCollectorWithType(
$containerBuilder,
NodeValueResolverAwareInterface::class,
NodeValueResolver::class,
'setNodeValueResolver'
);
}
}

View File

@ -2,22 +2,20 @@
namespace Rector\NodeValueResolver;
use PhpParser\ConstExprEvaluator;
use PhpParser\Node;
use Rector\NodeValueResolver\Contract\PerNodeValueResolver\PerNodeValueResolverInterface;
use PhpParser\Node\Expr;
/**
* Inspired by https://github.com/Roave/BetterReflection/blob/master/test/unit/NodeCompiler/CompileNodeToValueTest.php
*/
final class NodeValueResolver
{
/**
* @var PerNodeValueResolverInterface[]
* @var ConstExprEvaluator
*/
private $perNodeValueResolvers = [];
private $constExprEvaluator;
public function addPerNodeValueResolver(PerNodeValueResolverInterface $perNodeValueResolver): void
public function __construct(ConstExprEvaluator $constExprEvaluator)
{
$this->perNodeValueResolvers[$perNodeValueResolver->getNodeClass()] = $perNodeValueResolver;
$this->constExprEvaluator = $constExprEvaluator;
}
/**
@ -25,11 +23,10 @@ final class NodeValueResolver
*/
public function resolve(Node $node)
{
$nodeClass = get_class($node);
if (! isset($this->perNodeValueResolvers[$nodeClass])) {
return null;
if ($node instanceof Expr) {
return $this->constExprEvaluator->evaluateDirectly($node);
}
return $this->perNodeValueResolvers[$nodeClass]->resolve($node);
return null;
}
}

View File

@ -1,50 +0,0 @@
<?php declare(strict_types=1);
namespace Rector\NodeValueResolver\PerNodeValueResolver;
use PhpParser\Node;
use PhpParser\Node\Expr\Array_;
use Rector\NodeValueResolver\Contract\NodeValueResolverAwareInterface;
use Rector\NodeValueResolver\Contract\PerNodeValueResolver\PerNodeValueResolverInterface;
use Rector\NodeValueResolver\NodeValueResolver;
final class ArrayValueResolver implements PerNodeValueResolverInterface, NodeValueResolverAwareInterface
{
/**
* @var NodeValueResolver
*/
private $nodeValueResolver;
public function getNodeClass(): string
{
return Array_::class;
}
/**
* @param Array_ $arrayNode
* @return mixed[]
*/
public function resolve(Node $arrayNode): array
{
$compiledArray = [];
foreach ($arrayNode->items as $arrayItem) {
$compiledValue = $this->nodeValueResolver->resolve($arrayItem->value);
if ($arrayItem->key === null) {
$compiledArray[] = $compiledValue;
continue;
}
$key = $this->nodeValueResolver->resolve($arrayItem->key);
$compiledArray[$key] = $compiledValue;
}
return $compiledArray;
}
public function setNodeValueResolver(NodeValueResolver $nodeValueResolver): void
{
$this->nodeValueResolver = $nodeValueResolver;
}
}

View File

@ -1,33 +0,0 @@
<?php declare(strict_types=1);
namespace Rector\NodeValueResolver\PerNodeValueResolver;
use PhpParser\Node;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Identifier;
use Rector\Node\Attribute;
use Rector\NodeValueResolver\Contract\PerNodeValueResolver\PerNodeValueResolverInterface;
final class ClassConstFetchResolver implements PerNodeValueResolverInterface
{
public function getNodeClass(): string
{
return ClassConstFetch::class;
}
/**
* @param ClassConstFetch $classConstFetchNode
*/
public function resolve(Node $classConstFetchNode): string
{
$class = $classConstFetchNode->class->getAttribute(Attribute::RESOLVED_NAME)
->toString();
/** @var Identifier $identifierNode */
$identifierNode = $classConstFetchNode->name;
$constant = $identifierNode->toString();
return $class . '::' . $constant;
}
}

View File

@ -1,35 +0,0 @@
<?php declare(strict_types=1);
namespace Rector\NodeValueResolver\PerNodeValueResolver;
use PhpParser\Node;
use PhpParser\Node\Expr\ConstFetch;
use Rector\NodeValueResolver\Contract\PerNodeValueResolver\PerNodeValueResolverInterface;
final class ConstFetchResolver implements PerNodeValueResolverInterface
{
public function getNodeClass(): string
{
return ConstFetch::class;
}
/**
* @param ConstFetch $constFetchNode
*/
public function resolve(Node $constFetchNode): ?bool
{
$name = strtolower($constFetchNode->name->toString());
if ($name === 'true') {
return true;
}
if ($name === 'false') {
return false;
}
if ($name === 'null') {
return null;
}
}
}

View File

@ -1,23 +0,0 @@
<?php declare(strict_types=1);
namespace Rector\NodeValueResolver\PerNodeValueResolver;
use PhpParser\Node;
use PhpParser\Node\Scalar\String_;
use Rector\NodeValueResolver\Contract\PerNodeValueResolver\PerNodeValueResolverInterface;
final class StringValueResolver implements PerNodeValueResolverInterface
{
public function getNodeClass(): string
{
return String_::class;
}
/**
* @param String_ $stringNode
*/
public function resolve(Node $stringNode): string
{
return $stringNode->value;
}
}

View File

@ -5,4 +5,6 @@ services:
Rector\NodeValueResolver\:
resource: '../'
exclude: '../{Contract}'
PhpParser\ConstExprEvaluator: ~

View File

@ -4,7 +4,6 @@ namespace Rector\DependencyInjection;
use Rector\DependencyInjection\CompilerPass\CollectorCompilerPass;
use Rector\NodeTypeResolver\DependencyInjection\CompilerPass\NodeTypeResolverCollectorCompilerPass;
use Rector\NodeValueResolver\DependencyInjection\CompilerPass\NodeValueResolverCollectorCompilerPass;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
@ -59,7 +58,6 @@ final class AppKernel extends Kernel
protected function build(ContainerBuilder $containerBuilder): void
{
$containerBuilder->addCompilerPass(new CollectorCompilerPass());
$containerBuilder->addCompilerPass(new NodeValueResolverCollectorCompilerPass());
$containerBuilder->addCompilerPass(new NodeTypeResolverCollectorCompilerPass());
}
}