Skip to content

Commit d02f438

Browse files
Introduce all-methods tag
1 parent bd6f207 commit d02f438

File tree

7 files changed

+202
-0
lines changed

7 files changed

+202
-0
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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 AllMethodsImpureTagValueNode implements PhpDocTagValueNode
9+
{
10+
11+
use NodeAttributes;
12+
13+
/** @var string (may be empty) */
14+
public string $description;
15+
16+
public function __construct(string $description)
17+
{
18+
$this->description = $description;
19+
}
20+
21+
public function __toString(): string
22+
{
23+
return trim($this->description);
24+
}
25+
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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 AllMethodsPureTagValueNode implements PhpDocTagValueNode
9+
{
10+
11+
use NodeAttributes;
12+
13+
/** @var string (may be empty) */
14+
public string $description;
15+
16+
public function __construct(string $description)
17+
{
18+
$this->description = $description;
19+
}
20+
21+
public function __toString(): string
22+
{
23+
return trim($this->description);
24+
}
25+
26+
}

src/Ast/PhpDoc/PhpDocNode.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,28 @@ public function getPureUnlessCallableIsImpureTagValues(string $tagName = '@pure-
118118
);
119119
}
120120

121+
/**
122+
* @return AllMethodsImpureTagValueNode[]
123+
*/
124+
public function getAllMethodsImpureTagValues(string $tagName = '@phpstan-all-methods-impure'): array
125+
{
126+
return array_filter(
127+
array_column($this->getTagsByName($tagName), 'value'),
128+
static fn (PhpDocTagValueNode $value): bool => $value instanceof AllMethodsImpureTagValueNode,
129+
);
130+
}
131+
132+
/**
133+
* @return AllMethodsPureTagValueNode[]
134+
*/
135+
public function getAllMethodsPureTagValues(string $tagName = '@phpstan-all-methods-pure'): array
136+
{
137+
return array_filter(
138+
array_column($this->getTagsByName($tagName), 'value'),
139+
static fn (PhpDocTagValueNode $value): bool => $value instanceof AllMethodsPureTagValueNode,
140+
);
141+
}
142+
121143
/**
122144
* @return TemplateTagValueNode[]
123145
*/

src/Parser/PhpDocParser.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,14 @@ public function parseTagValue(TokenIterator $tokens, string $tag): Ast\PhpDoc\Ph
362362
$tagValue = $this->parsePureUnlessCallableIsImpureTagValue($tokens);
363363
break;
364364

365+
case '@phpstan-all-methods-impure':
366+
$tagValue = $this->parseAllMethodsImpureTagValue($tokens);
367+
break;
368+
369+
case '@phpstan-all-methods-pure':
370+
$tagValue = $this->parseAllMethodsPureTagValue($tokens);
371+
break;
372+
365373
case '@var':
366374
case '@phpstan-var':
367375
case '@psalm-var':
@@ -877,6 +885,20 @@ private function parsePureUnlessCallableIsImpureTagValue(TokenIterator $tokens):
877885
return new Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode($parameterName, $description);
878886
}
879887

888+
private function parseAllMethodsImpureTagValue(TokenIterator $tokens): Ast\PhpDoc\AllMethodsImpureTagValueNode
889+
{
890+
$description = $this->parseOptionalDescription($tokens, false);
891+
892+
return new Ast\PhpDoc\AllMethodsImpureTagValueNode($description);
893+
}
894+
895+
private function parseAllMethodsPureTagValue(TokenIterator $tokens): Ast\PhpDoc\AllMethodsPureTagValueNode
896+
{
897+
$description = $this->parseOptionalDescription($tokens, false);
898+
899+
return new Ast\PhpDoc\AllMethodsPureTagValueNode($description);
900+
}
901+
880902
private function parseVarTagValue(TokenIterator $tokens): Ast\PhpDoc\VarTagValueNode
881903
{
882904
$type = $this->typeParser->parse($tokens);

src/Printer/Printer.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprArrayNode;
99
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprNode;
1010
use PHPStan\PhpDocParser\Ast\Node;
11+
use PHPStan\PhpDocParser\Ast\PhpDoc\AllMethodsImpureTagValueNode;
12+
use PHPStan\PhpDocParser\Ast\PhpDoc\AllMethodsPureTagValueNode;
1113
use PHPStan\PhpDocParser\Ast\PhpDoc\AssertTagMethodValueNode;
1214
use PHPStan\PhpDocParser\Ast\PhpDoc\AssertTagPropertyValueNode;
1315
use PHPStan\PhpDocParser\Ast\PhpDoc\AssertTagValueNode;
@@ -354,6 +356,12 @@ private function printTagValue(PhpDocTagValueNode $node): string
354356
if ($node instanceof PureUnlessCallableIsImpureTagValueNode) {
355357
return trim("{$node->parameterName} {$node->description}");
356358
}
359+
if ($node instanceof AllMethodsImpureTagValueNode) {
360+
return trim($node->description);
361+
}
362+
if ($node instanceof AllMethodsPureTagValueNode) {
363+
return trim($node->description);
364+
}
357365
if ($node instanceof PropertyTagValueNode) {
358366
$type = $this->printType($node->type);
359367
return trim("{$type} {$node->propertyName} {$node->description}");

tests/PHPStan/Parser/PhpDocParserTest.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
use PHPStan\PhpDocParser\Ast\ConstExpr\DoctrineConstExprStringNode;
1414
use PHPStan\PhpDocParser\Ast\Node;
1515
use PHPStan\PhpDocParser\Ast\NodeTraverser;
16+
use PHPStan\PhpDocParser\Ast\PhpDoc\AllMethodsImpureTagValueNode;
17+
use PHPStan\PhpDocParser\Ast\PhpDoc\AllMethodsPureTagValueNode;
1618
use PHPStan\PhpDocParser\Ast\PhpDoc\AssertTagMethodValueNode;
1719
use PHPStan\PhpDocParser\Ast\PhpDoc\AssertTagPropertyValueNode;
1820
use PHPStan\PhpDocParser\Ast\PhpDoc\AssertTagValueNode;
@@ -102,6 +104,8 @@ protected function setUp(): void
102104
* @dataProvider provideTypelessParamTagsData
103105
* @dataProvider provideParamClosureThisTagsData
104106
* @dataProvider providePureUnlessCallableIsImpureTagsData
107+
* @dataProvider provideAllMethodsImpureTagsData
108+
* @dataProvider provideAllMethodsPureTagsData
105109
* @dataProvider provideVarTagsData
106110
* @dataProvider provideReturnTagsData
107111
* @dataProvider provideThrowsTagsData
@@ -757,6 +761,64 @@ public function providePureUnlessCallableIsImpureTagsData(): Iterator
757761
];
758762
}
759763

