1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Type;
4:
5: use PHPStan\Php\PhpVersion;
6: use PHPStan\PhpDocParser\Ast\Type\TypeNode;
7: use PHPStan\Reflection\Callables\CallableParametersAcceptor;
8: use PHPStan\Reflection\ClassConstantReflection;
9: use PHPStan\Reflection\ClassMemberAccessAnswerer;
10: use PHPStan\Reflection\ClassReflection;
11: use PHPStan\Reflection\ExtendedMethodReflection;
12: use PHPStan\Reflection\ExtendedPropertyReflection;
13: use PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection;
14: use PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection;
15: use PHPStan\TrinaryLogic;
16: use PHPStan\Type\Constant\ConstantArrayType;
17: use PHPStan\Type\Constant\ConstantStringType;
18: use PHPStan\Type\Enum\EnumCaseObjectType;
19: use PHPStan\Type\Generic\TemplateTypeMap;
20: use PHPStan\Type\Generic\TemplateTypeReference;
21: use PHPStan\Type\Generic\TemplateTypeVariance;
22:
23: /**
24: * @api
25: * @see https://phpstan.org/developing-extensions/type-system
26: */
27: interface Type
28: {
29:
30: /**
31: * @return list<string>
32: */
33: public function getReferencedClasses(): array;
34:
35: /** @return list<non-empty-string> */
36: public function getObjectClassNames(): array;
37:
38: /**
39: * @return list<ClassReflection>
40: */
41: public function getObjectClassReflections(): array;
42:
43: /**
44: * Returns object type Foo for class-string<Foo> and 'Foo' (if Foo is a valid class).
45: */
46: public function getClassStringObjectType(): Type;
47:
48: /**
49: * Returns object type Foo for class-string<Foo>, 'Foo' (if Foo is a valid class),
50: * and object type Foo.
51: */
52: public function getObjectTypeOrClassStringObjectType(): Type;
53:
54: public function isObject(): TrinaryLogic;
55:
56: public function isEnum(): TrinaryLogic;
57:
58: /** @return list<ArrayType|ConstantArrayType> */
59: public function getArrays(): array;
60:
61: /** @return list<ConstantArrayType> */
62: public function getConstantArrays(): array;
63:
64: /** @return list<ConstantStringType> */
65: public function getConstantStrings(): array;
66:
67: public function accepts(Type $type, bool $strictTypes): AcceptsResult;
68:
69: public function isSuperTypeOf(Type $type): IsSuperTypeOfResult;
70:
71: public function equals(Type $type): bool;
72:
73: public function describe(VerbosityLevel $level): string;
74:
75: public function canAccessProperties(): TrinaryLogic;
76:
77: public function hasProperty(string $propertyName): TrinaryLogic;
78:
79: public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope): ExtendedPropertyReflection;
80:
81: public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope): UnresolvedPropertyPrototypeReflection;
82:
83: public function canCallMethods(): TrinaryLogic;
84:
85: public function hasMethod(string $methodName): TrinaryLogic;
86:
87: public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope): ExtendedMethodReflection;
88:
89: public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope): UnresolvedMethodPrototypeReflection;
90:
91: public function canAccessConstants(): TrinaryLogic;
92:
93: public function hasConstant(string $constantName): TrinaryLogic;
94:
95: public function getConstant(string $constantName): ClassConstantReflection;
96:
97: public function isIterable(): TrinaryLogic;
98:
99: public function isIterableAtLeastOnce(): TrinaryLogic;
100:
101: public function getArraySize(): Type;
102:
103: public function getIterableKeyType(): Type;
104:
105: public function getFirstIterableKeyType(): Type;
106:
107: public function getLastIterableKeyType(): Type;
108:
109: public function getIterableValueType(): Type;
110:
111: public function getFirstIterableValueType(): Type;
112:
113: public function getLastIterableValueType(): Type;
114:
115: public function isArray(): TrinaryLogic;
116:
117: public function isConstantArray(): TrinaryLogic;
118:
119: public function isOversizedArray(): TrinaryLogic;
120:
121: public function isList(): TrinaryLogic;
122:
123: public function isOffsetAccessible(): TrinaryLogic;
124:
125: public function isOffsetAccessLegal(): TrinaryLogic;
126:
127: public function hasOffsetValueType(Type $offsetType): TrinaryLogic;
128:
129: public function getOffsetValueType(Type $offsetType): Type;
130:
131: public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = true): Type;
132:
133: public function setExistingOffsetValueType(Type $offsetType, Type $valueType): Type;
134:
135: public function unsetOffset(Type $offsetType): Type;
136:
137: public function getKeysArrayFiltered(Type $filterValueType, TrinaryLogic $strict): Type;
138:
139: public function getKeysArray(): Type;
140:
141: public function getValuesArray(): Type;
142:
143: public function chunkArray(Type $lengthType, TrinaryLogic $preserveKeys): Type;
144:
145: public function fillKeysArray(Type $valueType): Type;
146:
147: public function flipArray(): Type;
148:
149: public function intersectKeyArray(Type $otherArraysType): Type;
150:
151: public function popArray(): Type;
152:
153: public function reverseArray(TrinaryLogic $preserveKeys): Type;
154:
155: public function searchArray(Type $needleType, ?TrinaryLogic $strict = null): Type;
156:
157: public function shiftArray(): Type;
158:
159: public function shuffleArray(): Type;
160:
161: public function sliceArray(Type $offsetType, Type $lengthType, TrinaryLogic $preserveKeys): Type;
162:
163: public function spliceArray(Type $offsetType, Type $lengthType, Type $replacementType): Type;
164:
165: /**
166: * @return list<EnumCaseObjectType>
167: */
168: public function getEnumCases(): array;
169:
170: /**
171: * Returns a list of finite values.
172: *
173: * Examples:
174: *
175: * - for bool: [true, false]
176: * - for int<0, 3>: [0, 1, 2, 3]
177: * - for enums: list of enum cases
178: * - for scalars: the scalar itself
179: *
180: * For infinite types it returns an empty array.
181: *
182: * @return list<Type>
183: */
184: public function getFiniteTypes(): array;
185:
186: public function exponentiate(Type $exponent): Type;
187:
188: public function isCallable(): TrinaryLogic;
189:
190: /**
191: * @return CallableParametersAcceptor[]
192: */
193: public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array;
194:
195: public function isCloneable(): TrinaryLogic;
196:
197: public function toBoolean(): BooleanType;
198:
199: public function toNumber(): Type;
200:
201: public function toInteger(): Type;
202:
203: public function toFloat(): Type;
204:
205: public function toString(): Type;
206:
207: public function toArray(): Type;
208:
209: public function toArrayKey(): Type;
210:
211: /**
212: * Tells how a type might change when passed to an argument
213: * or assigned to a typed property.
214: *
215: * Example: int is accepted by int|float with strict_types = 1
216: * Stringable is accepted by string|Stringable even without strict_types.
217: *
218: * Note: Logic with $strictTypes=false is mostly not implemented in Type subclasses.
219: */
220: public function toCoercedArgumentType(bool $strictTypes): self;
221:
222: public function isSmallerThan(Type $otherType, PhpVersion $phpVersion): TrinaryLogic;
223:
224: public function isSmallerThanOrEqual(Type $otherType, PhpVersion $phpVersion): TrinaryLogic;
225:
226: /**
227: * Is Type of a known constant value? Includes literal strings, integers, floats, true, false, null, and array shapes.
228: */
229: public function isConstantValue(): TrinaryLogic;
230:
231: /**
232: * Is Type of a known constant scalar value? Includes literal strings, integers, floats, true, false, and null.
233: */
234: public function isConstantScalarValue(): TrinaryLogic;
235:
236: /**
237: * @return list<ConstantScalarType>
238: */
239: public function getConstantScalarTypes(): array;
240:
241: /**
242: * @return list<int|float|string|bool|null>
243: */
244: public function getConstantScalarValues(): array;
245:
246: public function isNull(): TrinaryLogic;
247:
248: public function isTrue(): TrinaryLogic;
249:
250: public function isFalse(): TrinaryLogic;
251:
252: public function isBoolean(): TrinaryLogic;
253:
254: public function isFloat(): TrinaryLogic;
255:
256: public function isInteger(): TrinaryLogic;
257:
258: public function isString(): TrinaryLogic;
259:
260: public function isNumericString(): TrinaryLogic;
261:
262: public function isNonEmptyString(): TrinaryLogic;
263:
264: public function isNonFalsyString(): TrinaryLogic;
265:
266: public function isLiteralString(): TrinaryLogic;
267:
268: public function isLowercaseString(): TrinaryLogic;
269:
270: public function isUppercaseString(): TrinaryLogic;
271:
272: public function isClassString(): TrinaryLogic;
273:
274: public function isVoid(): TrinaryLogic;
275:
276: public function isScalar(): TrinaryLogic;
277:
278: public function looseCompare(Type $type, PhpVersion $phpVersion): BooleanType;
279:
280: public function getSmallerType(PhpVersion $phpVersion): Type;
281:
282: public function getSmallerOrEqualType(PhpVersion $phpVersion): Type;
283:
284: public function getGreaterType(PhpVersion $phpVersion): Type;
285:
286: public function getGreaterOrEqualType(PhpVersion $phpVersion): Type;
287:
288: /**
289: * Returns actual template type for a given object.
290: *
291: * Example:
292: *
293: * @-template T
294: * class Foo {}
295: *
296: * // $fooType is Foo<int>
297: * $t = $fooType->getTemplateType(Foo::class, 'T');
298: * $t->isInteger(); // yes
299: *
300: * Returns ErrorType in case of a missing type.
301: *
302: * @param class-string $ancestorClassName
303: */
304: public function getTemplateType(string $ancestorClassName, string $templateTypeName): Type;
305:
306: /**
307: * Infers template types
308: *
309: * Infers the real Type of the TemplateTypes found in $this, based on
310: * the received Type.
311: */
312: public function inferTemplateTypes(Type $receivedType): TemplateTypeMap;
313:
314: /**
315: * Returns the template types referenced by this Type, recursively
316: *
317: * The return value is a list of TemplateTypeReferences, who contain the
318: * referenced template type as well as the variance position in which it was
319: * found.
320: *
321: * For example, calling this on array<Foo<T>,Bar> (with T a template type)
322: * will return one TemplateTypeReference for the type T.
323: *
324: * @param TemplateTypeVariance $positionVariance The variance position in
325: * which the receiver type was
326: * found.
327: *
328: * @return list<TemplateTypeReference>
329: */
330: public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance): array;
331:
332: public function toAbsoluteNumber(): Type;
333:
334: /**
335: * Traverses inner types
336: *
337: * Returns a new instance with all inner types mapped through $cb. Might
338: * return the same instance if inner types did not change.
339: *
340: * @param callable(Type):Type $cb
341: */
342: public function traverse(callable $cb): Type;
343:
344: /**
345: * Traverses inner types while keeping the same context in another type.
346: *
347: * @param callable(Type $left, Type $right): Type $cb
348: */
349: public function traverseSimultaneously(Type $right, callable $cb): Type;
350:
351: public function toPhpDocNode(): TypeNode;
352:
353: /**
354: * Return the difference with another type, or null if it cannot be represented.
355: *
356: * @see TypeCombinator::remove()
357: */
358: public function tryRemove(Type $typeToRemove): ?Type;
359:
360: public function generalize(GeneralizePrecision $precision): Type;
361:
362: }
363: