Skip to content

Commit 441036c

Browse files
committed
Support for @pure-unless-parameter-passed
1 parent 04c8de0 commit 441036c

File tree

6 files changed

+108
-0
lines changed

6 files changed

+108
-0
lines changed

src/Ast/PhpDoc/PhpDocNode.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,17 @@ public function getPureUnlessCallableIsImpureTagValues(string $tagName = '@pure-
126126
);
127127
}
128128

129+
/**
130+
* @return PureUnlessParameterIsPassedTagValueNode[]
131+
*/
132+
public function getPureUnlessParameterIsPassedTagValues(string $tagName = '@pure-unless-parameter-passed'): array
133+
{
134+
return array_filter(
135+
array_column($this->getTagsByName($tagName), 'value'),
136+
static fn (PhpDocTagValueNode $value): bool => $value instanceof PureUnlessParameterIsPassedTagValueNode,
137+
);
138+
}
139+
129140
/**
130141
* @return TemplateTagValueNode[]
131142
*/
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
4+
5+
use PHPStan\PhpDocParser\Ast\NodeAttributes;
6+
use function trim;
7+
8+
class PureUnlessParameterIsPassedTagValueNode implements PhpDocTagValueNode
9+
{
10+
11+
use NodeAttributes;
12+
13+
public string $parameterName;
14+
15+
/** @var string (may be empty) */
16+
public string $description;
17+
18+
public function __construct(string $parameterName, string $description)
19+
{
20+
$this->parameterName = $parameterName;
21+
$this->description = $description;
22+
}
23+
24+
public function __toString(): string
25+
{
26+
return trim("{$this->parameterName} {$this->description}");
27+
}
28+
29+
}

src/Parser/PhpDocParser.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,11 @@ public function parseTagValue(TokenIterator $tokens, string $tag): Ast\PhpDoc\Ph
358358
$tagValue = $this->parsePureUnlessCallableIsImpureTagValue($tokens);
359359
break;
360360

361+
case '@pure-unless-parameter-passed':
362+
case '@phpstan-pure-unless-parameter-passed':
363+
$tagValue = $this->parsePureUnlessParameterIsPassed($tokens);
364+
break;
365+
361366
case '@var':
362367
case '@phpstan-var':
363368
case '@psalm-var':
@@ -878,6 +883,14 @@ private function parsePureUnlessCallableIsImpureTagValue(TokenIterator $tokens):
878883
return new Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode($parameterName, $description);
879884
}
880885

886+
private function parsePureUnlessParameterIsPassed(TokenIterator $tokens): Ast\PhpDoc\PureUnlessParameterIsPassedTagValueNode
887+
{
888+
$parameterName = $this->parseRequiredVariableName($tokens);
889+
$description = $this->parseOptionalDescription($tokens, false);
890+
891+
return new Ast\PhpDoc\PureUnlessParameterIsPassedTagValueNode($parameterName, $description);
892+
}
893+
881894
private function parseVarTagValue(TokenIterator $tokens): Ast\PhpDoc\VarTagValueNode
882895
{
883896
$type = $this->typeParser->parse($tokens);

src/Printer/Printer.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTextNode;
3333
use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
3434
use PHPStan\PhpDocParser\Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode;
35+
use PHPStan\PhpDocParser\Ast\PhpDoc\PureUnlessParameterIsPassedTagValueNode;
3536
use PHPStan\PhpDocParser\Ast\PhpDoc\RequireExtendsTagValueNode;
3637
use PHPStan\PhpDocParser\Ast\PhpDoc\RequireImplementsTagValueNode;
3738
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
@@ -346,6 +347,9 @@ private function printTagValue(PhpDocTagValueNode $node): string
346347
if ($node instanceof PureUnlessCallableIsImpureTagValueNode) {
347348
return trim("{$node->parameterName} {$node->description}");
348349
}
350+
if ($node instanceof PureUnlessParameterIsPassedTagValueNode) {
351+
return trim("{$node->parameterName} {$node->description}");
352+
}
349353
if ($node instanceof PropertyTagValueNode) {
350354
$type = $this->printType($node->type);
351355
return trim("{$type} {$node->propertyName} {$node->description}");

tests/PHPStan/Parser/PhpDocParserTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTextNode;
4040
use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
4141
use PHPStan\PhpDocParser\Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode;
42+
use PHPStan\PhpDocParser\Ast\PhpDoc\PureUnlessParameterIsPassedTagValueNode;
4243
use PHPStan\PhpDocParser\Ast\PhpDoc\RequireExtendsTagValueNode;
4344
use PHPStan\PhpDocParser\Ast\PhpDoc\RequireImplementsTagValueNode;
4445
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
@@ -753,6 +754,37 @@ public function providePureUnlessCallableIsImpureTagsData(): Iterator
753754
];
754755
}
755756

757+
public function providePureUnlessParameterIsPassedTagsData(): Iterator
758+
{
759+
yield [
760+
'OK',
761+
'/** @pure-unless-parameter-passed $foo */',
762+
new PhpDocNode([
763+
new PhpDocTagNode(
764+
'@pure-unless-parameter-passed',
765+
new PureUnlessParameterIsPassedTagValueNode(
766+
'$foo',
767+
'',
768+
),
769+
),
770+
]),
771+
];
772+
773+
yield [
774+
'OK with description',
775+
'/** @pure-unless-parameter-passed $foo test two three */',
776+
new PhpDocNode([
777+
new PhpDocTagNode(
778+
'@pure-unless-parameter-passed',
779+
new PureUnlessParameterIsPassedTagValueNode(
780+
'$foo',
781+
'test two three',
782+
),
783+
),
784+
]),
785+
];
786+
}
787+
756788
public function provideVarTagsData(): Iterator
757789
{
758790
yield [

tests/PHPStan/Printer/PrinterTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode;
2525
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
2626
use PHPStan\PhpDocParser\Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode;
27+
use PHPStan\PhpDocParser\Ast\PhpDoc\PureUnlessParameterIsPassedTagValueNode;
2728
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
2829
use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode;
2930
use PHPStan\PhpDocParser\Ast\PhpDoc\TypeAliasImportTagValueNode;
@@ -1788,6 +1789,24 @@ public function enterNode(Node $node)
17881789
},
17891790
];
17901791

1792+
yield [
1793+
'/** @pure-unless-parameter-passed $foo test */',
1794+
'/** @pure-unless-parameter-passed $bar foo */',
1795+
new class extends AbstractNodeVisitor {
1796+
1797+
public function enterNode(Node $node)
1798+
{
1799+
if ($node instanceof PureUnlessParameterIsPassedTagValueNode) {
1800+
$node->parameterName = '$bar';
1801+
$node->description = 'foo';
1802+
}
1803+
1804+
return $node;
1805+
}
1806+
1807+
},
1808+
];
1809+
17911810
yield [
17921811
'/** @return Foo[abc] */',
17931812
'/** @return self::FOO[abc] */',

0 commit comments

Comments
 (0)