1: <?php
2: namespace Pharborist;
3:
4: 5: 6:
7: class VisitorBase implements VisitorInterface {
8: protected $methodCache = [];
9:
10: public static function getShortClassName($class_name) {
11: $offset = strrpos($class_name, '\\');
12: $offset = $offset ? $offset + 1: 0;
13: return substr($class_name, $offset);
14: }
15:
16: protected function getMethods(Node $node, $prefix) {
17: $node_class_name = get_class($node);
18: if (isset($this->methodCache[$node_class_name][$prefix])) {
19: return $this->methodCache[$node_class_name][$prefix];
20: }
21: else {
22: $methods = [];
23: $classes = array_merge([$node_class_name], class_parents($node), class_implements($node));
24: foreach ($classes as $class_name) {
25: $class_name = static::getShortClassName($class_name);
26: $method_name = $prefix . $class_name;
27: if (method_exists($this, $method_name)) {
28: $methods[] = $method_name;
29: }
30: }
31: $methods = array_reverse($methods);
32: $this->methodCache[$node_class_name][$prefix] = $methods;
33: return $methods;
34: }
35: }
36:
37: public function visit(Node $node) {
38: foreach ($this->getMethods($node, 'visit') as $method_name) {
39: $this->$method_name($node);
40: }
41: }
42:
43: public function visitEnd(ParentNode $node) {
44: foreach ($this->getMethods($node, 'end') as $method_name) {
45: $this->$method_name($node);
46: }
47: }
48: }
49: