Skip to content

Commit 19ee9e3

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

File tree

7 files changed

+141
-5
lines changed

7 files changed

+141
-5
lines changed

src/DependencyInjection/ConditionalTagsExtension.php

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
namespace PHPStan\DependencyInjection;
44

5+
use InvalidArgumentException;
56
use Nette;
67
use Nette\DI\CompilerExtension;
8+
use Nette\DI\Definitions\Statement;
79
use Nette\Schema\Expect;
810
use Override;
911
use PHPStan\ShouldNotHappenException;
@@ -23,7 +25,11 @@ public function getConfigSchema(): Nette\Schema\Schema
2325
$tags = array_values(ValidateServiceTagsExtension::INTERFACE_TAG_MAPPING);
2426

2527
return Expect::arrayOf(Expect::structure(
26-
array_fill_keys($tags, Expect::anyOf(Expect::bool(), Expect::listOf(Expect::bool()))),
28+
array_fill_keys($tags, Expect::anyOf(
29+
Expect::bool(),
30+
Expect::type(Statement::class),
31+
Expect::listOf(Expect::anyOf(Expect::bool(), Expect::type(Statement::class))),
32+
)),
2733
)->min(1));
2834
}
2935

@@ -41,10 +47,11 @@ public function beforeCompile(): void
4147
}
4248
foreach ($services as $service) {
4349
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) {
50+
$parameter = is_array($parameter)
51+
? array_reduce($parameter, fn ($carry, $item) => $carry && $this->resolveValue($item), true)
52+
: $this->resolveValue($parameter);
53+
54+
if ($parameter) {
4855
$service->addTag($tag);
4956
continue;
5057
}
@@ -53,4 +60,17 @@ public function beforeCompile(): void
5360
}
5461
}
5562

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

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)