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