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<non-empty-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: /** @deprecated Use hasInstanceProperty or hasStaticProperty instead */
78: public function hasProperty(string $propertyName): TrinaryLogic;
79:
80: /** @deprecated Use getInstanceProperty or getStaticProperty instead */
81: public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope): ExtendedPropertyReflection;
82:
83: /** @deprecated Use getUnresolvedInstancePropertyPrototype or getUnresolvedStaticPropertyPrototype instead */
84: public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope): UnresolvedPropertyPrototypeReflection;
85:
86: public function hasInstanceProperty(string $propertyName): TrinaryLogic;
87:
88: public function getInstanceProperty(string $propertyName, ClassMemberAccessAnswerer $scope): ExtendedPropertyReflection;
89:
90: public function getUnresolvedInstancePropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope): UnresolvedPropertyPrototypeReflection;
91:
92: public function hasStaticProperty(string $propertyName): TrinaryLogic;
93:
94: public function getStaticProperty(string $propertyName, ClassMemberAccessAnswerer $scope): ExtendedPropertyReflection;
95:
96: public function getUnresolvedStaticPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope): UnresolvedPropertyPrototypeReflection;
97:
98: public function canCallMethods(): TrinaryLogic;
99:
100: public function hasMethod(string $methodName): TrinaryLogic;
101:
102: public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope): ExtendedMethodReflection;
103:
104: public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope): UnresolvedMethodPrototypeReflection;
105:
106: public function canAccessConstants(): TrinaryLogic;
107:
108: public function hasConstant(string $constantName): TrinaryLogic;
109:
110: public function getConstant(string $constantName): ClassConstantReflection;
111:
112: public function isIterable(): TrinaryLogic;
113:
114: public function isIterableAtLeastOnce(): TrinaryLogic;
115:
116: public function getArraySize(): Type;
117:
118: public function getIterableKeyType(): Type;
119:
120: /** @deprecated use getIterableKeyType */
121: public function getFirstIterableKeyType(): Type;
122:
123: /** @deprecated use getIterableKeyType */
124: public function getLastIterableKeyType(): Type;
125:
126: public function getIterableValueType(): Type;
127:
128: /** @deprecated use getIterableValueType */
129: public function getFirstIterableValueType(): Type;
130:
131: /** @deprecated use getIterableValueType */
132: public function getLastIterableValueType(): Type;
133:
134: public function isArray(): TrinaryLogic;
135:
136: public function isConstantArray(): TrinaryLogic;
137:
138: public function isOversizedArray(): TrinaryLogic;
139:
140: public function isList(): TrinaryLogic;
141:
142: public function isOffsetAccessible(): TrinaryLogic;
143:
144: public function isOffsetAccessLegal(): TrinaryLogic;
145:
146: public function hasOffsetValueType(Type $offsetType): TrinaryLogic;
147:
148: public function getOffsetValueType(Type $offsetType): Type;
149:
150: public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = true): Type;
151:
152: public function setExistingOffsetValueType(Type $offsetType, Type $valueType): Type;
153:
154: public function unsetOffset(Type $offsetType): Type;
155:
156: public function getKeysArrayFiltered(Type $filterValueType, TrinaryLogic $strict): Type;
157:
158: public function getKeysArray(): Type;
159:
160: public function getValuesArray(): Type;
161:
162: public function chunkArray(Type $lengthType, TrinaryLogic $preserveKeys): Type;
163:
164: public function fillKeysArray(Type $valueType): Type;
165:
166: public function flipArray(): Type;
167:
168: public function intersectKeyArray(Type $otherArraysType): Type;
169:
170: public function popArray(): Type;
171:
172: public function reverseArray(TrinaryLogic $preserveKeys): Type;
173:
174: public function searchArray(Type $needleType, ?TrinaryLogic $strict = null): Type;
175:
176: public function shiftArray(): Type;
177:
178: public function shuffleArray(): Type;
179:
180: public function sliceArray(Type $offsetType, Type $lengthType, TrinaryLogic $preserveKeys): Type;
181:
182: public function spliceArray(Type $offsetType, Type $lengthType, Type $replacementType): Type;
183:
184: /**
185: * @return list<EnumCaseObjectType>
186: */
187: public function getEnumCases(): array;
188:
189: /**
190: * Returns a list of finite values.
191: *
192: * Examples:
193: *
194: * - for bool: [true, false]
195: * - for int<0, 3>: [0, 1, 2, 3]
196: * - for enums: list of enum cases
197: * - for scalars: the scalar itself
198: *
199: * For infinite types it returns an empty array.
200: *
201: * @return list<Type>
202: */
203: public function getFiniteTypes(): array;
204:
205: public function exponentiate(Type $exponent): Type;
206:
207: public function isCallable(): TrinaryLogic;
208:
209: /**
210: * @return CallableParametersAcceptor[]
211: */
212: public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array;
213:
214: public function isCloneable(): TrinaryLogic;
215:
216: public function toBoolean(): BooleanType;
217:
218: public function toNumber(): Type;
219:
220: public function toInteger(): Type;
221:
222: public function toFloat(): Type;
223:
224: public function toString(): Type;
225:
226: public function toArray(): Type;
227:
228: public function toArrayKey(): Type;
229:
230: /**
231: * Tells how a type might change when passed to an argument
232: * or assigned to a typed property.
233: *
234: * Example: int is accepted by int|float with strict_types = 1
235: * Stringable is accepted by string|Stringable even without strict_types.
236: */
237: public function toCoercedArgumentType(bool $strictTypes): self;
238:
239: public function isSmallerThan(Type $otherType, PhpVersion $phpVersion): TrinaryLogic;
240:
241: public function isSmallerThanOrEqual(Type $otherType, PhpVersion $phpVersion): TrinaryLogic;
242:
243: /**
244: * Is Type of a known constant value? Includes literal strings, integers, floats, true, false, null, and array shapes.
245: */
246: public function isConstantValue(): TrinaryLogic;
247:
248: /**
249: * Is Type of a known constant scalar value? Includes literal strings, integers, floats, true, false, and null.
250: */
251: public function isConstantScalarValue(): TrinaryLogic;
252:
253: /**
254: * @return list<ConstantScalarType>
255: */
256: public function getConstantScalarTypes(): array;
257:
258: /**
259: * @return list<int|float|string|bool|null>
260: */
261: public function getConstantScalarValues(): array;
262:
263: public function isNull(): TrinaryLogic;
264:
265: public function isTrue(): TrinaryLogic;
266:
267: public function isFalse(): TrinaryLogic;
268:
269: public function isBoolean(): TrinaryLogic;
270:
271: public function isFloat(): TrinaryLogic;
272:
273: public function isInteger(): TrinaryLogic;
274:
275: public function isString(): TrinaryLogic;
276:
277: public function isNumericString(): TrinaryLogic;
278:
279: public function isNonEmptyString(): TrinaryLogic;
280:
281: public function isNonFalsyString(): TrinaryLogic;
282:
283: public function isLiteralString(): TrinaryLogic;
284:
285: public function isLowercaseString(): TrinaryLogic;
286:
287: public function isUppercaseString(): TrinaryLogic;
288:
289: public function isClassString(): TrinaryLogic;
290:
291: public function isVoid(): TrinaryLogic;
292:
293: public function isScalar(): TrinaryLogic;
294:
295: public function looseCompare(Type $type, PhpVersion $phpVersion): BooleanType;
296:
297: public function getSmallerType(PhpVersion $phpVersion): Type;
298:
299: public function getSmallerOrEqualType(PhpVersion $phpVersion): Type;
300:
301: public function getGreaterType(PhpVersion $phpVersion): Type;
302:
303: public function getGreaterOrEqualType(PhpVersion $phpVersion): Type;
304:
305: /**
306: * Returns actual template type for a given object.
307: *
308: * Example:
309: *
310: * @-template T
311: * class Foo {}
312: *
313: * // $fooType is Foo<int>
314: * $t = $fooType->getTemplateType(Foo::class, 'T');
315: * $t->isInteger(); // yes
316: *
317: * Returns ErrorType in case of a missing type.
318: *
319: * @param class-string $ancestorClassName
320: */
321: public function getTemplateType(string $ancestorClassName, string $templateTypeName): Type;
322:
323: /**
324: * Infers template types
325: *
326: * Infers the real Type of the TemplateTypes found in $this, based on
327: * the received Type.
328: */
329: public function inferTemplateTypes(Type $receivedType): TemplateTypeMap;
330:
331: /**
332: * Returns the template types referenced by this Type, recursively
333: *
334: * The return value is a list of TemplateTypeReferences, who contain the
335: * referenced template type as well as the variance position in which it was
336: * found.
337: *
338: * For example, calling this on array<Foo<T>,Bar> (with T a template type)
339: * will return one TemplateTypeReference for the type T.
340: *
341: * @param TemplateTypeVariance $positionVariance The variance position in
342: * which the receiver type was
343: * found.
344: *
345: * @return list<TemplateTypeReference>
346: */
347: public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance): array;
348:
349: public function toAbsoluteNumber(): Type;
350:
351: /**
352: * Traverses inner types
353: *
354: * Returns a new instance with all inner types mapped through $cb. Might
355: * return the same instance if inner types did not change.
356: *
357: * @param callable(Type):Type $cb
358: */
359: public function traverse(callable $cb): Type;
360:
361: /**
362: * Traverses inner types while keeping the same context in another type.
363: *
364: * @param callable(Type $left, Type $right): Type $cb
365: */
366: public function traverseSimultaneously(Type $right, callable $cb): Type;
367:
368: public function toPhpDocNode(): TypeNode;
369:
370: /**
371: * Return the difference with another type, or null if it cannot be represented.
372: *
373: * @see TypeCombinator::remove()
374: */
375: public function tryRemove(Type $typeToRemove): ?Type;
376:
377: public function generalize(GeneralizePrecision $precision): Type;
378:
379: }
380: