Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/1.23.x' into 2.0.x
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Sep 26, 2024
2 parents cc479c9 + 6ca22b1 commit 426fd7a
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/Ast/PhpDoc/PhpDocNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ public function getParamClosureThisTagValues(string $tagName = '@param-closure-t
);
}

/**
* @return PureUnlessCallableIsImpureTagValueNode[]
*/
public function getPureUnlessCallableIsImpureTagValues(string $tagName = '@pure-unless-callable-is-impure'): array
{
return array_filter(
array_column($this->getTagsByName($tagName), 'value'),
static fn (PhpDocTagValueNode $value): bool => $value instanceof PureUnlessCallableIsImpureTagValueNode,
);
}

/**
* @return TemplateTagValueNode[]
Expand Down
29 changes: 29 additions & 0 deletions src/Ast/PhpDoc/PureUnlessCallableIsImpureTagValueNode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php declare(strict_types = 1);

namespace PHPStan\PhpDocParser\Ast\PhpDoc;

use PHPStan\PhpDocParser\Ast\NodeAttributes;
use function trim;

class PureUnlessCallableIsImpureTagValueNode implements PhpDocTagValueNode
{

use NodeAttributes;

public string $parameterName;

/** @var string (may be empty) */
public string $description;

public function __construct(string $parameterName, string $description)
{
$this->parameterName = $parameterName;
$this->description = $description;
}

public function __toString(): string
{
return trim("{$this->parameterName} {$this->description}");
}

}
12 changes: 12 additions & 0 deletions src/Parser/PhpDocParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,11 @@ public function parseTagValue(TokenIterator $tokens, string $tag): Ast\PhpDoc\Ph
$tagValue = $this->parseParamClosureThisTagValue($tokens);
break;

case '@pure-unless-callable-is-impure':
case '@phpstan-pure-unless-callable-is-impure':
$tagValue = $this->parsePureUnlessCallableIsImpureTagValue($tokens);
break;

case '@var':
case '@phpstan-var':
case '@psalm-var':
Expand Down Expand Up @@ -866,6 +871,13 @@ private function parseParamClosureThisTagValue(TokenIterator $tokens): Ast\PhpDo
return new Ast\PhpDoc\ParamClosureThisTagValueNode($type, $parameterName, $description);
}

private function parsePureUnlessCallableIsImpureTagValue(TokenIterator $tokens): Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode
{
$parameterName = $this->parseRequiredVariableName($tokens);
$description = $this->parseOptionalDescription($tokens, false);

return new Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode($parameterName, $description);
}

private function parseVarTagValue(TokenIterator $tokens): Ast\PhpDoc\VarTagValueNode
{
Expand Down
4 changes: 4 additions & 0 deletions src/Printer/Printer.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTextNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\RequireExtendsTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\RequireImplementsTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
Expand Down Expand Up @@ -342,6 +343,9 @@ private function printTagValue(PhpDocTagValueNode $node): string
if ($node instanceof ParamClosureThisTagValueNode) {
return trim("{$node->type} {$node->parameterName} {$node->description}");
}
if ($node instanceof PureUnlessCallableIsImpureTagValueNode) {
return trim("{$node->parameterName} {$node->description}");
}
if ($node instanceof PropertyTagValueNode) {
$type = $this->printType($node->type);
return trim("{$type} {$node->propertyName} {$node->description}");
Expand Down
33 changes: 33 additions & 0 deletions tests/PHPStan/Parser/PhpDocParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTextNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\RequireExtendsTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\RequireImplementsTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
Expand Down Expand Up @@ -96,6 +97,7 @@ protected function setUp(): void
* @dataProvider provideParamLaterInvokedCallableTagsData
* @dataProvider provideTypelessParamTagsData
* @dataProvider provideParamClosureThisTagsData
* @dataProvider providePureUnlessCallableIsImpureTagsData
* @dataProvider provideVarTagsData
* @dataProvider provideReturnTagsData
* @dataProvider provideThrowsTagsData
Expand Down Expand Up @@ -720,6 +722,37 @@ public function provideParamClosureThisTagsData(): Iterator
];
}

public function providePureUnlessCallableIsImpureTagsData(): Iterator
{
yield [
'OK',
'/** @pure-unless-callable-is-impure $foo */',
new PhpDocNode([
new PhpDocTagNode(
'@pure-unless-callable-is-impure',
new PureUnlessCallableIsImpureTagValueNode(
'$foo',
'',
),
),
]),
];

yield [
'OK with description',
'/** @pure-unless-callable-is-impure $foo test two three */',
new PhpDocNode([
new PhpDocTagNode(
'@pure-unless-callable-is-impure',
new PureUnlessCallableIsImpureTagValueNode(
'$foo',
'test two three',
),
),
]),
];
}

public function provideVarTagsData(): Iterator
{
yield [
Expand Down
19 changes: 19 additions & 0 deletions tests/PHPStan/Printer/PrinterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\TypeAliasImportTagValueNode;
Expand Down Expand Up @@ -1769,6 +1770,24 @@ public function enterNode(Node $node)
},
];

yield [
'/** @pure-unless-callable-is-impure $foo test */',
'/** @pure-unless-callable-is-impure $bar foo */',
new class extends AbstractNodeVisitor {

public function enterNode(Node $node)
{
if ($node instanceof PureUnlessCallableIsImpureTagValueNode) {
$node->parameterName = '$bar';
$node->description = 'foo';
}

return $node;
}

},
];

yield [
'/** @return Foo[abc] */',
'/** @return self::FOO[abc] */',
Expand Down

0 comments on commit 426fd7a

Please sign in to comment.