1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Type;
4:
5: use PHPStan\Reflection\ClassMemberAccessAnswerer;
6: use PHPStan\Reflection\ConstantReflection;
7: use PHPStan\Reflection\MethodReflection;
8: use PHPStan\Reflection\ParametersAcceptor;
9: use PHPStan\Reflection\PropertyReflection;
10: use PHPStan\Reflection\TrivialParametersAcceptor;
11: use PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection;
12: use PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection;
13: use PHPStan\ShouldNotHappenException;
14: use PHPStan\TrinaryLogic;
15: use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
16: use PHPStan\Type\Traits\NonGenericTypeTrait;
17: use PHPStan\Type\Traits\NonRemoveableTypeTrait;
18: use PHPStan\Type\Traits\UndecidedBooleanTypeTrait;
19: use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
20:
21: /** @api */
22: class NeverType implements CompoundType
23: {
24:
25: use UndecidedBooleanTypeTrait;
26: use NonGenericTypeTrait;
27: use UndecidedComparisonCompoundTypeTrait;
28: use NonRemoveableTypeTrait;
29: use NonGeneralizableTypeTrait;
30:
31: /** @api */
32: public function __construct(private bool $isExplicit = false)
33: {
34: }
35:
36: public function isExplicit(): bool
37: {
38: return $this->isExplicit;
39: }
40:
41: /**
42: * @return string[]
43: */
44: public function getReferencedClasses(): array
45: {
46: return [];
47: }
48:
49: public function accepts(Type $type, bool $strictTypes): TrinaryLogic
50: {
51: return TrinaryLogic::createYes();
52: }
53:
54: public function isSuperTypeOf(Type $type): TrinaryLogic
55: {
56: if ($type instanceof self) {
57: return TrinaryLogic::createYes();
58: }
59:
60: return TrinaryLogic::createNo();
61: }
62:
63: public function equals(Type $type): bool
64: {
65: return $type instanceof self;
66: }
67:
68: public function isSubTypeOf(Type $otherType): TrinaryLogic
69: {
70: return TrinaryLogic::createYes();
71: }
72:
73: public function isAcceptedBy(Type $acceptingType, bool $strictTypes): TrinaryLogic
74: {
75: return $this->isSubTypeOf($acceptingType);
76: }
77:
78: public function describe(VerbosityLevel $level): string
79: {
80: return '*NEVER*';
81: }
82:
83: public function canAccessProperties(): TrinaryLogic
84: {
85: return TrinaryLogic::createYes();
86: }
87:
88: public function hasProperty(string $propertyName): TrinaryLogic
89: {
90: return TrinaryLogic::createNo();
91: }
92:
93: public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope): PropertyReflection
94: {
95: throw new ShouldNotHappenException();
96: }
97:
98: public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope): UnresolvedPropertyPrototypeReflection
99: {
100: throw new ShouldNotHappenException();
101: }
102:
103: public function canCallMethods(): TrinaryLogic
104: {
105: return TrinaryLogic::createYes();
106: }
107:
108: public function hasMethod(string $methodName): TrinaryLogic
109: {
110: return TrinaryLogic::createNo();
111: }
112:
113: public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope): MethodReflection
114: {
115: throw new ShouldNotHappenException();
116: }
117:
118: public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope): UnresolvedMethodPrototypeReflection
119: {
120: throw new ShouldNotHappenException();
121: }
122:
123: public function canAccessConstants(): TrinaryLogic
124: {
125: return TrinaryLogic::createYes();
126: }
127:
128: public function hasConstant(string $constantName): TrinaryLogic
129: {
130: return TrinaryLogic::createNo();
131: }
132:
133: public function getConstant(string $constantName): ConstantReflection
134: {
135: throw new ShouldNotHappenException();
136: }
137:
138: public function isIterable(): TrinaryLogic
139: {
140: return TrinaryLogic::createYes();
141: }
142:
143: public function isIterableAtLeastOnce(): TrinaryLogic
144: {
145: return TrinaryLogic::createMaybe();
146: }
147:
148: public function getIterableKeyType(): Type
149: {
150: return new NeverType();
151: }
152:
153: public function getIterableValueType(): Type
154: {
155: return new NeverType();
156: }
157:
158: public function isOffsetAccessible(): TrinaryLogic
159: {
160: return TrinaryLogic::createYes();
161: }
162:
163: public function hasOffsetValueType(Type $offsetType): TrinaryLogic
164: {
165: return TrinaryLogic::createYes();
166: }
167:
168: public function getOffsetValueType(Type $offsetType): Type
169: {
170: return new NeverType();
171: }
172:
173: public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = true): Type
174: {
175: return new ErrorType();
176: }
177:
178: public function unsetOffset(Type $offsetType): Type
179: {
180: return new NeverType();
181: }
182:
183: public function isCallable(): TrinaryLogic
184: {
185: return TrinaryLogic::createYes();
186: }
187:
188: /**
189: * @return ParametersAcceptor[]
190: */
191: public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array
192: {
193: return [new TrivialParametersAcceptor()];
194: }
195:
196: public function isCloneable(): TrinaryLogic
197: {
198: return TrinaryLogic::createYes();
199: }
200:
201: public function toNumber(): Type
202: {
203: return $this;
204: }
205:
206: public function toString(): Type
207: {
208: return $this;
209: }
210:
211: public function toInteger(): Type
212: {
213: return $this;
214: }
215:
216: public function toFloat(): Type
217: {
218: return $this;
219: }
220:
221: public function toArray(): Type
222: {
223: return $this;
224: }
225:
226: public function traverse(callable $cb): Type
227: {
228: return $this;
229: }
230:
231: public function isArray(): TrinaryLogic
232: {
233: return TrinaryLogic::createNo();
234: }
235:
236: public function isOversizedArray(): TrinaryLogic
237: {
238: return TrinaryLogic::createNo();
239: }
240:
241: public function isString(): TrinaryLogic
242: {
243: return TrinaryLogic::createNo();
244: }
245:
246: public function isNumericString(): TrinaryLogic
247: {
248: return TrinaryLogic::createNo();
249: }
250:
251: public function isNonEmptyString(): TrinaryLogic
252: {
253: return TrinaryLogic::createNo();
254: }
255:
256: public function isNonFalsyString(): TrinaryLogic
257: {
258: return TrinaryLogic::createNo();
259: }
260:
261: public function isLiteralString(): TrinaryLogic
262: {
263: return TrinaryLogic::createNo();
264: }
265:
266: /**
267: * @param mixed[] $properties
268: */
269: public static function __set_state(array $properties): Type
270: {
271: return new self($properties['isExplicit']);
272: }
273:
274: }
275: