PluginProbe
Code Engine – PHP Snippets, AI Functions & Automation for WordPress / 0.4.2
Code Engine – PHP Snippets, AI Functions & Automation for WordPress v0.4.2
0.5.7 0.5.6 0.5.5 0.5.4 0.5.3 0.5.2 0.5.1 0.5.0 0.4.9 0.4.8 0.4.7 0.4.6 trunk 0.0.1 0.0.2 0.2.8 0.2.9 0.3.0 0.3.1 0.3.2 0.3.3 0.3.4 0.3.5 0.3.6 0.3.7 All 33 releases
code-engine / vendor / nikic / php-parser / lib / PhpParser / Comment.php

Comment.php in Code Engine – PHP Snippets, AI Functions & Automation for WordPress 0.4.2, at vendor/nikic/php-parser/lib/PhpParser/Comment.php

210 lines 6.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php declare(strict_types=1);
2
3 namespace PhpParser;
4
5 class Comment implements \JsonSerializable {
6 protected string $text;
7 protected int $startLine;
8 protected int $startFilePos;
9 protected int $startTokenPos;
10 protected int $endLine;
11 protected int $endFilePos;
12 protected int $endTokenPos;
13
14 /**
15 * Constructs a comment node.
16 *
17 * @param string $text Comment text (including comment delimiters like /*)
18 * @param int $startLine Line number the comment started on
19 * @param int $startFilePos File offset the comment started on
20 * @param int $startTokenPos Token offset the comment started on
21 */
22 public function __construct(
23 string $text,
24 int $startLine = -1, int $startFilePos = -1, int $startTokenPos = -1,
25 int $endLine = -1, int $endFilePos = -1, int $endTokenPos = -1
26 ) {
27 $this->text = $text;
28 $this->startLine = $startLine;
29 $this->startFilePos = $startFilePos;
30 $this->startTokenPos = $startTokenPos;
31 $this->endLine = $endLine;
32 $this->endFilePos = $endFilePos;
33 $this->endTokenPos = $endTokenPos;
34 }
35
36 /**
37 * Gets the comment text.
38 *
39 * @return string The comment text (including comment delimiters like /*)
40 */
41 public function getText(): string {
42 return $this->text;
43 }
44
45 /**
46 * Gets the line number the comment started on.
47 *
48 * @return int Line number (or -1 if not available)
49 * @phpstan-return -1|positive-int
50 */
51 public function getStartLine(): int {
52 return $this->startLine;
53 }
54
55 /**
56 * Gets the file offset the comment started on.
57 *
58 * @return int File offset (or -1 if not available)
59 */
60 public function getStartFilePos(): int {
61 return $this->startFilePos;
62 }
63
64 /**
65 * Gets the token offset the comment started on.
66 *
67 * @return int Token offset (or -1 if not available)
68 */
69 public function getStartTokenPos(): int {
70 return $this->startTokenPos;
71 }
72
73 /**
74 * Gets the line number the comment ends on.
75 *
76 * @return int Line number (or -1 if not available)
77 * @phpstan-return -1|positive-int
78 */
79 public function getEndLine(): int {
80 return $this->endLine;
81 }
82
83 /**
84 * Gets the file offset the comment ends on.
85 *
86 * @return int File offset (or -1 if not available)
87 */
88 public function getEndFilePos(): int {
89 return $this->endFilePos;
90 }
91
92 /**
93 * Gets the token offset the comment ends on.
94 *
95 * @return int Token offset (or -1 if not available)
96 */
97 public function getEndTokenPos(): int {
98 return $this->endTokenPos;
99 }
100
101 /**
102 * Gets the comment text.
103 *
104 * @return string The comment text (including comment delimiters like /*)
105 */
106 public function __toString(): string {
107 return $this->text;
108 }
109
110 /**
111 * Gets the reformatted comment text.
112 *
113 * "Reformatted" here means that we try to clean up the whitespace at the
114 * starts of the lines. This is necessary because we receive the comments
115 * without leading whitespace on the first line, but with leading whitespace
116 * on all subsequent lines.
117 *
118 * Additionally, this normalizes CRLF newlines to LF newlines.
119 */
120 public function getReformattedText(): string {
121 $text = str_replace("\r\n", "\n", $this->text);
122 $newlinePos = strpos($text, "\n");
123 if (false === $newlinePos) {
124 // Single line comments don't need further processing
125 return $text;
126 }
127 if (preg_match('(^.*(?:\n\s+\*.*)+$)', $text)) {
128 // Multi line comment of the type
129 //
130 // /*
131 // * Some text.
132 // * Some more text.
133 // */
134 //
135 // is handled by replacing the whitespace sequences before the * by a single space
136 return preg_replace('(^\s+\*)m', ' *', $text);
137 }
138 if (preg_match('(^/\*\*?\s*\n)', $text) && preg_match('(\n(\s*)\*/$)', $text, $matches)) {
139 // Multi line comment of the type
140 //
141 // /*
142 // Some text.
143 // Some more text.
144 // */
145 //
146 // is handled by removing the whitespace sequence on the line before the closing
147 // */ on all lines. So if the last line is " */", then " " is removed at the
148 // start of all lines.
149 return preg_replace('(^' . preg_quote($matches[1]) . ')m', '', $text);
150 }
151 if (preg_match('(^/\*\*?\s*(?!\s))', $text, $matches)) {
152 // Multi line comment of the type
153 //
154 // /* Some text.
155 // Some more text.
156 // Indented text.
157 // Even more text. */
158 //
159 // is handled by removing the difference between the shortest whitespace prefix on all
160 // lines and the length of the "/* " opening sequence.
161 $prefixLen = $this->getShortestWhitespacePrefixLen(substr($text, $newlinePos + 1));
162 $removeLen = $prefixLen - strlen($matches[0]);
163 return preg_replace('(^\s{' . $removeLen . '})m', '', $text);
164 }
165
166 // No idea how to format this comment, so simply return as is
167 return $text;
168 }
169
170 /**
171 * Get length of shortest whitespace prefix (at the start of a line).
172 *
173 * If there is a line with no prefix whitespace, 0 is a valid return value.
174 *
175 * @param string $str String to check
176 * @return int Length in characters. Tabs count as single characters.
177 */
178 private function getShortestWhitespacePrefixLen(string $str): int {
179 $lines = explode("\n", $str);
180 $shortestPrefixLen = \PHP_INT_MAX;
181 foreach ($lines as $line) {
182 preg_match('(^\s*)', $line, $matches);
183 $prefixLen = strlen($matches[0]);
184 if ($prefixLen < $shortestPrefixLen) {
185 $shortestPrefixLen = $prefixLen;
186 }
187 }
188 return $shortestPrefixLen;
189 }
190
191 /**
192 * @return array{nodeType:string, text:mixed, line:mixed, filePos:mixed}
193 */
194 public function jsonSerialize(): array {
195 // Technically not a node, but we make it look like one anyway
196 $type = $this instanceof Comment\Doc ? 'Comment_Doc' : 'Comment';
197 return [
198 'nodeType' => $type,
199 'text' => $this->text,
200 // TODO: Rename these to include "start".
201 'line' => $this->startLine,
202 'filePos' => $this->startFilePos,
203 'tokenPos' => $this->startTokenPos,
204 'endLine' => $this->endLine,
205 'endFilePos' => $this->endFilePos,
206 'endTokenPos' => $this->endTokenPos,
207 ];
208 }
209 }
210