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