Skip to content

Commit

Permalink
Introduce TypelessParamTagValueNode
Browse files Browse the repository at this point in the history
  • Loading branch information
rvanvelzen committed Jun 8, 2022
1 parent 66ae696 commit 1c74ef3
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 74 deletions.
7 changes: 3 additions & 4 deletions src/Ast/PhpDoc/ParamTagValueNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class ParamTagValueNode implements PhpDocTagValueNode

use NodeAttributes;

/** @var TypeNode|null */
/** @var TypeNode */
public $type;

/** @var bool */
Expand All @@ -26,7 +26,7 @@ class ParamTagValueNode implements PhpDocTagValueNode
/** @var string (may be empty) */
public $description;

public function __construct(?TypeNode $type, bool $isVariadic, string $parameterName, string $description, bool $isReference = false)
public function __construct(TypeNode $type, bool $isVariadic, string $parameterName, string $description, bool $isReference = false)
{
$this->type = $type;
$this->isReference = $isReference;
Expand All @@ -38,10 +38,9 @@ public function __construct(?TypeNode $type, bool $isVariadic, string $parameter

public function __toString(): string
{
$type = $this->type !== null ? "{$this->type} " : '';
$reference = $this->isReference ? '&' : '';
$variadic = $this->isVariadic ? '...' : '';
return trim("{$type}{$reference}{$variadic}{$this->parameterName} {$this->description}");
return trim("{$this->type} {$reference}{$variadic}{$this->parameterName} {$this->description}");
}

}
14 changes: 14 additions & 0 deletions src/Ast/PhpDoc/PhpDocNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,20 @@ static function (PhpDocTagValueNode $value): bool {
}


/**
* @return ParamTagValueNode[]
*/
public function getTypelessParamTagValues(string $tagName = '@param'): array
{
return array_filter(
array_column($this->getTagsByName($tagName), 'value'),
static function (PhpDocTagValueNode $value): bool {
return $value instanceof TypelessParamTagValueNode;
}
);
}


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

namespace PHPStan\PhpDocParser\Ast\PhpDoc;

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

class TypelessParamTagValueNode implements PhpDocTagValueNode
{

use NodeAttributes;

/** @var bool */
public $isReference;

/** @var bool */
public $isVariadic;

/** @var string */
public $parameterName;

/** @var string */
public $description;

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


public function __toString(): string
{
$reference = $this->isReference ? '&' : '';
$variadic = $this->isVariadic ? '...' : '';
return trim("{$reference}{$variadic}{$this->parameterName} {$this->description}");
}

}
15 changes: 12 additions & 3 deletions src/Parser/PhpDocParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,10 @@ public function parseTagValue(TokenIterator $tokens, string $tag): Ast\PhpDoc\Ph
}


private function parseParamTagValue(TokenIterator $tokens): Ast\PhpDoc\ParamTagValueNode
/**
* @return Ast\PhpDoc\ParamTagValueNode|Ast\PhpDoc\TypelessParamTagValueNode
*/
private function parseParamTagValue(TokenIterator $tokens): Ast\PhpDoc\PhpDocTagValueNode
{
if (
$tokens->isCurrentTokenType(Lexer::TOKEN_REFERENCE)
Expand All @@ -246,8 +249,14 @@ private function parseParamTagValue(TokenIterator $tokens): Ast\PhpDoc\ParamTagV
$isReference = $tokens->tryConsumeTokenType(Lexer::TOKEN_REFERENCE);
$isVariadic = $tokens->tryConsumeTokenType(Lexer::TOKEN_VARIADIC);
$parameterName = $this->parseRequiredVariableName($tokens);
$description = $type === null ? $this->parseRequiredDescription($tokens) : $this->parseOptionalDescription($tokens);
return new Ast\PhpDoc\ParamTagValueNode($type, $isVariadic, $parameterName, $description, $isReference);

if ($type !== null) {
$description = $this->parseOptionalDescription($tokens);
return new Ast\PhpDoc\ParamTagValueNode($type, $isVariadic, $parameterName, $description, $isReference);
}

$description = $this->parseRequiredDescription($tokens);
return new Ast\PhpDoc\TypelessParamTagValueNode($isVariadic, $parameterName, $description, $isReference);
}


Expand Down
134 changes: 67 additions & 67 deletions tests/PHPStan/Parser/PhpDocParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use PHPStan\PhpDocParser\Ast\PhpDoc\ThrowsTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\TypeAliasImportTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\TypeAliasTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\TypelessParamTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\UsesTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode;
Expand Down Expand Up @@ -64,6 +65,7 @@ protected function setUp(): void
/**
* @dataProvider provideTagsWithNumbers
* @dataProvider provideParamTagsData
* @dataProvider provideTypelessParamTagsData
* @dataProvider provideVarTagsData
* @dataProvider provideReturnTagsData
* @dataProvider provideThrowsTagsData
Expand Down Expand Up @@ -242,72 +244,6 @@ public function provideParamTagsData(): Iterator
]),
];

yield [
'OK without type',
'/** @param $foo description */',
new PhpDocNode([
new PhpDocTagNode(
'@param',
new ParamTagValueNode(
null,
false,
'$foo',
'description'
)
),
]),
];

yield [
'OK reference without type',
'/** @param &$foo description */',
new PhpDocNode([
new PhpDocTagNode(
'@param',
new ParamTagValueNode(
null,
false,
'$foo',
'description',
true
)
),
]),
];

yield [
'OK variadic without type',
'/** @param ...$foo description */',
new PhpDocNode([
new PhpDocTagNode(
'@param',
new ParamTagValueNode(
null,
true,
'$foo',
'description'
)
),
]),
];

yield [
'OK reference variadic without type',
'/** @param &...$foo description */',
new PhpDocNode([
new PhpDocTagNode(
'@param',
new ParamTagValueNode(
null,
true,
'$foo',
'description',
true
)
),
]),
];

yield [
'invalid without type, parameter name and description',
'/** @param */',
Expand Down Expand Up @@ -459,6 +395,71 @@ public function provideParamTagsData(): Iterator
),
]),
];
}

public function provideTypelessParamTagsData(): Iterator
{
yield [
'OK',
'/** @param $foo description */',
new PhpDocNode([
new PhpDocTagNode(
'@param',
new TypelessParamTagValueNode(
false,
'$foo',
'description'
)
),
]),
];

yield [
'OK reference',
'/** @param &$foo description */',
new PhpDocNode([
new PhpDocTagNode(
'@param',
new TypelessParamTagValueNode(
false,
'$foo',
'description',
true
)
),
]),
];

yield [
'OK variadic',
'/** @param ...$foo description */',
new PhpDocNode([
new PhpDocTagNode(
'@param',
new TypelessParamTagValueNode(
true,
'$foo',
'description'
)
),
]),
];

yield [
'OK reference variadic',
'/** @param &...$foo description */',
new PhpDocNode([
new PhpDocTagNode(
'@param',
new TypelessParamTagValueNode(
true,
'$foo',
'description',
true
)
),
]),
];

yield [
'invalid without type and description',
Expand All @@ -480,7 +481,6 @@ public function provideParamTagsData(): Iterator
];
}


public function provideVarTagsData(): Iterator
{
yield [
Expand Down

0 comments on commit 1c74ef3

Please sign in to comment.