PageRenderTime 30ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php

https://gitlab.com/ealexis.t/trends
PHP | 162 lines | 111 code | 23 blank | 28 comment | 19 complexity | 538bcfcdc58cd8aadc479ae8778a9af5 MD5 | raw file
  1. <?php
  2. namespace PhpParser;
  3. class NodeTraverser implements NodeTraverserInterface
  4. {
  5. /**
  6. * @var NodeVisitor[] Visitors
  7. */
  8. protected $visitors;
  9. /**
  10. * @var bool
  11. */
  12. private $cloneNodes;
  13. /**
  14. * Constructs a node traverser.
  15. *
  16. * @param bool $cloneNodes Should the traverser clone the nodes when traversing the AST
  17. */
  18. public function __construct($cloneNodes = false) {
  19. $this->visitors = array();
  20. $this->cloneNodes = $cloneNodes;
  21. }
  22. /**
  23. * Adds a visitor.
  24. *
  25. * @param NodeVisitor $visitor Visitor to add
  26. */
  27. public function addVisitor(NodeVisitor $visitor) {
  28. $this->visitors[] = $visitor;
  29. }
  30. /**
  31. * Removes an added visitor.
  32. *
  33. * @param NodeVisitor $visitor
  34. */
  35. public function removeVisitor(NodeVisitor $visitor) {
  36. foreach ($this->visitors as $index => $storedVisitor) {
  37. if ($storedVisitor === $visitor) {
  38. unset($this->visitors[$index]);
  39. break;
  40. }
  41. }
  42. }
  43. /**
  44. * Traverses an array of nodes using the registered visitors.
  45. *
  46. * @param Node[] $nodes Array of nodes
  47. *
  48. * @return Node[] Traversed array of nodes
  49. */
  50. public function traverse(array $nodes) {
  51. foreach ($this->visitors as $visitor) {
  52. if (null !== $return = $visitor->beforeTraverse($nodes)) {
  53. $nodes = $return;
  54. }
  55. }
  56. $nodes = $this->traverseArray($nodes);
  57. foreach ($this->visitors as $visitor) {
  58. if (null !== $return = $visitor->afterTraverse($nodes)) {
  59. $nodes = $return;
  60. }
  61. }
  62. return $nodes;
  63. }
  64. protected function traverseNode(Node $node) {
  65. if ($this->cloneNodes) {
  66. $node = clone $node;
  67. }
  68. foreach ($node->getSubNodeNames() as $name) {
  69. $subNode =& $node->$name;
  70. if (is_array($subNode)) {
  71. $subNode = $this->traverseArray($subNode);
  72. } elseif ($subNode instanceof Node) {
  73. $traverseChildren = true;
  74. foreach ($this->visitors as $visitor) {
  75. $return = $visitor->enterNode($subNode);
  76. if (self::DONT_TRAVERSE_CHILDREN === $return) {
  77. $traverseChildren = false;
  78. } else if (null !== $return) {
  79. $subNode = $return;
  80. }
  81. }
  82. if ($traverseChildren) {
  83. $subNode = $this->traverseNode($subNode);
  84. }
  85. foreach ($this->visitors as $visitor) {
  86. if (null !== $return = $visitor->leaveNode($subNode)) {
  87. if (is_array($return)) {
  88. throw new \LogicException(
  89. 'leaveNode() may only return an array ' .
  90. 'if the parent structure is an array'
  91. );
  92. }
  93. $subNode = $return;
  94. }
  95. }
  96. }
  97. }
  98. return $node;
  99. }
  100. protected function traverseArray(array $nodes) {
  101. $doNodes = array();
  102. foreach ($nodes as $i => &$node) {
  103. if (is_array($node)) {
  104. $node = $this->traverseArray($node);
  105. } elseif ($node instanceof Node) {
  106. $traverseChildren = true;
  107. foreach ($this->visitors as $visitor) {
  108. $return = $visitor->enterNode($node);
  109. if (self::DONT_TRAVERSE_CHILDREN === $return) {
  110. $traverseChildren = false;
  111. } else if (null !== $return) {
  112. $node = $return;
  113. }
  114. }
  115. if ($traverseChildren) {
  116. $node = $this->traverseNode($node);
  117. }
  118. foreach ($this->visitors as $visitor) {
  119. $return = $visitor->leaveNode($node);
  120. if (self::REMOVE_NODE === $return) {
  121. $doNodes[] = array($i, array());
  122. break;
  123. } elseif (is_array($return)) {
  124. $doNodes[] = array($i, $return);
  125. break;
  126. } elseif (null !== $return) {
  127. $node = $return;
  128. }
  129. }
  130. }
  131. }
  132. if (!empty($doNodes)) {
  133. while (list($i, $replace) = array_pop($doNodes)) {
  134. array_splice($nodes, $i, 1, $replace);
  135. }
  136. }
  137. return $nodes;
  138. }
  139. }