Add support for constant types.

phpstan supports contant definitions and expressions to
link to constants.
This commit is contained in:
Jaapio
2022-11-04 11:21:53 +01:00
parent 8d57d3da2d
commit 50bf16734e
8 changed files with 206 additions and 62 deletions
+35 -4
View File
@@ -4,10 +4,15 @@ declare(strict_types=1);
namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
use phpDocumentor\Reflection\FqsenResolver;
use phpDocumentor\Reflection\PseudoTypes\ArrayShape;
use phpDocumentor\Reflection\PseudoTypes\ArrayShapeItem;
use phpDocumentor\Reflection\PseudoTypes\ConstExpression;
use phpDocumentor\Reflection\PseudoTypes\FloatValue;
use phpDocumentor\Reflection\PseudoTypes\IntegerRange;
use phpDocumentor\Reflection\PseudoTypes\IntegerValue;
use phpDocumentor\Reflection\PseudoTypes\List_;
use phpDocumentor\Reflection\PseudoTypes\StringValue;
use phpDocumentor\Reflection\Type;
use phpDocumentor\Reflection\TypeResolver;
use phpDocumentor\Reflection\Types\Array_;
@@ -20,6 +25,10 @@ use phpDocumentor\Reflection\Types\InterfaceString;
use phpDocumentor\Reflection\Types\Intersection;
use phpDocumentor\Reflection\Types\Nullable;
use phpDocumentor\Reflection\Types\This;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprFloatNode;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprStringNode;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstFetchNode;
use PHPStan\PhpDocParser\Ast\Type\ArrayShapeItemNode;
use PHPStan\PhpDocParser\Ast\Type\ArrayShapeNode;
use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode;
@@ -48,10 +57,12 @@ use function strtolower;
final class TypeFactory
{
private TypeResolver $resolver;
private FqsenResolver $fqsenResolver;
public function __construct(TypeResolver $resolver)
public function __construct(TypeResolver $resolver, FqsenResolver $fqsenResolver)
{
$this->resolver = $resolver;
$this->fqsenResolver = $fqsenResolver;
}
public function createType(?TypeNode $type, ?Context $context): ?Type
@@ -82,7 +93,7 @@ final class TypeFactory
return $this->createFromCallable($type, $context);
case ConstTypeNode::class:
return null;
return $this->createFromConst($type, $context);
case GenericTypeNode::class:
return $this->createFromGeneric($type, $context);
@@ -144,12 +155,12 @@ final class TypeFactory
case 'class-string':
return new ClassString(
$this->createType($type->genericTypes[0], $context)->getFqsen()
$this->fqsenResolver->resolve((string) $type->genericTypes[0], $context)
);
case 'interface-string':
return new InterfaceString(
$this->createType($type->genericTypes[0], $context)->getFqsen()
$this->fqsenResolver->resolve((string) $type->genericTypes[0], $context)
);
case 'list':
@@ -180,4 +191,24 @@ final class TypeFactory
{
return new Callable_();
}
private function createFromConst(ConstTypeNode $type, ?Context $context): ?Type
{
switch (get_class($type->constExpr)) {
case ConstExprIntegerNode::class:
return new IntegerValue((int) $type->constExpr->value);
case ConstExprFloatNode::class:
return new FloatValue((float) $type->constExpr->value);
case ConstExprStringNode::class:
return new StringValue($type->constExpr->value);
case ConstFetchNode::class:
return new ConstExpression(
$this->fqsenResolver->resolve($type->constExpr->className, $context),
$type->constExpr->name
);
}
}
}