diff vendor/nikic/php-parser/doc/component/FAQ.markdown @ 13:5fb285c0d0e3

Update Drupal core to 8.4.7 via Composer. Security update; I *think* we've been lucky to get away with this so far, as we don't support self-registration which seems to be used by the so-called "drupalgeddon 2" attack that 8.4.5 was vulnerable to.
author Chris Cannam
date Mon, 23 Apr 2018 09:33:26 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/nikic/php-parser/doc/component/FAQ.markdown	Mon Apr 23 09:33:26 2018 +0100
@@ -0,0 +1,68 @@
+Frequently Asked Questions
+==========================
+
+ * [How can the parent of a node be obtained?](#how-can-the-parent-of-a-node-be-obtained)
+ * [How can the next/previous sibling of a node be obtained?](#how-can-the-nextprevious-sibling-of-a-node-be-obtained)
+
+How can the parent of a node be obtained?
+-----
+
+The AST does not store parent nodes by default. However, it is easy to add a custom parent node
+attribute using a custom node visitor:
+
+```php
+use PhpParser\Node;
+use PhpParser\NodeVisitorAbstract;
+
+class ParentConnector extends NodeVisitorAbstract {
+    private $stack;
+    public function beforeTraverse(array $nodes) {
+        $this->stack = [];
+    }
+    public function enterNode(Node $node) {
+        if (!empty($this->stack)) {
+            $node->setAttribute('parent', $this->stack[count($this->stack)-1]);
+        }
+        $this->stack[] = $node;
+    }
+    public function leaveNode(Node $node) {
+        array_pop($this->stack);
+    }
+}
+```
+
+After running this visitor, the parent node can be obtained through `$node->getAttribute('parent')`.
+
+How can the next/previous sibling of a node be obtained?
+-----
+
+Again, siblings are not stored by default, but the visitor from the previous entry can be easily
+extended to store the previous / next node with a common parent as well:
+
+```php
+use PhpParser\Node;
+use PhpParser\NodeVisitorAbstract;
+
+class NodeConnector extends NodeVisitorAbstract {
+    private $stack;
+    private $prev;
+    public function beforeTraverse(array $nodes) {
+        $this->stack = [];
+        $this->prev = null;
+    }
+    public function enterNode(Node $node) {
+        if (!empty($this->stack)) {
+            $node->setAttribute('parent', $this->stack[count($this->stack)-1]);
+        }
+        if ($this->prev && $this->prev->getAttribute('parent') == $node->getAttribute('parent')) {
+            $node->setAttribute('prev', $this->prev);
+            $this->prev->setAttribute('next', $node);
+        }
+        $this->stack[] = $node;
+    }
+    public function leaveNode(Node $node) {
+        $this->prev = $node;
+        array_pop($this->stack);
+    }
+}
+```