Skip to content

Commit a0a967a

Browse files
Add support for statement in conditional tags
1 parent 571cd30 commit a0a967a

File tree

7 files changed

+140
-6
lines changed

7 files changed

+140
-6
lines changed

src/DependencyInjection/ConditionalTagsExtension.php

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Nette;
66
use Nette\DI\CompilerExtension;
7+
use Nette\DI\Definitions\Statement;
78
use Nette\Schema\Expect;
89
use Override;
910
use PHPStan\ShouldNotHappenException;
@@ -23,7 +24,11 @@ public function getConfigSchema(): Nette\Schema\Schema
2324
$tags = array_values(ValidateServiceTagsExtension::INTERFACE_TAG_MAPPING);
2425

2526
return Expect::arrayOf(Expect::structure(
26-
array_fill_keys($tags, Expect::anyOf(Expect::bool(), Expect::listOf(Expect::bool()))),
27+
array_fill_keys($tags, Expect::anyOf(
28+
Expect::bool(),
29+
Expect::type(Statement::class),
30+
Expect::listOf(Expect::anyOf(Expect::bool(), Expect::type(Statement::class))),
31+
)),
2732
)->min(1));
2833
}
2934

@@ -41,16 +46,29 @@ public function beforeCompile(): void
4146
}
4247
foreach ($services as $service) {
4348
foreach ($tags as $tag => $parameter) {
44-
if (is_array($parameter)) {
45-
$parameter = array_reduce($parameter, static fn ($carry, $item) => $carry && (bool) $item, true);
46-
}
47-
if ((bool) $parameter) {
49+
$parameter = is_array($parameter)
50+
? array_reduce($parameter, fn ($carry, $item) => $carry && $this->resolveValue($item), true)
51+
: $this->resolveValue($parameter);
52+
53+
if ($parameter) {
4854
$service->addTag($tag);
49-
continue;
5055
}
5156
}
5257
}
5358
}
5459
}
5560

61+
public function resolveValue(mixed $parameter): bool
62+
{
63+
if (!$parameter instanceof Statement) {
64+
return (bool) $parameter;
65+
}
66+
67+
if ('not' === $parameter->getEntity()) {
68+
return ! (bool) $parameter->arguments[0];
69+
}
70+
71+
throw new \InvalidArgumentException('Unsupported Statement.');
72+
}
73+
5674
}

tests/PHPStan/DependencyInjection/ConditionalTagsExtensionTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,14 @@ public function testConditionalTags(): void
1616
$enabledServices = array_map(static fn ($service) => get_class($service), $enabledServices);
1717
$this->assertNotContains(TestedConditionalServiceDisabled::class, $enabledServices);
1818
$this->assertContains(TestedConditionalServiceEnabled::class, $enabledServices);
19+
$this->assertContains(TestedConditionalServiceNotDisabled::class, $enabledServices);
20+
$this->assertNotContains(TestedConditionalServiceNotEnabled::class, $enabledServices);
1921
$this->assertNotContains(TestedConditionalServiceDisabledDisabled::class, $enabledServices);
2022
$this->assertNotContains(TestedConditionalServiceDisabledEnabled::class, $enabledServices);
2123
$this->assertNotContains(TestedConditionalServiceEnabledDisabled::class, $enabledServices);
2224
$this->assertContains(TestedConditionalServiceEnabledEnabled::class, $enabledServices);
25+
$this->assertContains(TestedConditionalServiceEnabledNotDisabled::class, $enabledServices);
26+
$this->assertNotContains(TestedConditionalServiceEnabledNotEnabled::class, $enabledServices);
2327
}
2428

