From fdf3d0eafb565d6cc4758a738fd19e1aabdab7aa Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Wed, 28 Jul 2021 16:34:10 +0200 Subject: [PATCH] Added integer range phpdoc support --- src/PhpDoc/TypeNodeResolver.php | 21 ++++++++++++ .../Analyser/data/integer-range-types.php | 33 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/PhpDoc/TypeNodeResolver.php b/src/PhpDoc/TypeNodeResolver.php index 2c9963c000..37298c94ee 100644 --- a/src/PhpDoc/TypeNodeResolver.php +++ b/src/PhpDoc/TypeNodeResolver.php @@ -474,6 +474,27 @@ private function resolveGenericTypeNode(GenericTypeNode $typeNode, NameScope $na } return new ErrorType(); + } elseif ($mainTypeName === 'int') { + if (count($genericTypes) === 2) { // int, int<1, 3> + + if ($genericTypes[0] instanceof ConstantIntegerType) { + $min = $genericTypes[0]->getValue(); + } elseif ($typeNode->genericTypes[0] instanceof IdentifierTypeNode && $typeNode->genericTypes[0]->name === 'min') { + $min = null; + } else { + return new ErrorType(); + } + + if ($genericTypes[1] instanceof ConstantIntegerType) { + $max = $genericTypes[1]->getValue(); + } elseif ($typeNode->genericTypes[1] instanceof IdentifierTypeNode && $typeNode->genericTypes[1]->name === 'max') { + $max = null; + } else { + return new ErrorType(); + } + + return IntegerRangeType::fromInterval($min, $max); + } } $mainType = $this->resolveIdentifierTypeNode($typeNode->type, $nameScope); diff --git a/tests/PHPStan/Analyser/data/integer-range-types.php b/tests/PHPStan/Analyser/data/integer-range-types.php index 794c339935..53a37bd563 100644 --- a/tests/PHPStan/Analyser/data/integer-range-types.php +++ b/tests/PHPStan/Analyser/data/integer-range-types.php @@ -156,3 +156,36 @@ function (int $a, int $b, int $c): void { assertType('int', $b * $c); assertType('int', $a * $b * $c); }; + +class X { + /** + * @var int<0, 100> + */ + public $percentage; + /** + * @var int + */ + public $min; + /** + * @var int<0, max> + */ + public $max; + + /** + * @var int<0, something> + */ + public $error1; + /** + * @var int + */ + public $error2; + + public function supportsPhpdocIntegerRange() { + assertType('int<0, 100>', $this->percentage); + assertType('int', $this->min); + assertType('int<0, max>', $this->max); + + assertType('*ERROR*', $this->error1); + assertType('*ERROR*', $this->error2); + } +}