1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Type;
4:
5: use PHPStan\PhpDocParser\Ast\Type\ThisTypeNode;
6: use PHPStan\PhpDocParser\Ast\Type\TypeNode;
7: use PHPStan\Reflection\ClassReflection;
8: use function sprintf;
9:
10: /** @api */
11: class ThisType extends StaticType
12: {
13:
14: /**
15: * @api
16: */
17: public function __construct(
18: ClassReflection $classReflection,
19: ?Type $subtractedType = null,
20: )
21: {
22: parent::__construct($classReflection, $subtractedType);
23: }
24:
25: public function changeBaseClass(ClassReflection $classReflection): StaticType
26: {
27: return new self($classReflection, $this->getSubtractedType());
28: }
29:
30: public function describe(VerbosityLevel $level): string
31: {
32: return sprintf('$this(%s)', $this->getStaticObjectType()->describe($level));
33: }
34:
35: public function isSuperTypeOf(Type $type): IsSuperTypeOfResult
36: {
37: if ($type instanceof self) {
38: return $this->getStaticObjectType()->isSuperTypeOf($type);
39: }
40:
41: if ($type instanceof CompoundType) {
42: return $type->isSubTypeOf($this);
43: }
44:
45: $parent = new parent($this->getClassReflection(), $this->getSubtractedType());
46:
47: return $parent->isSuperTypeOf($type)->and(IsSuperTypeOfResult::createMaybe());
48: }
49:
50: public function changeSubtractedType(?Type $subtractedType): Type
51: {
52: $type = parent::changeSubtractedType($subtractedType);
53: if ($type instanceof parent) {
54: return new self($type->getClassReflection(), $subtractedType);
55: }
56:
57: return $type;
58: }
59:
60: public function traverse(callable $cb): Type
61: {
62: $subtractedType = $this->getSubtractedType() !== null ? $cb($this->getSubtractedType()) : null;
63:
64: if ($subtractedType !== $this->getSubtractedType()) {
65: return new self(
66: $this->getClassReflection(),
67: $subtractedType,
68: );
69: }
70:
71: return $this;
72: }
73:
74: public function traverseSimultaneously(Type $right, callable $cb): Type
75: {
76: if ($this->getSubtractedType() === null) {
77: return $this;
78: }
79:
80: return new self($this->getClassReflection());
81: }
82:
83: public function toPhpDocNode(): TypeNode
84: {
85: return new ThisTypeNode();
86: }
87:
88: }
89: