1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Type;
4:
5: use PHPStan\Php\PhpVersion;
6: use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
7: use PHPStan\PhpDocParser\Ast\Type\TypeNode;
8: use PHPStan\Reflection\ClassConstantReflection;
9: use PHPStan\Reflection\ClassMemberAccessAnswerer;
10: use PHPStan\Reflection\ExtendedMethodReflection;
11: use PHPStan\Reflection\ExtendedPropertyReflection;
12: use PHPStan\Reflection\ReflectionProvider;
13: use PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection;
14: use PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection;
15: use PHPStan\ShouldNotHappenException;
16: use PHPStan\TrinaryLogic;
17: use PHPStan\Type\Enum\EnumCaseObjectType;
18: use PHPStan\Type\Generic\TemplateType;
19: use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
20: use PHPStan\Type\Traits\NonGenericTypeTrait;
21: use PHPStan\Type\Traits\NonRemoveableTypeTrait;
22: use PHPStan\Type\Traits\UndecidedBooleanTypeTrait;
23: use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
24:
25: /** @api */
26: class NeverType implements CompoundType
27: {
28:
29: use UndecidedBooleanTypeTrait;
30: use NonGenericTypeTrait;
31: use UndecidedComparisonCompoundTypeTrait;
32: use NonRemoveableTypeTrait;
33: use NonGeneralizableTypeTrait;
34:
35: /** @api */
36: public function __construct(private bool $isExplicit = false, private ?string $reason = null)
37: {
38: }
39:
40: public function isExplicit(): bool
41: {
42: return $this->isExplicit;
43: }
44:
45: public function getReason(): ?string
46: {
47: return $this->reason;
48: }
49:
50: public function getReferencedClasses(): array
51: {
52: return [];
53: }
54:
55: public function getArrays(): array
56: {
57: return [];
58: }
59:
60: public function getConstantArrays(): array
61: {
62: return [];
63: }
64:
65: public function getObjectClassNames(): array
66: {
67: return [];
68: }
69:
70: public function getObjectClassReflections(): array
71: {
72: return [];
73: }
74:
75: public function getConstantStrings(): array
76: {
77: return [];
78: }
79:
80: public function accepts(Type $type, bool $strictTypes): AcceptsResult
81: {
82: return AcceptsResult::createYes();
83: }
84:
85: public function isSuperTypeOf(Type $type): IsSuperTypeOfResult
86: {
87: if ($type instanceof self) {
88: return IsSuperTypeOfResult::createYes();
89: }
90:
91: if ($type instanceof TemplateType) {
92: return IsSuperTypeOfResult::createMaybe();
93: }
94:
95: return IsSuperTypeOfResult::createNo();
96: }
97:
98: public function equals(Type $type): bool
99: {
100: return $type instanceof self;
101: }
102:
103: public function isSubTypeOf(Type $otherType): IsSuperTypeOfResult
104: {
105: return IsSuperTypeOfResult::createYes();
106: }
107:
108: public function isAcceptedBy(Type $acceptingType, bool $strictTypes): AcceptsResult
109: {
110: return $this->isSubTypeOf($acceptingType)->toAcceptsResult();
111: }
112:
113: public function describe(VerbosityLevel $level): string
114: {
115: return '*NEVER*';
116: }
117:
118: public function getTemplateType(string $ancestorClassName, string $templateTypeName): Type
119: {
120: return new NeverType();
121: }
122:
123: public function isObject(): TrinaryLogic
124: {
125: return TrinaryLogic::createNo();
126: }
127:
128: public function getClassStringType(): Type
129: {
130: return new NeverType();
131: }
132:
133: public function isEnum(): TrinaryLogic
134: {
135: return TrinaryLogic::createNo();
136: }
137:
138: public function canAccessProperties(): TrinaryLogic
139: {
140: return TrinaryLogic::createYes();
141: }
142:
143: public function hasProperty(string $propertyName): TrinaryLogic
144: {
145: return TrinaryLogic::createNo();
146: }
147:
148: public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope): ExtendedPropertyReflection
149: {
150: throw new ShouldNotHappenException();
151: }
152:
153: public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope): UnresolvedPropertyPrototypeReflection
154: {
155: throw new ShouldNotHappenException();
156: }
157:
158: public function hasInstanceProperty(string $propertyName): TrinaryLogic
159: {
160: return TrinaryLogic::createNo();
161: }
162:
163: public function getInstanceProperty(string $propertyName, ClassMemberAccessAnswerer $scope): ExtendedPropertyReflection
164: {
165: throw new ShouldNotHappenException();
166: }
167:
168: public function getUnresolvedInstancePropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope): UnresolvedPropertyPrototypeReflection
169: {
170: throw new ShouldNotHappenException();
171: }
172:
173: public function hasStaticProperty(string $propertyName): TrinaryLogic
174: {
175: return TrinaryLogic::createNo();
176: }
177:
178: public function getStaticProperty(string $propertyName, ClassMemberAccessAnswerer $scope): ExtendedPropertyReflection
179: {
180: throw new ShouldNotHappenException();
181: }
182:
183: public function getUnresolvedStaticPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope): UnresolvedPropertyPrototypeReflection
184: {
185: throw new ShouldNotHappenException();
186: }
187:
188: public function canCallMethods(): TrinaryLogic
189: {
190: return TrinaryLogic::createYes();
191: }
192:
193: public function hasMethod(string $methodName): TrinaryLogic
194: {
195: return TrinaryLogic::createNo();
196: }
197:
198: public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope): ExtendedMethodReflection
199: {
200: throw new ShouldNotHappenException();
201: }
202:
203: public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope): UnresolvedMethodPrototypeReflection
204: {
205: throw new ShouldNotHappenException();
206: }
207:
208: public function canAccessConstants(): TrinaryLogic
209: {
210: return TrinaryLogic::createYes();
211: }
212:
213: public function hasConstant(string $constantName): TrinaryLogic
214: {
215: return TrinaryLogic::createNo();
216: }
217:
218: public function getConstant(string $constantName): ClassConstantReflection
219: {
220: throw new ShouldNotHappenException();
221: }
222:
223: public function isIterable(): TrinaryLogic
224: {
225: return TrinaryLogic::createYes();
226: }
227:
228: public function isIterableAtLeastOnce(): TrinaryLogic
229: {
230: return TrinaryLogic::createMaybe();
231: }
232:
233: public function getArraySize(): Type
234: {
235: return new NeverType();
236: }
237:
238: public function getIterableKeyType(): Type
239: {
240: return new NeverType();
241: }
242:
243: public function getFirstIterableKeyType(): Type
244: {
245: return new NeverType();
246: }
247:
248: public function getLastIterableKeyType(): Type
249: {
250: return new NeverType();
251: }
252:
253: public function getIterableValueType(): Type
254: {
255: return new NeverType();
256: }
257:
258: public function getFirstIterableValueType(): Type
259: {
260: return new NeverType();
261: }
262:
263: public function getLastIterableValueType(): Type
264: {
265: return new NeverType();
266: }
267:
268: public function isArray(): TrinaryLogic
269: {
270: return TrinaryLogic::createNo();
271: }
272:
273: public function isConstantArray(): TrinaryLogic
274: {
275: return TrinaryLogic::createNo();
276: }
277:
278: public function isOversizedArray(): TrinaryLogic
279: {
280: return TrinaryLogic::createNo();
281: }
282:
283: public function isList(): TrinaryLogic
284: {
285: return TrinaryLogic::createNo();
286: }
287:
288: public function isOffsetAccessible(): TrinaryLogic
289: {
290: return TrinaryLogic::createYes();
291: }
292:
293: public function isOffsetAccessLegal(): TrinaryLogic
294: {
295: return TrinaryLogic::createYes();
296: }
297:
298: public function hasOffsetValueType(Type $offsetType): TrinaryLogic
299: {
300: return TrinaryLogic::createYes();
301: }
302:
303: public function getOffsetValueType(Type $offsetType): Type
304: {
305: return new NeverType();
306: }
307:
308: public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = true): Type
309: {
310: return new ErrorType();
311: }
312:
313: public function setExistingOffsetValueType(Type $offsetType, Type $valueType): Type
314: {
315: return new ErrorType();
316: }
317:
318: public function unsetOffset(Type $offsetType): Type
319: {
320: return new NeverType();
321: }
322:
323: public function getKeysArrayFiltered(Type $filterValueType, TrinaryLogic $strict): Type
324: {
325: return $this->getKeysArray();
326: }
327:
328: public function getKeysArray(): Type
329: {
330: return new NeverType();
331: }
332:
333: public function getValuesArray(): Type
334: {
335: return new NeverType();
336: }
337:
338: public function chunkArray(Type $lengthType, TrinaryLogic $preserveKeys): Type
339: {
340: return new NeverType();
341: }
342:
343: public function fillKeysArray(Type $valueType): Type
344: {
345: return new NeverType();
346: }
347:
348: public function flipArray(): Type
349: {
350: return new NeverType();
351: }
352:
353: public function intersectKeyArray(Type $otherArraysType): Type
354: {
355: return new NeverType();
356: }
357:
358: public function popArray(): Type
359: {
360: return new NeverType();
361: }
362:
363: public function reverseArray(TrinaryLogic $preserveKeys): Type
364: {
365: return new NeverType();
366: }
367:
368: public function searchArray(Type $needleType, ?TrinaryLogic $strict = null): Type
369: {
370: return new NeverType();
371: }
372:
373: public function shiftArray(): Type
374: {
375: return new NeverType();
376: }
377:
378: public function shuffleArray(): Type
379: {
380: return new NeverType();
381: }
382:
383: public function sliceArray(Type $offsetType, Type $lengthType, TrinaryLogic $preserveKeys): Type
384: {
385: return new NeverType();
386: }
387:
388: public function spliceArray(Type $offsetType, Type $lengthType, Type $replacementType): Type
389: {
390: return new NeverType();
391: }
392:
393: public function truncateListToSize(Type $sizeType): Type
394: {
395: return new NeverType();
396: }
397:
398: public function makeListMaybe(): Type
399: {
400: return new NeverType();
401: }
402:
403: public function mapValueType(callable $cb): Type
404: {
405: return new NeverType();
406: }
407:
408: public function mapKeyType(callable $cb): Type
409: {
410: return new NeverType();
411: }
412:
413: public function makeAllArrayKeysOptional(): Type
414: {
415: return new NeverType();
416: }
417:
418: public function changeKeyCaseArray(?int $case): Type
419: {
420: return new NeverType();
421: }
422:
423: public function filterArrayRemovingFalsey(): Type
424: {
425: return new NeverType();
426: }
427:
428: public function isCallable(): TrinaryLogic
429: {
430: return TrinaryLogic::createNo();
431: }
432:
433: public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array
434: {
435: throw new ShouldNotHappenException();
436: }
437:
438: public function isCloneable(): TrinaryLogic
439: {
440: return TrinaryLogic::createYes();
441: }
442:
443: public function toNumber(): Type
444: {
445: return $this;
446: }
447:
448: public function toBitwiseNotType(): Type
449: {
450: return $this;
451: }
452:
453: public function toGetClassResultType(): Type
454: {
455: return $this;
456: }
457:
458: public function toClassConstantType(ReflectionProvider $reflectionProvider): Type
459: {
460: return $this;
461: }
462:
463: public function toObjectTypeForInstanceofCheck(): ClassNameToObjectTypeResult
464: {
465: return new ClassNameToObjectTypeResult($this, false);
466: }
467:
468: public function toObjectTypeForIsACheck(Type $objectOrClassType, bool $allowString, bool $allowSameClass): ClassNameToObjectTypeResult
469: {
470: return new ClassNameToObjectTypeResult($this, false);
471: }
472:
473: public function toAbsoluteNumber(): Type
474: {
475: return $this;
476: }
477:
478: public function toString(): Type
479: {
480: return $this;
481: }
482:
483: public function toInteger(): Type
484: {
485: return $this;
486: }
487:
488: public function toFloat(): Type
489: {
490: return $this;
491: }
492:
493: public function toArray(): Type
494: {
495: return $this;
496: }
497:
498: public function toArrayKey(): Type
499: {
500: return $this;
501: }
502:
503: public function toCoercedArgumentType(bool $strictTypes): Type
504: {
505: return $this;
506: }
507:
508: public function traverse(callable $cb): Type
509: {
510: return $this;
511: }
512:
513: public function traverseSimultaneously(Type $right, callable $cb): Type
514: {
515: return $this;
516: }
517:
518: public function isNull(): TrinaryLogic
519: {
520: return TrinaryLogic::createNo();
521: }
522:
523: public function isConstantValue(): TrinaryLogic
524: {
525: return TrinaryLogic::createNo();
526: }
527:
528: public function isConstantScalarValue(): TrinaryLogic
529: {
530: return TrinaryLogic::createNo();
531: }
532:
533: public function getConstantScalarTypes(): array
534: {
535: return [];
536: }
537:
538: public function getConstantScalarValues(): array
539: {
540: return [];
541: }
542:
543: public function isTrue(): TrinaryLogic
544: {
545: return TrinaryLogic::createNo();
546: }
547:
548: public function isFalse(): TrinaryLogic
549: {
550: return TrinaryLogic::createNo();
551: }
552:
553: public function isBoolean(): TrinaryLogic
554: {
555: return TrinaryLogic::createNo();
556: }
557:
558: public function isFloat(): TrinaryLogic
559: {
560: return TrinaryLogic::createNo();
561: }
562:
563: public function isInteger(): TrinaryLogic
564: {
565: return TrinaryLogic::createNo();
566: }
567:
568: public function isString(): TrinaryLogic
569: {
570: return TrinaryLogic::createNo();
571: }
572:
573: public function isNumericString(): TrinaryLogic
574: {
575: return TrinaryLogic::createNo();
576: }
577:
578: public function isDecimalIntegerString(): TrinaryLogic
579: {
580: return TrinaryLogic::createNo();
581: }
582:
583: public function isNonEmptyString(): TrinaryLogic
584: {
585: return TrinaryLogic::createNo();
586: }
587:
588: public function isNonFalsyString(): TrinaryLogic
589: {
590: return TrinaryLogic::createNo();
591: }
592:
593: public function isLiteralString(): TrinaryLogic
594: {
595: return TrinaryLogic::createNo();
596: }
597:
598: public function isLowercaseString(): TrinaryLogic
599: {
600: return TrinaryLogic::createNo();
601: }
602:
603: public function isUppercaseString(): TrinaryLogic
604: {
605: return TrinaryLogic::createNo();
606: }
607:
608: public function isClassString(): TrinaryLogic
609: {
610: return TrinaryLogic::createNo();
611: }
612:
613: public function getClassStringObjectType(): Type
614: {
615: return new ErrorType();
616: }
617:
618: public function getObjectTypeOrClassStringObjectType(): Type
619: {
620: return new ErrorType();
621: }
622:
623: public function isVoid(): TrinaryLogic
624: {
625: return TrinaryLogic::createNo();
626: }
627:
628: public function isScalar(): TrinaryLogic
629: {
630: return TrinaryLogic::createNo();
631: }
632:
633: public function looseCompare(Type $type, PhpVersion $phpVersion): BooleanType
634: {
635: return new BooleanType();
636: }
637:
638: public function getEnumCases(): array
639: {
640: return [];
641: }
642:
643: public function getEnumCaseObject(): ?EnumCaseObjectType
644: {
645: return null;
646: }
647:
648: public function exponentiate(Type $exponent): Type
649: {
650: return $this;
651: }
652:
653: public function getFiniteTypes(): array
654: {
655: return [];
656: }
657:
658: public function toPhpDocNode(): TypeNode
659: {
660: return new IdentifierTypeNode('never');
661: }
662:
663: public function hasTemplateOrLateResolvableType(): bool
664: {
665: return false;
666: }
667:
668: }
669: