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\ClassMemberAccessAnswerer;
9: use PHPStan\Reflection\ConstantReflection;
10: use PHPStan\Reflection\ExtendedMethodReflection;
11: use PHPStan\Reflection\PropertyReflection;
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 isOffsetAccessLegal(): TrinaryLogic
260: {
261: return TrinaryLogic::createYes();
262: }
263:
264: public function hasOffsetValueType(Type $offsetType): TrinaryLogic
265: {
266: return TrinaryLogic::createYes();
267: }
268:
269: public function getOffsetValueType(Type $offsetType): Type
270: {
271: return new NeverType();
272: }
273:
274: public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = true): Type
275: {
276: return new ErrorType();
277: }
278:
279: public function setExistingOffsetValueType(Type $offsetType, Type $valueType): Type
280: {
281: return new ErrorType();
282: }
283:
284: public function unsetOffset(Type $offsetType): Type
285: {
286: return new NeverType();
287: }
288:
289: public function getKeysArray(): Type
290: {
291: return new NeverType();
292: }
293:
294: public function getValuesArray(): Type
295: {
296: return new NeverType();
297: }
298:
299: public function fillKeysArray(Type $valueType): Type
300: {
301: return new NeverType();
302: }
303:
304: public function flipArray(): Type
305: {
306: return new NeverType();
307: }
308:
309: public function intersectKeyArray(Type $otherArraysType): Type
310: {
311: return new NeverType();
312: }
313:
314: public function popArray(): Type
315: {
316: return new NeverType();
317: }
318:
319: public function searchArray(Type $needleType): Type
320: {
321: return new NeverType();
322: }
323:
324: public function shiftArray(): Type
325: {
326: return new NeverType();
327: }
328:
329: public function shuffleArray(): Type
330: {
331: return new NeverType();
332: }
333:
334: public function isCallable(): TrinaryLogic
335: {
336: return TrinaryLogic::createNo();
337: }
338:
339: public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array
340: {
341: throw new ShouldNotHappenException();
342: }
343:
344: public function isCloneable(): TrinaryLogic
345: {
346: return TrinaryLogic::createYes();
347: }
348:
349: public function toNumber(): Type
350: {
351: return $this;
352: }
353:
354: public function toAbsoluteNumber(): Type
355: {
356: return $this;
357: }
358:
359: public function toString(): Type
360: {
361: return $this;
362: }
363:
364: public function toInteger(): Type
365: {
366: return $this;
367: }
368:
369: public function toFloat(): Type
370: {
371: return $this;
372: }
373:
374: public function toArray(): Type
375: {
376: return $this;
377: }
378:
379: public function toArrayKey(): Type
380: {
381: return $this;
382: }
383:
384: public function traverse(callable $cb): Type
385: {
386: return $this;
387: }
388:
389: public function traverseSimultaneously(Type $right, callable $cb): Type
390: {
391: return $this;
392: }
393:
394: public function isNull(): TrinaryLogic
395: {
396: return TrinaryLogic::createNo();
397: }
398:
399: public function isConstantValue(): TrinaryLogic
400: {
401: return TrinaryLogic::createNo();
402: }
403:
404: public function isConstantScalarValue(): TrinaryLogic
405: {
406: return TrinaryLogic::createNo();
407: }
408:
409: public function getConstantScalarTypes(): array
410: {
411: return [];
412: }
413:
414: public function getConstantScalarValues(): array
415: {
416: return [];
417: }
418:
419: public function isTrue(): TrinaryLogic
420: {
421: return TrinaryLogic::createNo();
422: }
423:
424: public function isFalse(): TrinaryLogic
425: {
426: return TrinaryLogic::createNo();
427: }
428:
429: public function isBoolean(): TrinaryLogic
430: {
431: return TrinaryLogic::createNo();
432: }
433:
434: public function isFloat(): TrinaryLogic
435: {
436: return TrinaryLogic::createNo();
437: }
438:
439: public function isInteger(): TrinaryLogic
440: {
441: return TrinaryLogic::createNo();
442: }
443:
444: public function isString(): TrinaryLogic
445: {
446: return TrinaryLogic::createNo();
447: }
448:
449: public function isNumericString(): TrinaryLogic
450: {
451: return TrinaryLogic::createNo();
452: }
453:
454: public function isNonEmptyString(): TrinaryLogic
455: {
456: return TrinaryLogic::createNo();
457: }
458:
459: public function isNonFalsyString(): TrinaryLogic
460: {
461: return TrinaryLogic::createNo();
462: }
463:
464: public function isLiteralString(): TrinaryLogic
465: {
466: return TrinaryLogic::createNo();
467: }
468:
469: public function isClassStringType(): TrinaryLogic
470: {
471: return TrinaryLogic::createNo();
472: }
473:
474: public function getClassStringObjectType(): Type
475: {
476: return new ErrorType();
477: }
478:
479: public function getObjectTypeOrClassStringObjectType(): Type
480: {
481: return new ErrorType();
482: }
483:
484: public function isVoid(): TrinaryLogic
485: {
486: return TrinaryLogic::createNo();
487: }
488:
489: public function isScalar(): TrinaryLogic
490: {
491: return TrinaryLogic::createNo();
492: }
493:
494: public function looseCompare(Type $type, PhpVersion $phpVersion): BooleanType
495: {
496: return new BooleanType();
497: }
498:
499: public function getEnumCases(): array
500: {
501: return [];
502: }
503:
504: public function exponentiate(Type $exponent): Type
505: {
506: return $this;
507: }
508:
509: public function getFiniteTypes(): array
510: {
511: return [];
512: }
513:
514: public function toPhpDocNode(): TypeNode
515: {
516: return new IdentifierTypeNode('never');
517: }
518:
519: /**
520: * @param mixed[] $properties
521: */
522: public static function __set_state(array $properties): Type
523: {
524: return new self($properties['isExplicit']);
525: }
526:
527: }
528: