1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Analyser;
4:
5: use PHPStan\Reflection\ClassReflection;
6: use PHPStan\ShouldNotHappenException;
7:
8: class ScopeContext
9: {
10:
11: private function __construct(
12: private string $file,
13: private ?ClassReflection $classReflection,
14: private ?ClassReflection $traitReflection,
15: )
16: {
17: }
18:
19: /** @api */
20: public static function create(string $file): self
21: {
22: return new self($file, null, null);
23: }
24:
25: public function beginFile(): self
26: {
27: return new self($this->file, null, null);
28: }
29:
30: public function enterClass(ClassReflection $classReflection): self
31: {
32: if ($this->classReflection !== null && !$classReflection->isAnonymous()) {
33: throw new ShouldNotHappenException();
34: }
35: if ($classReflection->isTrait()) {
36: throw new ShouldNotHappenException();
37: }
38: return new self($this->file, $classReflection, null);
39: }
40:
41: public function enterTrait(ClassReflection $traitReflection): self
42: {
43: if ($this->classReflection === null) {
44: throw new ShouldNotHappenException();
45: }
46: if (!$traitReflection->isTrait()) {
47: throw new ShouldNotHappenException();
48: }
49:
50: return new self($this->file, $this->classReflection, $traitReflection);
51: }
52:
53: public function equals(self $otherContext): bool
54: {
55: if ($this->file !== $otherContext->file) {
56: return false;
57: }
58:
59: if ($this->getClassReflection() === null) {
60: return $otherContext->getClassReflection() === null;
61: } elseif ($otherContext->getClassReflection() === null) {
62: return false;
63: }
64:
65: $isSameClass = $this->getClassReflection()->getName() === $otherContext->getClassReflection()->getName();
66:
67: if ($this->getTraitReflection() === null) {
68: return $otherContext->getTraitReflection() === null && $isSameClass;
69: } elseif ($otherContext->getTraitReflection() === null) {
70: return false;
71: }
72:
73: $isSameTrait = $this->getTraitReflection()->getName() === $otherContext->getTraitReflection()->getName();
74:
75: return $isSameClass && $isSameTrait;
76: }
77:
78: public function getFile(): string
79: {
80: return $this->file;
81: }
82:
83: public function getClassReflection(): ?ClassReflection
84: {
85: return $this->classReflection;
86: }
87:
88: public function getTraitReflection(): ?ClassReflection
89: {
90: return $this->traitReflection;
91: }
92:
93: }
94: