1 | <?php |
||
30 | final class ElementNameResolver extends NodeVisitorAbstract |
||
31 | { |
||
32 | /** |
||
33 | * @var \SplDoublyLinkedList |
||
34 | */ |
||
35 | private $parts = null; |
||
36 | |||
37 | /** |
||
38 | * Resets the object to a known state before start processing. |
||
39 | * |
||
40 | * @param array $nodes |
||
41 | */ |
||
42 | public function beforeTraverse(array $nodes) |
||
46 | |||
47 | /** |
||
48 | * Performs a reset of the added element when needed. |
||
49 | * |
||
50 | * @param Node $node |
||
51 | */ |
||
52 | public function leaveNode(Node $node) |
||
53 | { |
||
54 | switch (get_class($node)) { |
||
55 | case Namespace_::class: |
||
56 | case Class_::class: |
||
57 | case ClassMethod::class: |
||
58 | case Trait_::class: |
||
59 | case PropertyProperty::class: |
||
60 | case ClassConst::class: |
||
61 | case Const_::class: |
||
62 | case Interface_::class: |
||
63 | case Function_::class: |
||
64 | $this->parts->pop(); |
||
65 | break; |
||
66 | } |
||
67 | } |
||
68 | |||
69 | /** |
||
70 | * Adds fqsen property to a node when applicable. |
||
71 | * |
||
72 | * @param Node $node |
||
73 | */ |
||
74 | 4 | public function enterNode(Node $node) |
|
75 | { |
||
76 | 4 | switch (get_class($node)) { |
|
77 | case Namespace_::class: |
||
78 | 1 | $this->resetState('\\' . $node->name . '\\'); |
|
|
|||
79 | 1 | $node->fqsen = new Fqsen($this->buildName()); |
|
80 | 1 | break; |
|
81 | case Class_::class: |
||
82 | case Trait_::class: |
||
83 | case Interface_::class: |
||
84 | 2 | $this->parts->push((string)$node->name); |
|
85 | 2 | $node->fqsen = new Fqsen($this->buildName()); |
|
86 | 2 | break; |
|
87 | case Function_::class: |
||
88 | 1 | $this->parts->push($node->name . '()'); |
|
89 | 1 | $node->fqsen = new Fqsen($this->buildName()); |
|
90 | 1 | break; |
|
91 | case ClassMethod::class: |
||
92 | $this->parts->push('::' . $node->name . '()'); |
||
93 | $node->fqsen = new Fqsen($this->buildName()); |
||
94 | break; |
||
95 | case ClassConst::class: |
||
96 | 1 | $this->parts->push('::'); |
|
97 | 1 | break; |
|
98 | case Const_::class: |
||
99 | 2 | $this->parts->push($node->name); |
|
100 | 2 | $node->fqsen = new Fqsen($this->buildName()); |
|
101 | 2 | break; |
|
102 | case PropertyProperty::class: |
||
103 | $this->parts->push('::$' . $node->name); |
||
104 | $node->fqsen = new Fqsen($this->buildName()); |
||
105 | break; |
||
106 | } |
||
107 | 4 | } |
|
108 | |||
109 | /** |
||
110 | * Resets the state of the object to an empty state. |
||
111 | * |
||
112 | * @param string $namespace |
||
113 | */ |
||
114 | 4 | private function resetState($namespace = null) |
|
119 | |||
120 | /** |
||
121 | * Builds the name of the current node using the parts that are pushed to the parts list. |
||
122 | * |
||
123 | * @return null|string |
||
124 | */ |
||
125 | 4 | private function buildName() |
|
133 | } |
If you access a property on an interface, you most likely code against a concrete implementation of the interface.
Available Fixes
Adding an additional type check:
Changing the type hint: