Add equality assert syntax

This commit is contained in:
Richard van Velzen 2022-10-21 09:21:14 +02:00 committed by Ondřej Mirtes
parent ae85d4b73c
commit 33aefcdab4
5 changed files with 59 additions and 9 deletions

View File

@ -23,15 +23,19 @@ class AssertTagMethodValueNode implements PhpDocTagValueNode
/** @var bool */ /** @var bool */
public $isNegated; public $isNegated;
/** @var bool */
public $isEquality;
/** @var string (may be empty) */ /** @var string (may be empty) */
public $description; public $description;
public function __construct(TypeNode $type, string $parameter, string $method, bool $isNegated, string $description) public function __construct(TypeNode $type, string $parameter, string $method, bool $isNegated, string $description, bool $isEquality = false)
{ {
$this->type = $type; $this->type = $type;
$this->parameter = $parameter; $this->parameter = $parameter;
$this->method = $method; $this->method = $method;
$this->isNegated = $isNegated; $this->isNegated = $isNegated;
$this->isEquality = $isEquality;
$this->description = $description; $this->description = $description;
} }
@ -39,7 +43,8 @@ class AssertTagMethodValueNode implements PhpDocTagValueNode
public function __toString(): string public function __toString(): string
{ {
$isNegated = $this->isNegated ? '!' : ''; $isNegated = $this->isNegated ? '!' : '';
return trim("{$isNegated}{$this->type} {$this->parameter}->{$this->method}() {$this->description}"); $isEquality = $this->isEquality ? '=' : '';
return trim("{$isNegated}{$isEquality}{$this->type} {$this->parameter}->{$this->method}() {$this->description}");
} }
} }

View File

@ -23,15 +23,19 @@ class AssertTagPropertyValueNode implements PhpDocTagValueNode
/** @var bool */ /** @var bool */
public $isNegated; public $isNegated;
/** @var bool */
public $isEquality;
/** @var string (may be empty) */ /** @var string (may be empty) */
public $description; public $description;
public function __construct(TypeNode $type, string $parameter, string $property, bool $isNegated, string $description) public function __construct(TypeNode $type, string $parameter, string $property, bool $isNegated, string $description, bool $isEquality = false)
{ {
$this->type = $type; $this->type = $type;
$this->parameter = $parameter; $this->parameter = $parameter;
$this->property = $property; $this->property = $property;
$this->isNegated = $isNegated; $this->isNegated = $isNegated;
$this->isEquality = $isEquality;
$this->description = $description; $this->description = $description;
} }
@ -39,7 +43,8 @@ class AssertTagPropertyValueNode implements PhpDocTagValueNode
public function __toString(): string public function __toString(): string
{ {
$isNegated = $this->isNegated ? '!' : ''; $isNegated = $this->isNegated ? '!' : '';
return trim("{$isNegated}{$this->type} {$this->parameter}->{$this->property} {$this->description}"); $isEquality = $this->isEquality ? '=' : '';
return trim("{$isNegated}{$isEquality}{$this->type} {$this->parameter}->{$this->property} {$this->description}");
} }
} }

View File

@ -20,14 +20,18 @@ class AssertTagValueNode implements PhpDocTagValueNode
/** @var bool */ /** @var bool */
public $isNegated; public $isNegated;
/** @var bool */
public $isEquality;
/** @var string (may be empty) */ /** @var string (may be empty) */
public $description; public $description;
public function __construct(TypeNode $type, string $parameter, bool $isNegated, string $description) public function __construct(TypeNode $type, string $parameter, bool $isNegated, string $description, bool $isEquality = false)
{ {
$this->type = $type; $this->type = $type;
$this->parameter = $parameter; $this->parameter = $parameter;
$this->isNegated = $isNegated; $this->isNegated = $isNegated;
$this->isEquality = $isEquality;
$this->description = $description; $this->description = $description;
} }
@ -35,7 +39,8 @@ class AssertTagValueNode implements PhpDocTagValueNode
public function __toString(): string public function __toString(): string
{ {
$isNegated = $this->isNegated ? '!' : ''; $isNegated = $this->isNegated ? '!' : '';
return trim("{$isNegated}{$this->type} {$this->parameter} {$this->description}"); $isEquality = $this->isEquality ? '=' : '';
return trim("{$isNegated}{$isEquality}{$this->type} {$this->parameter} {$this->description}");
} }
} }

View File

@ -472,17 +472,18 @@ class PhpDocParser
private function parseAssertTagValue(TokenIterator $tokens): Ast\PhpDoc\PhpDocTagValueNode private function parseAssertTagValue(TokenIterator $tokens): Ast\PhpDoc\PhpDocTagValueNode
{ {
$isNegated = $tokens->tryConsumeTokenType(Lexer::TOKEN_NEGATED); $isNegated = $tokens->tryConsumeTokenType(Lexer::TOKEN_NEGATED);
$isEquality = $tokens->tryConsumeTokenType(Lexer::TOKEN_EQUAL);
$type = $this->typeParser->parse($tokens); $type = $this->typeParser->parse($tokens);
$parameter = $this->parseAssertParameter($tokens); $parameter = $this->parseAssertParameter($tokens);
$description = $this->parseOptionalDescription($tokens); $description = $this->parseOptionalDescription($tokens);
if (array_key_exists('method', $parameter)) { if (array_key_exists('method', $parameter)) {
return new Ast\PhpDoc\AssertTagMethodValueNode($type, $parameter['parameter'], $parameter['method'], $isNegated, $description); return new Ast\PhpDoc\AssertTagMethodValueNode($type, $parameter['parameter'], $parameter['method'], $isNegated, $description, $isEquality);
} elseif (array_key_exists('property', $parameter)) { } elseif (array_key_exists('property', $parameter)) {
return new Ast\PhpDoc\AssertTagPropertyValueNode($type, $parameter['parameter'], $parameter['property'], $isNegated, $description); return new Ast\PhpDoc\AssertTagPropertyValueNode($type, $parameter['parameter'], $parameter['property'], $isNegated, $description, $isEquality);
} }
return new Ast\PhpDoc\AssertTagValueNode($type, $parameter['parameter'], $isNegated, $description); return new Ast\PhpDoc\AssertTagValueNode($type, $parameter['parameter'], $isNegated, $description, $isEquality);
} }
/** /**

View File

@ -4002,6 +4002,40 @@ some text in the middle'
), ),
]), ]),
]; ];
yield [
'OK equality',
'/** @phpstan-assert =Type $var */',
new PhpDocNode([
new PhpDocTagNode(
'@phpstan-assert',
new AssertTagValueNode(
new IdentifierTypeNode('Type'),
'$var',
false,
'',
true
)
),
]),
];
yield [
'OK negated equality',
'/** @phpstan-assert !=Type $var */',
new PhpDocNode([
new PhpDocTagNode(
'@phpstan-assert',
new AssertTagValueNode(
new IdentifierTypeNode('Type'),
'$var',
true,
'',
true
)
),
]),
];
} }
public function providerDebug(): Iterator public function providerDebug(): Iterator