Skip to content

Commit 426fd7a

Browse files
committedSep 26, 2024
Merge remote-tracking branch 'origin/1.23.x' into 2.0.x
2 parents cc479c9 + 6ca22b1 commit 426fd7a

File tree

6 files changed

+107
-0
lines changed

6 files changed

+107
-0
lines changed
 

‎src/Ast/PhpDoc/PhpDocNode.php

+10
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,16 @@ public function getParamClosureThisTagValues(string $tagName = '@param-closure-t
115115
);
116116
}
117117

118+
/**
119+
* @return PureUnlessCallableIsImpureTagValueNode[]
120+
*/
121+
public function getPureUnlessCallableIsImpureTagValues(string $tagName = '@pure-unless-callable-is-impure'): array
122+
{
123+
return array_filter(
124+
array_column($this->getTagsByName($tagName), 'value'),
125+
static fn (PhpDocTagValueNode $value): bool => $value instanceof PureUnlessCallableIsImpureTagValueNode,
126+
);
127+
}
118128

119129
/**
120130
* @return TemplateTagValueNode[]
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 PureUnlessCallableIsImpureTagValueNode 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

+12
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,11 @@ public function parseTagValue(TokenIterator $tokens, string $tag): Ast\PhpDoc\Ph
354354
$tagValue = $this->parseParamClosureThisTagValue($tokens);
355355
break;
356356

357+
case '@pure-unless-callable-is-impure':
358+
case '@phpstan-pure-unless-callable-is-impure':
359+
$tagValue = $this->parsePureUnlessCallableIsImpureTagValue($tokens);
360+
break;
361+
357362
case '@var':
358363
case '@phpstan-var':
359364
case '@psalm-var':
@@ -866,6 +871,13 @@ private function parseParamClosureThisTagValue(TokenIterator $tokens): Ast\PhpDo
866871
return new Ast\PhpDoc\ParamClosureThisTagValueNode($type, $parameterName, $description);
867872
}
868873

874+
private function parsePureUnlessCallableIsImpureTagValue(TokenIterator $tokens): Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode
875+
{
876+
$parameterName = $this->parseRequiredVariableName($tokens);
877+
$description = $this->parseOptionalDescription($tokens, false);
878+
879+
return new Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode($parameterName, $description);
880+
}
869881

870882
private function parseVarTagValue(TokenIterator $tokens): Ast\PhpDoc\VarTagValueNode
871883
{

‎src/Printer/Printer.php

+4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode;
3232
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTextNode;
3333
use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
34+
use PHPStan\PhpDocParser\Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode;
3435
use PHPStan\PhpDocParser\Ast\PhpDoc\RequireExtendsTagValueNode;
3536
use PHPStan\PhpDocParser\Ast\PhpDoc\RequireImplementsTagValueNode;
3637
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
@@ -342,6 +343,9 @@ private function printTagValue(PhpDocTagValueNode $node): string
342343
if ($node instanceof ParamClosureThisTagValueNode) {
343344
return trim("{$node->type} {$node->parameterName} {$node->description}");
344345
}
346+
if ($node instanceof PureUnlessCallableIsImpureTagValueNode) {
347+
return trim("{$node->parameterName} {$node->description}");
348+
}
345349
if ($node instanceof PropertyTagValueNode) {
346350
$type = $this->printType($node->type);
347351
return trim("{$type} {$node->propertyName} {$node->description}");

‎tests/PHPStan/Parser/PhpDocParserTest.php

+33
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
3939
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTextNode;
4040
use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
41+
use PHPStan\PhpDocParser\Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode;
4142
use PHPStan\PhpDocParser\Ast\PhpDoc\RequireExtendsTagValueNode;
4243
use PHPStan\PhpDocParser\Ast\PhpDoc\RequireImplementsTagValueNode;
4344
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
@@ -96,6 +97,7 @@ protected function setUp(): void
9697
* @dataProvider provideParamLaterInvokedCallableTagsData
9798
* @dataProvider provideTypelessParamTagsData
9899
* @dataProvider provideParamClosureThisTagsData
100+
* @dataProvider providePureUnlessCallableIsImpureTagsData
99101
* @dataProvider provideVarTagsData
100102
* @dataProvider provideReturnTagsData
101103
* @dataProvider provideThrowsTagsData
@@ -720,6 +722,37 @@ public function provideParamClosureThisTagsData(): Iterator
720722
];
721723
}
722724

725+
public function providePureUnlessCallableIsImpureTagsData(): Iterator
726+
{
727+
yield [
728+
'OK',
729+
'/** @pure-unless-callable-is-impure $foo */',
730+
new PhpDocNode([
731+
new PhpDocTagNode(
732+
'@pure-unless-callable-is-impure',
733+
new PureUnlessCallableIsImpureTagValueNode(
734+
'$foo',
735+
'',
736+
),
737+
),
738+
]),
739+
];
740+
741+
yield [
742+
'OK with description',
743+
'/** @pure-unless-callable-is-impure $foo test two three */',
744+
new PhpDocNode([
745+
new PhpDocTagNode(
746+
'@pure-unless-callable-is-impure',
747+
new PureUnlessCallableIsImpureTagValueNode(
748+
'$foo',
749+
'test two three',
750+
),
751+
),
752+
]),
753+
];
754+
}
755+
723756
public function provideVarTagsData(): Iterator
724757
{
725758
yield [

‎tests/PHPStan/Printer/PrinterTest.php

+19
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
2424
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode;
2525
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
26+
use PHPStan\PhpDocParser\Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode;
2627
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
2728
use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode;
2829
use PHPStan\PhpDocParser\Ast\PhpDoc\TypeAliasImportTagValueNode;
@@ -1769,6 +1770,24 @@ public function enterNode(Node $node)
17691770
},
17701771
];
17711772

1773+
yield [
1774+
'/** @pure-unless-callable-is-impure $foo test */',
1775+
'/** @pure-unless-callable-is-impure $bar foo */',
1776+
new class extends AbstractNodeVisitor {
1777+
1778+
public function enterNode(Node $node)
1779+
{
1780+
if ($node instanceof PureUnlessCallableIsImpureTagValueNode) {
1781+
$node->parameterName = '$bar';
1782+
$node->description = 'foo';
1783+
}
1784+
1785+
return $node;
1786+
}
1787+
1788+
},
1789+
];
1790+
17721791
yield [
17731792
'/** @return Foo[abc] */',
17741793
'/** @return self::FOO[abc] */',

0 commit comments

Comments
 (0)
Failed to load comments.