1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Type;
4:
5: use PHPStan\Php\PhpVersion;
6: use PHPStan\Reflection\ClassMemberAccessAnswerer;
7: use PHPStan\Reflection\ConstantReflection;
8: use PHPStan\Reflection\ExtendedMethodReflection;
9: use PHPStan\Reflection\ParametersAcceptor;
10: use PHPStan\Reflection\PropertyReflection;
11: use PHPStan\Reflection\TrivialParametersAcceptor;
12: use PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection;
13: use PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection;
14: use PHPStan\ShouldNotHappenException;
15: use PHPStan\TrinaryLogic;
16: use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
17: use PHPStan\Type\Traits\NonGenericTypeTrait;
18: use PHPStan\Type\Traits\NonRemoveableTypeTrait;
19: use PHPStan\Type\Traits\UndecidedBooleanTypeTrait;
20: use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
21:
22: /** @api */
23: class NeverType implements CompoundType
24: {
25:
26: use UndecidedBooleanTypeTrait;
27: use NonGenericTypeTrait;
28: use UndecidedComparisonCompoundTypeTrait;
29: use NonRemoveableTypeTrait;
30: use NonGeneralizableTypeTrait;
31:
32: /** @api */
33: public function __construct(private bool $isExplicit = false)
34: {
35: }
36:
37: public function isExplicit(): bool
38: {
39: return $this->isExplicit;
40: }
41:
42: /**
43: * @return string[]
44: */
45: public function getReferencedClasses(): array
46: {
47: return [];
48: }
49:
50: public function getArrays(): array
51: {
52: return [];
53: }
54:
55: public function getConstantArrays(): array
56: {
57: return [];
58: }
59:
60: public function getObjectClassNames(): array
61: {
62: return [];
63: }
64:
65: public function getObjectClassReflections(): array
66: {
67: return [];
68: }
69:
70: public function getConstantStrings(): array
71: {
72: return [];
73: }
74:
75: public function accepts(Type $type, bool $strictTypes): TrinaryLogic
76: {
77: return $this->acceptsWithReason($type, $strictTypes)->result;
78: }
79:
80: public function acceptsWithReason(Type $type, bool $strictTypes): AcceptsResult
81: {
82: return AcceptsResult::createYes();
83: }
84:
85: public function isSuperTypeOf(Type $type): TrinaryLogic
86: {
87: if ($type instanceof self) {
88: return TrinaryLogic::createYes();
89: }
90:
91: return TrinaryLogic::createNo();
92: }
93:
94: public function equals(Type $type): bool
95: {
96: return $type instanceof self;
97: }
98:
99: public function isSubTypeOf(Type $otherType): TrinaryLogic
100: {
101: return TrinaryLogic::createYes();
102: }
103:
104: public function isAcceptedBy(Type $acceptingType, bool $strictTypes): TrinaryLogic
105: {
106: return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result;
107: }
108:
109: public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes): AcceptsResult
110: {
111: return new AcceptsResult($this->isSubTypeOf($acceptingType), []);
112: }
113:
114: public function describe(VerbosityLevel $level): string
115: {
116: return '*NEVER*';
117: }
118:
119: public function getTemplateType(string $ancestorClassName, string $templateTypeName): Type
120: {
121: return new NeverType();
122: }
123:
124: public function isObject(): TrinaryLogic
125: {
126: return TrinaryLogic::createNo();
127: }
128:
129: public function isEnum(): TrinaryLogic
130: {
131: return TrinaryLogic::createNo();
132: }
133:
134: public function canAccessProperties(): TrinaryLogic
135: {
136: return TrinaryLogic::createYes();
137: }
138:
139: public function hasProperty(string $propertyName): TrinaryLogic
140: {
141: return TrinaryLogic::createNo();
142: }
143:
144: public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope): PropertyReflection
145: {
146: throw new ShouldNotHappenException();
147: }
148:
149: public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope): UnresolvedPropertyPrototypeReflection
150: {
151: throw new ShouldNotHappenException();
152: }
153:
154: public function canCallMethods(): TrinaryLogic
155: {
156: return TrinaryLogic::createYes();
157: }
158:
159: public function hasMethod(string $methodName): TrinaryLogic
160: {
161: return TrinaryLogic::createNo();
162: }
163:
164: public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope): ExtendedMethodReflection
165: {
166: throw new ShouldNotHappenException();
167: }
168:
169: public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope): UnresolvedMethodPrototypeReflection
170: {
171: throw new ShouldNotHappenException();
172: }
173:
174: public function canAccessConstants(): TrinaryLogic
175: {
176: return TrinaryLogic::createYes();
177: }
178:
179: public function hasConstant(string $constantName): TrinaryLogic
180: {
181: return TrinaryLogic::createNo();
182: }
183:
184: public function getConstant(string $constantName): ConstantReflection
185: {
186: throw new ShouldNotHappenException();
187: }
188:
189: public function isIterable(): TrinaryLogic
190: {
191: return TrinaryLogic::createYes();
192: }
193:
194: public function isIterableAtLeastOnce(): TrinaryLogic
195: {
196: return TrinaryLogic::createMaybe();
197: }
198:
199: public function getArraySize(): Type
200: {
201: return new NeverType();
202: }
203:
204: public function getIterableKeyType(): Type
205: {
206: return new NeverType();
207: }
208:
209: public function getFirstIterableKeyType(): Type
210: {
211: return new NeverType();
212: }
213:
214: public function getLastIterableKeyType(): Type
215: {
216: return new NeverType();
217: }
218:
219: public function getIterableValueType(): Type
220: {
221: return new NeverType();
222: }
223:
224: public function getFirstIterableValueType(): Type
225: {
226: return new NeverType();
227: }
228:
229: public function getLastIterableValueType(): Type
230: {
231: return new NeverType();
232: }
233:
234: public function isArray(): TrinaryLogic
235: {
236: return TrinaryLogic::createNo();
237: }
238:
239: public function isConstantArray(): TrinaryLogic
240: {
241: return TrinaryLogic::createNo();
242: }
243:
244: public function isOversizedArray(): TrinaryLogic
245: {
246: return TrinaryLogic::createNo();
247: }
248:
249: public function isList(): TrinaryLogic
250: {
251: return TrinaryLogic::createNo();
252: }
253:
254: public function isOffsetAccessible(): TrinaryLogic
255: {
256: return TrinaryLogic::createYes();
257: }
258:
259: public function hasOffsetValueType(Type $offsetType): TrinaryLogic
260: {
261: return TrinaryLogic::createYes();
262: }
263:
264: public function getOffsetValueType(Type $offsetType): Type
265: {
266: return new NeverType();
267: }
268:
269: public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = true): Type
270: {
271: return new ErrorType();
272: }
273:
274: public function unsetOffset(Type $offsetType): Type
275: {
276: return new NeverType();
277: }
278:
279: public function getKeysArray(): Type
280: {
281: return new NeverType();
282: }
283:
284: public function getValuesArray(): Type
285: {
286: return new NeverType();
287: }
288:
289: public function fillKeysArray(Type $valueType): Type
290: {
291: return new NeverType();
292: }
293:
294: public function flipArray(): Type
295: {
296: return new NeverType();
297: }
298:
299: public function intersectKeyArray(Type $otherArraysType): Type
300: {
301: return new NeverType();
302: }
303:
304: public function popArray(): Type
305: {
306: return new NeverType();
307: }
308:
309: public function searchArray(Type $needleType): Type
310: {
311: return new NeverType();
312: }
313:
314: public function shiftArray(): Type
315: {
316: return new NeverType();
317: }
318:
319: public function shuffleArray(): Type
320: {
321: return new NeverType();
322: }
323:
324: public function isCallable(): TrinaryLogic
325: {
326: return TrinaryLogic::createYes();
327: }
328:
329: /**
330: * @return ParametersAcceptor[]
331: */
332: public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array
333: {
334: return [new TrivialParametersAcceptor()];
335: }
336:
337: public function isCloneable(): TrinaryLogic
338: {
339: return TrinaryLogic::createYes();
340: }
341:
342: public function toNumber(): Type
343: {
344: return $this;
345: }
346:
347: public function toString(): Type
348: {
349: return $this;
350: }
351:
352: public function toInteger(): Type
353: {
354: return $this;
355: }
356:
357: public function toFloat(): Type
358: {
359: return $this;
360: }
361:
362: public function toArray(): Type
363: {
364: return $this;
365: }
366:
367: public function toArrayKey(): Type
368: {
369: return $this;
370: }
371:
372: public function traverse(callable $cb): Type
373: {
374: return $this;
375: }
376:
377: public function isNull(): TrinaryLogic
378: {
379: return TrinaryLogic::createNo();
380: }
381:
382: public function isConstantValue(): TrinaryLogic
383: {
384: return TrinaryLogic::createNo();
385: }
386:
387: public function isConstantScalarValue(): TrinaryLogic
388: {
389: return TrinaryLogic::createNo();
390: }
391:
392: public function getConstantScalarTypes(): array
393: {
394: return [];
395: }
396:
397: public function getConstantScalarValues(): array
398: {
399: return [];
400: }
401:
402: public function isTrue(): TrinaryLogic
403: {
404: return TrinaryLogic::createNo();
405: }
406:
407: public function isFalse(): TrinaryLogic
408: {
409: return TrinaryLogic::createNo();
410: }
411:
412: public function isBoolean(): TrinaryLogic
413: {
414: return TrinaryLogic::createNo();
415: }
416:
417: public function isFloat(): TrinaryLogic
418: {
419: return TrinaryLogic::createNo();
420: }
421:
422: public function isInteger(): TrinaryLogic
423: {
424: return TrinaryLogic::createNo();
425: }
426:
427: public function isString(): TrinaryLogic
428: {
429: return TrinaryLogic::createNo();
430: }
431:
432: public function isNumericString(): TrinaryLogic
433: {
434: return TrinaryLogic::createNo();
435: }
436:
437: public function isNonEmptyString(): TrinaryLogic
438: {
439: return TrinaryLogic::createNo();
440: }
441:
442: public function isNonFalsyString(): TrinaryLogic
443: {
444: return TrinaryLogic::createNo();
445: }
446:
447: public function isLiteralString(): TrinaryLogic
448: {
449: return TrinaryLogic::createNo();
450: }
451:
452: public function isClassStringType(): TrinaryLogic
453: {
454: return TrinaryLogic::createNo();
455: }
456:
457: public function getClassStringObjectType(): Type
458: {
459: return new ErrorType();
460: }
461:
462: public function getObjectTypeOrClassStringObjectType(): Type
463: {
464: return new ErrorType();
465: }
466:
467: public function isVoid(): TrinaryLogic
468: {
469: return TrinaryLogic::createNo();
470: }
471:
472: public function isScalar(): TrinaryLogic
473: {
474: return TrinaryLogic::createNo();
475: }
476:
477: public function looseCompare(Type $type, PhpVersion $phpVersion): BooleanType
478: {
479: return new BooleanType();
480: }
481:
482: public function getEnumCases(): array
483: {
484: return [];
485: }
486:
487: public function exponentiate(Type $exponent): Type
488: {
489: return $this;
490: }
491:
492: /**
493: * @param mixed[] $properties
494: */
495: public static function __set_state(array $properties): Type
496: {
497: return new self($properties['isExplicit']);
498: }
499:
500: }
501: