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