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 */
public $isNegated;
/** @var bool */
public $isEquality;
/** @var string (may be empty) */
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->parameter = $parameter;
$this->method = $method;
$this->isNegated = $isNegated;
$this->isEquality = $isEquality;
$this->description = $description;
}
@ -39,7 +43,8 @@ class AssertTagMethodValueNode implements PhpDocTagValueNode
public function __toString(): string
{
$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 */
public $isNegated;
/** @var bool */
public $isEquality;
/** @var string (may be empty) */
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->parameter = $parameter;
$this->property = $property;
$this->isNegated = $isNegated;
$this->isEquality = $isEquality;
$this->description = $description;
}
@ -39,7 +43,8 @@ class AssertTagPropertyValueNode implements PhpDocTagValueNode
public function __toString(): string
{
$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 */
public $isNegated;
/** @var bool */
public $isEquality;
/** @var string (may be empty) */
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->parameter = $parameter;
$this->isNegated = $isNegated;
$this->isEquality = $isEquality;
$this->description = $description;
}
@ -35,7 +39,8 @@ class AssertTagValueNode implements PhpDocTagValueNode
public function __toString(): string
{
$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
{
$isNegated = $tokens->tryConsumeTokenType(Lexer::TOKEN_NEGATED);
$isEquality = $tokens->tryConsumeTokenType(Lexer::TOKEN_EQUAL);
$type = $this->typeParser->parse($tokens);
$parameter = $this->parseAssertParameter($tokens);
$description = $this->parseOptionalDescription($tokens);
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)) {
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