764+
public function provideAllMethodsImpureTagsData(): Iterator
765+
{
766+
yield [
767+
'OK',
768+
'/** @phpstan-all-methods-impure */',
769+
new PhpDocNode([
770+
new PhpDocTagNode(
771+
'@phpstan-all-methods-impure',
772+
new AllMethodsImpureTagValueNode(
773+
'',
774+
),
775+
),
776+
]),
777+
];
778+
779+
yield [
780+
'OK with description',
781+
'/** @phpstan-all-methods-impure test two three */',
782+
new PhpDocNode([
783+
new PhpDocTagNode(
784+
'@phpstan-all-methods-impure',
785+
new AllMethodsImpureTagValueNode(
786+
'test two three',
787+
),
788+
),
789+
]),
790+
];
791+
}
792+
793+
public function provideAllMethodsPureTagsData(): Iterator
794+
{
795+
yield [
796+
'OK',
797+
'/** @phpstan-all-methods-pure */',
798+
new PhpDocNode([
799+
new PhpDocTagNode(
800+
'@phpstan-all-methods-pure',
801+
new AllMethodsPureTagValueNode(
802+
'',
803+
),
804+
),
805+
]),
806+
];
807+
808+
yield [
809+
'OK with description',
810+
'/** @phpstan-all-methods-pure test two three */',
811+
new PhpDocNode([
812+
new PhpDocTagNode(
813+
'@phpstan-all-methods-pure',
814+
new AllMethodsPureTagValueNode(
815+
'test two three',
816+
),
817+
),
818+
]),
819+
];
820+
}
821+
760822
public function provideVarTagsData(): Iterator
761823
{
762824
yield [

tests/PHPStan/Printer/PrinterTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
use PHPStan\PhpDocParser\Ast\Node;
1414
use PHPStan\PhpDocParser\Ast\NodeTraverser;
1515
use PHPStan\PhpDocParser\Ast\NodeVisitor;
16+
use PHPStan\PhpDocParser\Ast\PhpDoc\AllMethodsImpureTagValueNode;
17+
use PHPStan\PhpDocParser\Ast\PhpDoc\AllMethodsPureTagValueNode;
1618
use PHPStan\PhpDocParser\Ast\PhpDoc\Doctrine\DoctrineAnnotation;
1719
use PHPStan\PhpDocParser\Ast\PhpDoc\Doctrine\DoctrineArgument;
1820
use PHPStan\PhpDocParser\Ast\PhpDoc\Doctrine\DoctrineArray;
@@ -2115,6 +2117,40 @@ public function enterNode(Node $node)
21152117
},
21162118
];
21172119

2120+
yield [
2121+
'/** @phpstan-all-methods-impure test */',
2122+
'/** @phpstan-all-methods-impure foo */',
2123+
new class extends AbstractNodeVisitor {
2124+
2125+
public function enterNode(Node $node)
2126+
{
2127+
if ($node instanceof AllMethodsImpureTagValueNode) {
2128+
$node->description = 'foo';
2129+
}
2130+
2131+
return $node;
2132+
}
2133+
2134+
},
2135+
];
2136+
2137+
yield [
2138+
'/** @phpstan-all-methods-pure test */',
2139+
'/** @phpstan-all-methods-pure foo */',
2140+
new class extends AbstractNodeVisitor {
2141+
2142+
public function enterNode(Node $node)
2143+
{
2144+
if ($node instanceof AllMethodsPureTagValueNode) {
2145+
$node->description = 'foo';
2146+
}
2147+
2148+
return $node;
2149+
}
2150+
2151+
},
2152+
];
2153+
21182154
yield [
21192155
'/** @return Foo[abc] */',
21202156
'/** @return self::FOO[abc] */',

0 commit comments

Comments
 (0)