Skip to content

Commit

Permalink
NeonAdapter: resolving of constants and enums moved here from filterA…
Browse files Browse the repository at this point in the history
…rguments() (BC break)
  • Loading branch information
dg committed Apr 28, 2024
1 parent a22fd3a commit e07ff3a
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 20 deletions.
22 changes: 22 additions & 0 deletions src/DI/Config/Adapters/NeonAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public function load(string $file): array
$node = $traverser->traverse($node, $this->removeUnderscoreVisitor(...));
$node = $traverser->traverse($node, $this->convertAtSignVisitor(...));
$node = $traverser->traverse($node, $this->deprecatedParametersVisitor(...));
$node = $traverser->traverse($node, $this->resolveConstants(...));
return $this->process((array) $node->toValue());
}

Expand Down Expand Up @@ -217,4 +218,25 @@ private function deprecatedParametersVisitor(Neon\Node $node): void
trigger_error('%parameters% is deprecated, use @container::getParameters() (in ' . $this->file . ')', E_USER_DEPRECATED);
}
}


private function resolveConstants(Neon\Node $node): void
{
$items = match (true) {
$node instanceof Neon\Node\ArrayNode => $node->items,
$node instanceof Neon\Node\EntityNode => $node->attributes,
default => null,
};
if ($items) {
foreach ($items as $item) {
if ($item->value instanceof Neon\Node\LiteralNode
&& is_string($item->value->value)
&& preg_match('#^([\w\\\\]*)::[A-Z]\w+$#D', $item->value->value)
&& defined(ltrim($item->value->value, ':'))
) {
$item->value->value = constant(ltrim($item->value->value, ':'));
}
}
}
}
}
10 changes: 1 addition & 9 deletions src/DI/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,15 +158,7 @@ public static function escape(mixed $value): mixed
public static function filterArguments(array $args): array
{
foreach ($args as $k => $v) {
if (
is_string($v)
&& preg_match('#^([\w\\\\]+)::\w+$#D', $v, $m)
&& enum_exists($m[1])
) {
$args[$k] = new Nette\PhpGenerator\Literal($v);
} elseif (is_string($v) && preg_match('#^[\w\\\\]*::[A-Z][a-zA-Z0-9_]*$#D', $v)) {
$args[$k] = new Nette\PhpGenerator\Literal(ltrim($v, ':'));
} elseif (is_string($v) && preg_match('#^@[\w\\\\]+$#D', $v)) {
if (is_string($v) && preg_match('#^@[\w\\\\]+$#D', $v)) {
$args[$k] = new Reference(substr($v, 1));
} elseif (is_array($v)) {
$args[$k] = self::filterArguments($v);
Expand Down
2 changes: 1 addition & 1 deletion tests/DI/Compiler.parameters.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ test('NOT class constant as parameter', function () {
one: Service(%bar%)
');

Assert::same(['bar' => 'Service::Name'], $container->getParameters()); // not resolved
Assert::same(['bar' => 'hello'], $container->getParameters());
Assert::same('hello', $container->getService('one')->arg);
});

Expand Down
6 changes: 3 additions & 3 deletions tests/DI/DecoratorExtension.basic.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require __DIR__ . '/../bootstrap.php';

interface Iface
{
public const Name = self::class;
public const Name = 'hello';
}


Expand Down Expand Up @@ -77,7 +77,7 @@ services:
$builder = $compiler->getContainerBuilder();

Assert::same(
['a' => true, 'tag' => 2, DI\Extensions\InjectExtension::TagInject => true, 'Iface::Name' => true],
['a' => true, 'tag' => 2, DI\Extensions\InjectExtension::TagInject => true, 'hello' => true],
$builder->getDefinition('one')->getTags(),
);

Expand All @@ -86,7 +86,7 @@ Assert::true($builder->getDefinition('one')->getTag(DI\Extensions\InjectExtensio
Assert::equal([
new Statement([new Reference('self'), 'setup'], ['Service']),
new Statement([new Reference('self'), 'setup'], ['Object']),
new Statement([new Reference('self'), 'setup'], [new Nette\PhpGenerator\Literal('Iface::Name')]),
new Statement([new Reference('self'), 'setup'], ['hello']),
new Statement([new Reference('self'), 'setup']),
new Statement([new Reference('self'), '$a'], [10]),
], $builder->getDefinition('one')->getSetup());
9 changes: 2 additions & 7 deletions tests/DI/Helpers.filterArguments.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,12 @@ require __DIR__ . '/../bootstrap.php';

Assert::same([], Helpers::filterArguments([]));

Assert::equal(
['a', 'b', ContainerBuilder::literal('Nette\DI\ContainerBuilder::ThisContainer')],
Helpers::filterArguments(['a', 'b', 'Nette\DI\ContainerBuilder::ThisContainer']),
);

Assert::equal(
['a', 'b', new Nette\DI\Definitions\Reference('service')],
Helpers::filterArguments(['a', 'b', '@service']),
);

Assert::equal(
[new Statement('class', ['a', ContainerBuilder::literal('Nette\DI\ContainerBuilder::ThisContainer')])],
Helpers::filterArguments([new Statement('class', ['a', 'Nette\DI\ContainerBuilder::ThisContainer'])]),
[new Statement('class', ['a', new Nette\DI\Definitions\Reference('service')])],
Helpers::filterArguments([new Statement('class', ['a', '@service'])]),
);
21 changes: 21 additions & 0 deletions tests/DI/NeonAdapter.preprocess.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,24 @@ Assert::equal(
],
$data,
);


// constants
$data = @$adapter->load(Tester\FileMock::create('
- Foo::Bar
- ArrayIterator::STD_PROP_LIST
- "ArrayIterator::STD_PROP_LIST"
- ::PHP_INT_MAX
- ArrayIterator::STD_PROP_LIST()
', 'neon'));

Assert::equal(
[
'Foo::Bar',
ArrayIterator::STD_PROP_LIST,
'ArrayIterator::STD_PROP_LIST',
PHP_INT_MAX,
new Statement('ArrayIterator::STD_PROP_LIST'),
],
$data,
);

0 comments on commit e07ff3a

Please sign in to comment.