1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Type;
4:
5: use PHPStan\Type\Constant\ConstantArrayTypeBuilder;
6: use PHPStan\Type\Constant\ConstantBooleanType;
7: use PHPStan\Type\Constant\ConstantFloatType;
8: use PHPStan\Type\Constant\ConstantIntegerType;
9: use PHPStan\Type\Constant\ConstantStringType;
10: use PHPStan\Type\Enum\EnumCaseObjectType;
11: use UnitEnum;
12: use function count;
13: use function function_exists;
14: use function get_class;
15: use function is_array;
16: use function is_bool;
17: use function is_float;
18: use function is_int;
19: use function is_nan;
20: use function is_object;
21: use function is_string;
22:
23: /**
24: * @api
25: */
26: final class ConstantTypeHelper
27: {
28:
29: /**
30: * @param mixed $value
31: */
32: public static function getTypeFromValue($value): Type
33: {
34: if (is_int($value)) {
35: return new ConstantIntegerType($value);
36: } elseif (is_float($value)) {
37: if (is_nan($value)) {
38: return new MixedType();
39: }
40: return new ConstantFloatType($value);
41: } elseif (is_bool($value)) {
42: return new ConstantBooleanType($value);
43: } elseif ($value === null) {
44: return new NullType();
45: } elseif (is_string($value)) {
46: return new ConstantStringType($value);
47: } elseif (is_array($value)) {
48: $arrayBuilder = ConstantArrayTypeBuilder::createEmpty();
49: if (count($value) > ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT) {
50: $arrayBuilder->degradeToGeneralArray(true);
51: }
52: foreach ($value as $k => $v) {
53: $arrayBuilder->setOffsetValueType(self::getTypeFromValue($k), self::getTypeFromValue($v));
54: }
55: return $arrayBuilder->getArray();
56: } elseif (is_object($value)) {
57: $class = get_class($value);
58: /** phpcs:disable SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName */
59: if (function_exists('enum_exists') && \enum_exists($class)) {
60: /** @var UnitEnum $value */
61: return new EnumCaseObjectType($class, $value->name);
62: }
63: /** phpcs:enable */
64:
65: return new ObjectType(get_class($value));
66: }
67:
68: return new MixedType();
69: }
70:
71: }
72: