1: | <?php declare(strict_types = 1); |
2: | |
3: | namespace PHPStan\Type\Accessory; |
4: | |
5: | use PHPStan\TrinaryLogic; |
6: | use PHPStan\Type\CompoundType; |
7: | use PHPStan\Type\Constant\ConstantIntegerType; |
8: | use PHPStan\Type\Constant\ConstantStringType; |
9: | use PHPStan\Type\ConstantScalarType; |
10: | use PHPStan\Type\ErrorType; |
11: | use PHPStan\Type\IntersectionType; |
12: | use PHPStan\Type\MixedType; |
13: | use PHPStan\Type\Traits\MaybeCallableTypeTrait; |
14: | use PHPStan\Type\Traits\MaybeIterableTypeTrait; |
15: | use PHPStan\Type\Traits\MaybeObjectTypeTrait; |
16: | use PHPStan\Type\Traits\NonGeneralizableTypeTrait; |
17: | use PHPStan\Type\Traits\NonGenericTypeTrait; |
18: | use PHPStan\Type\Traits\NonRemoveableTypeTrait; |
19: | use PHPStan\Type\Traits\TruthyBooleanTypeTrait; |
20: | use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait; |
21: | use PHPStan\Type\Type; |
22: | use PHPStan\Type\UnionType; |
23: | use PHPStan\Type\VerbosityLevel; |
24: | use function sprintf; |
25: | |
26: | class HasOffsetType implements CompoundType, AccessoryType |
27: | { |
28: | |
29: | use MaybeCallableTypeTrait; |
30: | use MaybeIterableTypeTrait; |
31: | use MaybeObjectTypeTrait; |
32: | use TruthyBooleanTypeTrait; |
33: | use NonGenericTypeTrait; |
34: | use UndecidedComparisonCompoundTypeTrait; |
35: | use NonRemoveableTypeTrait; |
36: | use NonGeneralizableTypeTrait; |
37: | |
38: | |
39: | |
40: | |
41: | |
42: | public function __construct(private Type $offsetType) |
43: | { |
44: | } |
45: | |
46: | |
47: | |
48: | |
49: | public function getOffsetType(): Type |
50: | { |
51: | return $this->offsetType; |
52: | } |
53: | |
54: | public function getReferencedClasses(): array |
55: | { |
56: | return []; |
57: | } |
58: | |
59: | public function accepts(Type $type, bool $strictTypes): TrinaryLogic |
60: | { |
61: | if ($type instanceof CompoundType) { |
62: | return $type->isAcceptedBy($this, $strictTypes); |
63: | } |
64: | |
65: | return $type->isOffsetAccessible() |
66: | ->and($type->hasOffsetValueType($this->offsetType)); |
67: | } |
68: | |
69: | public function isSuperTypeOf(Type $type): TrinaryLogic |
70: | { |
71: | if ($this->equals($type)) { |
72: | return TrinaryLogic::createYes(); |
73: | } |
74: | return $type->isOffsetAccessible() |
75: | ->and($type->hasOffsetValueType($this->offsetType)); |
76: | } |
77: | |
78: | public function isSubTypeOf(Type $otherType): TrinaryLogic |
79: | { |
80: | if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { |
81: | return $otherType->isSuperTypeOf($this); |
82: | } |
83: | |
84: | return $otherType->isOffsetAccessible() |
85: | ->and($otherType->hasOffsetValueType($this->offsetType)) |
86: | ->and($otherType instanceof self ? TrinaryLogic::createYes() : TrinaryLogic::createMaybe()); |
87: | } |
88: | |
89: | public function isAcceptedBy(Type $acceptingType, bool $strictTypes): TrinaryLogic |
90: | { |
91: | return $this->isSubTypeOf($acceptingType); |
92: | } |
93: | |
94: | public function equals(Type $type): bool |
95: | { |
96: | return $type instanceof self |
97: | && $this->offsetType->equals($type->offsetType); |
98: | } |
99: | |
100: | public function describe(VerbosityLevel $level): string |
101: | { |
102: | return sprintf('hasOffset(%s)', $this->offsetType->describe($level)); |
103: | } |
104: | |
105: | public function isOffsetAccessible(): TrinaryLogic |
106: | { |
107: | return TrinaryLogic::createYes(); |
108: | } |
109: | |
110: | public function hasOffsetValueType(Type $offsetType): TrinaryLogic |
111: | { |
112: | if ($offsetType instanceof ConstantScalarType && $offsetType->equals($this->offsetType)) { |
113: | return TrinaryLogic::createYes(); |
114: | } |
115: | |
116: | return TrinaryLogic::createMaybe(); |
117: | } |
118: | |
119: | public function getOffsetValueType(Type $offsetType): Type |
120: | { |
121: | return new MixedType(); |
122: | } |
123: | |
124: | public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = true): Type |
125: | { |
126: | return $this; |
127: | } |
128: | |
129: | public function unsetOffset(Type $offsetType): Type |
130: | { |
131: | if ($this->offsetType->isSuperTypeOf($offsetType)->yes()) { |
132: | return new ErrorType(); |
133: | } |
134: | return $this; |
135: | } |
136: | |
137: | public function isIterableAtLeastOnce(): TrinaryLogic |
138: | { |
139: | return TrinaryLogic::createYes(); |
140: | } |
141: | |
142: | public function isArray(): TrinaryLogic |
143: | { |
144: | return TrinaryLogic::createMaybe(); |
145: | } |
146: | |
147: | public function isOversizedArray(): TrinaryLogic |
148: | { |
149: | return TrinaryLogic::createMaybe(); |
150: | } |
151: | |
152: | public function isString(): TrinaryLogic |
153: | { |
154: | return TrinaryLogic::createMaybe(); |
155: | } |
156: | |
157: | public function isNumericString(): TrinaryLogic |
158: | { |
159: | return TrinaryLogic::createMaybe(); |
160: | } |
161: | |
162: | public function isNonEmptyString(): TrinaryLogic |
163: | { |
164: | return TrinaryLogic::createMaybe(); |
165: | } |
166: | |
167: | public function isNonFalsyString(): TrinaryLogic |
168: | { |
169: | return TrinaryLogic::createMaybe(); |
170: | } |
171: | |
172: | public function isLiteralString(): TrinaryLogic |
173: | { |
174: | return TrinaryLogic::createMaybe(); |
175: | } |
176: | |
177: | public function toNumber(): Type |
178: | { |
179: | return new ErrorType(); |
180: | } |
181: | |
182: | public function toInteger(): Type |
183: | { |
184: | return new ErrorType(); |
185: | } |
186: | |
187: | public function toFloat(): Type |
188: | { |
189: | return new ErrorType(); |
190: | } |
191: | |
192: | public function toString(): Type |
193: | { |
194: | return new ErrorType(); |
195: | } |
196: | |
197: | public function toArray(): Type |
198: | { |
199: | return new MixedType(); |
200: | } |
201: | |
202: | public function traverse(callable $cb): Type |
203: | { |
204: | return $this; |
205: | } |
206: | |
207: | public static function __set_state(array $properties): Type |
208: | { |
209: | return new self($properties['offsetType']); |
210: | } |
211: | |
212: | } |
213: | |