PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 3.5.0
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v3.5.0
4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.5.2 All 199 releases
betterdocs / includes / Dependencies / PhpParser / NodeDumper.php

NodeDumper.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 3.5.0, at includes/Dependencies/PhpParser/NodeDumper.php

197 lines 6.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPDeveloper\BetterDocs\Dependencies\PhpParser;
4
5 use WPDeveloper\BetterDocs\Dependencies\PhpParser\Node\Expr\Include_;
6 use WPDeveloper\BetterDocs\Dependencies\PhpParser\Node\Stmt\Class_;
7 use WPDeveloper\BetterDocs\Dependencies\PhpParser\Node\Stmt\GroupUse;
8 use WPDeveloper\BetterDocs\Dependencies\PhpParser\Node\Stmt\Use_;
9 use WPDeveloper\BetterDocs\Dependencies\PhpParser\Node\Stmt\UseUse;
10
11 class NodeDumper
12 {
13 private $dumpComments;
14 private $dumpPositions;
15 private $code;
16
17 /**
18 * Constructs a NodeDumper.
19 *
20 * Supported options:
21 * * bool dumpComments: Whether comments should be dumped.
22 * * bool dumpPositions: Whether line/offset information should be dumped. To dump offset
23 * information, the code needs to be passed to dump().
24 *
25 * @param array $options Options (see description)
26 */
27 public function __construct(array $options = []) {
28 $this->dumpComments = !empty($options['dumpComments']);
29 $this->dumpPositions = !empty($options['dumpPositions']);
30 }
31
32 /**
33 * Dumps a node or array.
34 *
35 * @param array|Node $node Node or array to dump
36 * @param string|null $code Code corresponding to dumped AST. This only needs to be passed if
37 * the dumpPositions option is enabled and the dumping of node offsets
38 * is desired.
39 *
40 * @return string Dumped value
41 */
42 public function dump($node, $code = null) {
43 $this->code = $code;
44 return $this->dumpRecursive($node);
45 }
46
47 protected function dumpRecursive($node) {
48 if ($node instanceof Node) {
49 $r = $node->getType();
50 if ($this->dumpPositions && null !== $p = $this->dumpPosition($node)) {
51 $r .= $p;
52 }
53 $r .= '(';
54
55 foreach ($node->getSubNodeNames() as $key) {
56 $r .= "\n " . $key . ': ';
57
58 $value = $node->$key;
59 if (null === $value) {
60 $r .= 'null';
61 } elseif (false === $value) {
62 $r .= 'false';
63 } elseif (true === $value) {
64 $r .= 'true';
65 } elseif (is_scalar($value)) {
66 if ('flags' === $key || 'newModifier' === $key) {
67 $r .= $this->dumpFlags($value);
68 } else if ('type' === $key && $node instanceof Include_) {
69 $r .= $this->dumpIncludeType($value);
70 } else if ('type' === $key
71 && ($node instanceof Use_ || $node instanceof UseUse || $node instanceof GroupUse)) {
72 $r .= $this->dumpUseType($value);
73 } else {
74 $r .= $value;
75 }
76 } else {
77 $r .= str_replace("\n", "\n ", $this->dumpRecursive($value));
78 }
79 }
80
81 if ($this->dumpComments && $comments = $node->getAttribute('comments')) {
82 $r .= "\n comments: " . str_replace("\n", "\n ", $this->dumpRecursive($comments));
83 }
84 } elseif (is_array($node)) {
85 $r = 'array(';
86
87 foreach ($node as $key => $value) {
88 $r .= "\n " . $key . ': ';
89
90 if (null === $value) {
91 $r .= 'null';
92 } elseif (false === $value) {
93 $r .= 'false';
94 } elseif (true === $value) {
95 $r .= 'true';
96 } elseif (is_scalar($value)) {
97 $r .= $value;
98 } else {
99 $r .= str_replace("\n", "\n ", $this->dumpRecursive($value));
100 }
101 }
102 } elseif ($node instanceof Comment) {
103 return $node->getReformattedText();
104 } else {
105 throw new \InvalidArgumentException('Can only dump nodes and arrays.');
106 }
107
108 return $r . "\n)";
109 }
110
111 protected function dumpFlags($flags) {
112 $strs = [];
113 if ($flags & Class_::MODIFIER_PUBLIC) {
114 $strs[] = 'MODIFIER_PUBLIC';
115 }
116 if ($flags & Class_::MODIFIER_PROTECTED) {
117 $strs[] = 'MODIFIER_PROTECTED';
118 }
119 if ($flags & Class_::MODIFIER_PRIVATE) {
120 $strs[] = 'MODIFIER_PRIVATE';
121 }
122 if ($flags & Class_::MODIFIER_ABSTRACT) {
123 $strs[] = 'MODIFIER_ABSTRACT';
124 }
125 if ($flags & Class_::MODIFIER_STATIC) {
126 $strs[] = 'MODIFIER_STATIC';
127 }
128 if ($flags & Class_::MODIFIER_FINAL) {
129 $strs[] = 'MODIFIER_FINAL';
130 }
131
132 if ($strs) {
133 return implode(' | ', $strs) . ' (' . $flags . ')';
134 } else {
135 return $flags;
136 }
137 }
138
139 protected function dumpIncludeType($type) {
140 $map = [
141 Include_::TYPE_INCLUDE => 'TYPE_INCLUDE',
142 Include_::TYPE_INCLUDE_ONCE => 'TYPE_INCLUDE_ONCE',
143 Include_::TYPE_REQUIRE => 'TYPE_REQUIRE',
144 Include_::TYPE_REQUIRE_ONCE => 'TYPE_REQURE_ONCE',
145 ];
146
147 if (!isset($map[$type])) {
148 return $type;
149 }
150 return $map[$type] . ' (' . $type . ')';
151 }
152
153 protected function dumpUseType($type) {
154 $map = [
155 Use_::TYPE_UNKNOWN => 'TYPE_UNKNOWN',
156 Use_::TYPE_NORMAL => 'TYPE_NORMAL',
157 Use_::TYPE_FUNCTION => 'TYPE_FUNCTION',
158 Use_::TYPE_CONSTANT => 'TYPE_CONSTANT',
159 ];
160
161 if (!isset($map[$type])) {
162 return $type;
163 }
164 return $map[$type] . ' (' . $type . ')';
165 }
166
167 protected function dumpPosition(Node $node) {
168 if (!$node->hasAttribute('startLine') || !$node->hasAttribute('endLine')) {
169 return null;
170 }
171
172 $start = $node->getAttribute('startLine');
173 $end = $node->getAttribute('endLine');
174 if ($node->hasAttribute('startFilePos') && $node->hasAttribute('endFilePos')
175 && null !== $this->code
176 ) {
177 $start .= ':' . $this->toColumn($this->code, $node->getAttribute('startFilePos'));
178 $end .= ':' . $this->toColumn($this->code, $node->getAttribute('endFilePos'));
179 }
180 return "[$start - $end]";
181 }
182
183 // Copied from Error class
184 private function toColumn($code, $pos) {
185 if ($pos > strlen($code)) {
186 throw new \RuntimeException('Invalid position information');
187 }
188
189 $lineStartPos = strrpos($code, "\n", $pos - strlen($code));
190 if (false === $lineStartPos) {
191 $lineStartPos = -1;
192 }
193
194 return $pos - $lineStartPos;
195 }
196 }
197