2529
/**
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\DependencyInjection;
4+
5+
use PhpParser\Node;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\Rules\Rule;
8+
9+
/**
10+
* @implements Rule<Node>
11+
*/
12+
class TestedConditionalServiceEnabledNotDisabled implements Rule
13+
{
14+
15+
public function getNodeType(): string
16+
{
17+
return Node::class;
18+
}
19+
20+
public function processNode(Node $node, Scope $scope): array
21+
{
22+
return [];
23+
}
24+
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\DependencyInjection;
4+
5+
use PhpParser\Node;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\Rules\Rule;
8+
9+
/**
10+
* @implements Rule<Node>
11+
*/
12+
class TestedConditionalServiceEnabledNotEnabled implements Rule
13+
{
14+
15+
public function getNodeType(): string
16+
{
17+
return Node::class;
18+
}
19+
20+
public function processNode(Node $node, Scope $scope): array
21+
{
22+
return [];
23+
}
24+
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\DependencyInjection;
4+
5+
use PhpParser\Node;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\Rules\Rule;
8+
9+
/**
10+
* @implements Rule<Node>
11+
*/
12+
class TestedConditionalServiceNotDisabled implements Rule
13+
{
14+
15+
public function getNodeType(): string
16+
{
17+
return Node::class;
18+
}
19+
20+
public function processNode(Node $node, Scope $scope): array
21+
{
22+
return [];
23+
}
24+
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\DependencyInjection;
4+
5+
use PhpParser\Node;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\Rules\Rule;
8+
9+
/**
10+
* @implements Rule<Node>
11+
*/
12+
class TestedConditionalServiceNotEnabled implements Rule
13+
{
14+
15+
public function getNodeType(): string
16+
{
17+
return Node::class;
18+
}
19+
20+
public function processNode(Node $node, Scope $scope): array
21+
{
22+
return [];
23+
}
24+
25+
}

tests/PHPStan/DependencyInjection/conditionalTags.neon

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ conditionalTags:
1111
phpstan.rules.rule: %disabled%
1212
PHPStan\DependencyInjection\TestedConditionalServiceEnabled:
1313
phpstan.rules.rule: %enabled%
14+
PHPStan\DependencyInjection\TestedConditionalServiceNotDisabled:
15+
phpstan.rules.rule: not(%disabled%)
16+
PHPStan\DependencyInjection\TestedConditionalServiceNotEnabled:
17+
phpstan.rules.rule: not(%enabled%)
1418
PHPStan\DependencyInjection\TestedConditionalServiceDisabledDisabled:
1519
phpstan.rules.rule: [%disabled%, %disabled%]
1620
PHPStan\DependencyInjection\TestedConditionalServiceDisabledEnabled:
@@ -19,11 +23,19 @@ conditionalTags:
1923
phpstan.rules.rule: [%enabled%, %disabled%]
2024
PHPStan\DependencyInjection\TestedConditionalServiceEnabledEnabled:
2125
phpstan.rules.rule: [%enabled%, %enabled%]
26+
PHPStan\DependencyInjection\TestedConditionalServiceEnabledNotEnabled:
27+
phpstan.rules.rule: [%enabled%, not(%enabled%)]
28+
PHPStan\DependencyInjection\TestedConditionalServiceEnabledNotDisabled:
29+
phpstan.rules.rule: [%enabled%, not(%disabled%)]
2230

2331
services:
2432
- PHPStan\DependencyInjection\TestedConditionalServiceDisabled
2533
- PHPStan\DependencyInjection\TestedConditionalServiceEnabled
34+
- PHPStan\DependencyInjection\TestedConditionalServiceNotDisabled
35+
- PHPStan\DependencyInjection\TestedConditionalServiceNotEnabled
2636
- PHPStan\DependencyInjection\TestedConditionalServiceDisabledDisabled
2737
- PHPStan\DependencyInjection\TestedConditionalServiceDisabledEnabled
2838
- PHPStan\DependencyInjection\TestedConditionalServiceEnabledDisabled
2939
- PHPStan\DependencyInjection\TestedConditionalServiceEnabledEnabled
40+
- PHPStan\DependencyInjection\TestedConditionalServiceEnabledNotEnabled
41+
- PHPStan\DependencyInjection\TestedConditionalServiceEnabledNotDisabled

0 commit comments

Comments
 (0)