1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Type;
4:
5: use PHPStan\Type\Generic\TemplateTypeVariance;
6: use PHPStan\Type\Traits\LateResolvableTypeTrait;
7: use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
8: use function array_merge;
9: use function sprintf;
10:
11: /** @api */
12: final class OffsetAccessType implements CompoundType, LateResolvableType
13: {
14:
15: use LateResolvableTypeTrait;
16: use NonGeneralizableTypeTrait;
17:
18: public function __construct(
19: private Type $type,
20: private Type $offset,
21: )
22: {
23: }
24:
25: public function getReferencedClasses(): array
26: {
27: return array_merge(
28: $this->type->getReferencedClasses(),
29: $this->offset->getReferencedClasses(),
30: );
31: }
32:
33: public function getObjectClassNames(): array
34: {
35: return [];
36: }
37:
38: public function getObjectClassReflections(): array
39: {
40: return [];
41: }
42:
43: public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance): array
44: {
45: return array_merge(
46: $this->type->getReferencedTemplateTypes($positionVariance),
47: $this->offset->getReferencedTemplateTypes($positionVariance),
48: );
49: }
50:
51: public function equals(Type $type): bool
52: {
53: return $type instanceof self
54: && $this->type->equals($type->type)
55: && $this->offset->equals($type->offset);
56: }
57:
58: public function describe(VerbosityLevel $level): string
59: {
60: return sprintf(
61: '%s[%s]',
62: $this->type->describe($level),
63: $this->offset->describe($level),
64: );
65: }
66:
67: public function isResolvable(): bool
68: {
69: return !TypeUtils::containsTemplateType($this->type)
70: && !TypeUtils::containsTemplateType($this->offset);
71: }
72:
73: protected function getResult(): Type
74: {
75: return $this->type->getOffsetValueType($this->offset);
76: }
77:
78: /**
79: * @param callable(Type): Type $cb
80: */
81: public function traverse(callable $cb): Type
82: {
83: $type = $cb($this->type);
84: $offset = $cb($this->offset);
85:
86: if ($this->type === $type && $this->offset === $offset) {
87: return $this;
88: }
89:
90: return new OffsetAccessType($type, $offset);
91: }
92:
93: /**
94: * @param mixed[] $properties
95: */
96: public static function __set_state(array $properties): Type
97: {
98: return new self(
99: $properties['type'],
100: $properties['offset'],
101: );
102: }
103:
104: }
105: