-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
/
CollectionType.php
118 lines (100 loc) · 3.14 KB
/
CollectionType.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeIdentifier;
/**
* Represents a key/value collection type.
*
* It proxies every method to the main type and adds methods related to key and value types.
*
* @author Mathias Arlaud <mathias.arlaud@gmail.com>
* @author Baptiste Leduc <baptiste.leduc@gmail.com>
*
* @template T of BuiltinType<TypeIdentifier::ARRAY>|BuiltinType<TypeIdentifier::ITERABLE>|ObjectType|GenericType
*/
final class CollectionType extends Type
{
/**
* @param T $type
*/
public function __construct(
private readonly BuiltinType|ObjectType|GenericType $type,
private readonly bool $isList = false,
) {
if ($this->isList()) {
$keyType = $this->getCollectionKeyType();
if (!$keyType instanceof BuiltinType || TypeIdentifier::INT !== $keyType->getTypeIdentifier()) {
throw new InvalidArgumentException(sprintf('"%s" is not a valid list key type.', (string) $keyType));
}
}
}
public function getBaseType(): BuiltinType|ObjectType
{
return $this->getType()->getBaseType();
}
/**
* @return T
*/
public function getType(): BuiltinType|ObjectType|GenericType
{
return $this->type;
}
public function isA(TypeIdentifier|string $subject): bool
{
return $this->getType()->isA($subject);
}
public function isList(): bool
{
return $this->isList;
}
public function asNonNullable(): self
{
return $this;
}
public function getCollectionKeyType(): Type
{
$defaultCollectionKeyType = self::union(self::int(), self::string());
if ($this->type instanceof GenericType) {
return match (\count($this->type->getVariableTypes())) {
2 => $this->type->getVariableTypes()[0],
1 => self::int(),
default => $defaultCollectionKeyType,
};
}
return $defaultCollectionKeyType;
}
public function getCollectionValueType(): Type
{
$defaultCollectionValueType = self::mixed();
if ($this->type instanceof GenericType) {
return match (\count($this->type->getVariableTypes())) {
2 => $this->type->getVariableTypes()[1],
1 => $this->type->getVariableTypes()[0],
default => $defaultCollectionValueType,
};
}
return $defaultCollectionValueType;
}
public function __toString(): string
{
return (string) $this->type;
}
/**
* Proxies all method calls to the original type.
*
* @param list<mixed> $arguments
*/
public function __call(string $method, array $arguments): mixed
{
return $this->type->{$method}(...$arguments);
}
}